compiler_test.go 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838
  1. package goja
  2. import (
  3. "github.com/dop251/goja/parser"
  4. "io/ioutil"
  5. "os"
  6. "testing"
  7. )
  8. func testScript(script string, expectedResult Value, t *testing.T) {
  9. prg, err := parser.ParseFile(nil, "test.js", script, 0)
  10. if err != nil {
  11. t.Fatal(err)
  12. }
  13. c := newCompiler()
  14. c.compile(prg)
  15. r := &Runtime{}
  16. r.init()
  17. vm := r.vm
  18. vm.prg = c.p
  19. vm.prg.dumpCode(t.Logf)
  20. vm.run()
  21. vm.pop()
  22. t.Logf("stack size: %d", len(vm.stack))
  23. t.Logf("stashAllocs: %d", vm.stashAllocs)
  24. v := vm.r.globalObject.self.getStr("rv")
  25. if v == nil {
  26. v = _undefined
  27. }
  28. if !v.SameAs(expectedResult) {
  29. t.Fatalf("Result: %+v, expected: %+v", v, expectedResult)
  30. }
  31. if vm.sp != 0 {
  32. t.Fatalf("sp: %d", vm.sp)
  33. }
  34. }
  35. func testScript1(script string, expectedResult Value, t *testing.T) {
  36. prg, err := parser.ParseFile(nil, "test.js", script, 0)
  37. if err != nil {
  38. t.Fatal(err)
  39. }
  40. c := newCompiler()
  41. c.compile(prg)
  42. r := &Runtime{}
  43. r.init()
  44. vm := r.vm
  45. vm.prg = c.p
  46. vm.prg.dumpCode(t.Logf)
  47. vm.run()
  48. v := vm.pop()
  49. t.Logf("stack size: %d", len(vm.stack))
  50. t.Logf("stashAllocs: %d", vm.stashAllocs)
  51. if v == nil && expectedResult != nil || !v.SameAs(expectedResult) {
  52. t.Fatalf("Result: %+v, expected: %+v", v, expectedResult)
  53. }
  54. if vm.sp != 0 {
  55. t.Fatalf("sp: %d", vm.sp)
  56. }
  57. }
  58. func TestEmptyProgram(t *testing.T) {
  59. const SCRIPT = `
  60. `
  61. testScript1(SCRIPT, _undefined, t)
  62. }
  63. func TestErrorProto(t *testing.T) {
  64. const SCRIPT = `
  65. var e = new TypeError();
  66. e.name;
  67. `
  68. testScript1(SCRIPT, asciiString("TypeError"), t)
  69. }
  70. func TestThis1(t *testing.T) {
  71. const SCRIPT = `
  72. function independent() {
  73. return this.prop;
  74. }
  75. var o = {};
  76. o.b = {g: independent, prop: 42};
  77. var rv = o.b.g();
  78. `
  79. testScript(SCRIPT, intToValue(42), t)
  80. }
  81. func TestThis2(t *testing.T) {
  82. const SCRIPT = `
  83. var o = {
  84. prop: 37,
  85. f: function() {
  86. return this.prop;
  87. }
  88. };
  89. var rv = o.f();
  90. `
  91. testScript(SCRIPT, intToValue(37), t)
  92. }
  93. func TestThisStrict(t *testing.T) {
  94. const SCRIPT = `
  95. "use strict";
  96. Object.defineProperty(Object.prototype, "x", { get: function () { return this; } });
  97. (5).x === 5;
  98. `
  99. testScript1(SCRIPT, valueTrue, t)
  100. }
  101. func TestThisNoStrict(t *testing.T) {
  102. const SCRIPT = `
  103. Object.defineProperty(Object.prototype, "x", { get: function () { return this; } });
  104. (5).x == 5;
  105. `
  106. testScript1(SCRIPT, valueTrue, t)
  107. }
  108. func TestCallLessArgs(t *testing.T) {
  109. const SCRIPT = `
  110. function A(a, b, c) {
  111. return String(a) + " " + String(b) + " " + String(c);
  112. }
  113. var rv = A(1, 2);
  114. `
  115. testScript(SCRIPT, asciiString("1 2 undefined"), t)
  116. }
  117. func TestCallMoreArgs(t *testing.T) {
  118. const SCRIPT = `
  119. function A(a, b) {
  120. var c = 4;
  121. return a - b + c;
  122. }
  123. var rv = A(1, 2, 3);
  124. `
  125. testScript(SCRIPT, intToValue(3), t)
  126. }
  127. func TestCallMoreArgsDynamic(t *testing.T) {
  128. const SCRIPT = `
  129. function A(a, b) {
  130. var c = 4;
  131. if (false) {
  132. eval("");
  133. }
  134. return a - b + c;
  135. }
  136. var rv = A(1, 2, 3);
  137. `
  138. testScript(SCRIPT, intToValue(3), t)
  139. }
  140. func TestCallLessArgsDynamic(t *testing.T) {
  141. const SCRIPT = `
  142. function A(a, b, c) {
  143. // Make it stashful
  144. function B() {
  145. return a;
  146. }
  147. return String(a) + " " + String(b) + " " + String(c);
  148. }
  149. var rv = A(1, 2);
  150. `
  151. testScript(SCRIPT, asciiString("1 2 undefined"), t)
  152. }
  153. func TestCallLessArgsDynamicLocalVar(t *testing.T) {
  154. const SCRIPT = `
  155. function f(param) {
  156. var a = 42;
  157. if (false) {
  158. eval("");
  159. }
  160. return a;
  161. }
  162. f();
  163. `
  164. testScript1(SCRIPT, intToValue(42), t)
  165. }
  166. /*
  167. func TestFib(t *testing.T) {
  168. testScript(TEST_FIB, valueInt(9227465), t)
  169. }
  170. */
  171. func TestNativeCall(t *testing.T) {
  172. const SCRIPT = `
  173. var o = Object(1);
  174. Object.defineProperty(o, "test", {value: 42});
  175. var rv = o.test;
  176. `
  177. testScript(SCRIPT, intToValue(42), t)
  178. }
  179. func TestJSCall(t *testing.T) {
  180. const SCRIPT = `
  181. function getter() {
  182. return this.x;
  183. }
  184. var o = Object(1);
  185. o.x = 42;
  186. Object.defineProperty(o, "test", {get: getter});
  187. var rv = o.test;
  188. `
  189. testScript(SCRIPT, intToValue(42), t)
  190. }
  191. func TestLoop1(t *testing.T) {
  192. const SCRIPT = `
  193. function A() {
  194. var x = 1;
  195. for (var i = 0; i < 1; i++) {
  196. var x = 2;
  197. }
  198. return x;
  199. }
  200. var rv = A();
  201. `
  202. testScript(SCRIPT, intToValue(2), t)
  203. }
  204. func TestLoopBreak(t *testing.T) {
  205. const SCRIPT = `
  206. function A() {
  207. var x = 1;
  208. for (var i = 0; i < 1; i++) {
  209. break;
  210. var x = 2;
  211. }
  212. return x;
  213. }
  214. var rv = A();
  215. `
  216. testScript(SCRIPT, intToValue(1), t)
  217. }
  218. func TestForLoopOptionalExpr(t *testing.T) {
  219. const SCRIPT = `
  220. function A() {
  221. var x = 1;
  222. for (;;) {
  223. break;
  224. var x = 2;
  225. }
  226. return x;
  227. }
  228. var rv = A();
  229. `
  230. testScript(SCRIPT, intToValue(1), t)
  231. }
  232. func TestBlockBreak(t *testing.T) {
  233. const SCRIPT = `
  234. var rv = 0;
  235. B1: {
  236. rv = 1;
  237. B2: {
  238. rv = 2;
  239. break B1;
  240. }
  241. rv = 3;
  242. }
  243. `
  244. testScript(SCRIPT, intToValue(2), t)
  245. }
  246. func TestTry(t *testing.T) {
  247. const SCRIPT = `
  248. function A() {
  249. var x = 1;
  250. try {
  251. x = 2;
  252. } catch(e) {
  253. x = 3;
  254. } finally {
  255. x = 4;
  256. }
  257. return x;
  258. }
  259. var rv = A();
  260. `
  261. testScript(SCRIPT, intToValue(4), t)
  262. }
  263. func TestTryCatch(t *testing.T) {
  264. const SCRIPT = `
  265. function A() {
  266. var x;
  267. try {
  268. throw 4;
  269. } catch(e) {
  270. x = e;
  271. }
  272. return x;
  273. }
  274. var rv = A();
  275. `
  276. testScript(SCRIPT, intToValue(4), t)
  277. }
  278. func TestTryExceptionInCatch(t *testing.T) {
  279. const SCRIPT = `
  280. function A() {
  281. var x;
  282. try {
  283. throw 4;
  284. } catch(e) {
  285. throw 5;
  286. }
  287. return x;
  288. }
  289. var rv;
  290. try {
  291. A();
  292. } catch (e) {
  293. rv = e;
  294. }
  295. `
  296. testScript(SCRIPT, intToValue(5), t)
  297. }
  298. func TestTryContinueInFinally(t *testing.T) {
  299. const SCRIPT = `
  300. var c3 = 0, fin3 = 0;
  301. while (c3 < 2) {
  302. try {
  303. throw "ex1";
  304. } catch(er1) {
  305. c3 += 1;
  306. } finally {
  307. fin3 = 1;
  308. continue;
  309. }
  310. fin3 = 0;
  311. }
  312. fin3;
  313. `
  314. testScript1(SCRIPT, intToValue(1), t)
  315. }
  316. func TestCatchLexicalEnv(t *testing.T) {
  317. const SCRIPT = `
  318. function F() {
  319. try {
  320. throw 1;
  321. } catch (e) {
  322. var x = e;
  323. }
  324. return x;
  325. }
  326. F();
  327. `
  328. testScript1(SCRIPT, intToValue(1), t)
  329. }
  330. func TestThrowType(t *testing.T) {
  331. const SCRIPT = `
  332. function Exception(message) {
  333. this.message = message;
  334. }
  335. function A() {
  336. try {
  337. throw new Exception("boo!");
  338. } catch(e) {
  339. return e;
  340. }
  341. }
  342. var thrown = A();
  343. var rv = thrown !== null && typeof thrown === "object" && thrown.constructor === Exception;
  344. `
  345. testScript(SCRIPT, valueTrue, t)
  346. }
  347. func TestThrowConstructorName(t *testing.T) {
  348. const SCRIPT = `
  349. function Exception(message) {
  350. this.message = message;
  351. }
  352. function A() {
  353. try {
  354. throw new Exception("boo!");
  355. } catch(e) {
  356. return e;
  357. }
  358. }
  359. A().constructor.name;
  360. `
  361. testScript1(SCRIPT, asciiString("Exception"), t)
  362. }
  363. func TestThrowNativeConstructorName(t *testing.T) {
  364. const SCRIPT = `
  365. function A() {
  366. try {
  367. throw new TypeError();
  368. } catch(e) {
  369. return e;
  370. }
  371. }
  372. A().constructor.name;
  373. `
  374. testScript1(SCRIPT, asciiString("TypeError"), t)
  375. }
  376. func TestEmptyTryNoCatch(t *testing.T) {
  377. const SCRIPT = `
  378. var called = false;
  379. try {
  380. } finally {
  381. called = true;
  382. }
  383. called;
  384. `
  385. testScript1(SCRIPT, valueTrue, t)
  386. }
  387. func TestIfElse(t *testing.T) {
  388. const SCRIPT = `
  389. var rv;
  390. if (rv === undefined) {
  391. rv = "passed";
  392. } else {
  393. rv = "failed";
  394. }
  395. `
  396. testScript(SCRIPT, asciiString("passed"), t)
  397. }
  398. func TestIfElseRetVal(t *testing.T) {
  399. const SCRIPT = `
  400. var x;
  401. if (x === undefined) {
  402. "passed";
  403. } else {
  404. "failed";
  405. }
  406. `
  407. testScript1(SCRIPT, asciiString("passed"), t)
  408. }
  409. func TestBreakOutOfTry(t *testing.T) {
  410. const SCRIPT = `
  411. function A() {
  412. var x = 1;
  413. B: {
  414. try {
  415. x = 2;
  416. } catch(e) {
  417. x = 3;
  418. } finally {
  419. break B;
  420. x = 4;
  421. }
  422. }
  423. return x;
  424. }
  425. A();
  426. `
  427. testScript1(SCRIPT, intToValue(2), t)
  428. }
  429. func TestReturnOutOfTryNested(t *testing.T) {
  430. const SCRIPT = `
  431. function A() {
  432. function nested() {
  433. try {
  434. return 1;
  435. } catch(e) {
  436. return 2;
  437. }
  438. }
  439. return nested();
  440. }
  441. A();
  442. `
  443. testScript1(SCRIPT, intToValue(1), t)
  444. }
  445. func TestContinueLoop(t *testing.T) {
  446. const SCRIPT = `
  447. function A() {
  448. var r = 0;
  449. for (var i = 0; i < 5; i++) {
  450. if (i > 1) {
  451. continue;
  452. }
  453. r++;
  454. }
  455. return r;
  456. }
  457. A();
  458. `
  459. testScript1(SCRIPT, intToValue(2), t)
  460. }
  461. func TestContinueOutOfTry(t *testing.T) {
  462. const SCRIPT = `
  463. function A() {
  464. var r = 0;
  465. for (var i = 0; i < 5; i++) {
  466. try {
  467. if (i > 1) {
  468. continue;
  469. }
  470. } catch(e) {
  471. return 99;
  472. }
  473. r++;
  474. }
  475. return r;
  476. }
  477. A();
  478. `
  479. testScript1(SCRIPT, intToValue(2), t)
  480. }
  481. func TestThisInCatch(t *testing.T) {
  482. const SCRIPT = `
  483. function O() {
  484. try {
  485. f();
  486. } catch (e) {
  487. this.value = e.toString();
  488. }
  489. }
  490. function f() {
  491. throw "ex";
  492. }
  493. var o = new O();
  494. o.value;
  495. `
  496. testScript1(SCRIPT, asciiString("ex"), t)
  497. }
  498. func TestNestedTry(t *testing.T) {
  499. const SCRIPT = `
  500. var ex;
  501. try {
  502. throw "ex1";
  503. } catch (er1) {
  504. try {
  505. throw "ex2";
  506. } catch (er1) {
  507. ex = er1;
  508. }
  509. }
  510. ex;
  511. `
  512. testScript1(SCRIPT, asciiString("ex2"), t)
  513. }
  514. func TestNestedTryInStashlessFunc(t *testing.T) {
  515. const SCRIPT = `
  516. function f() {
  517. var ex1, ex2;
  518. try {
  519. throw "ex1";
  520. } catch (er1) {
  521. try {
  522. throw "ex2";
  523. } catch (er1) {
  524. ex2 = er1;
  525. }
  526. ex1 = er1;
  527. }
  528. return ex1 == "ex1" && ex2 == "ex2";
  529. }
  530. f();
  531. `
  532. testScript1(SCRIPT, valueTrue, t)
  533. }
  534. func TestEvalInCatchInStashlessFunc(t *testing.T) {
  535. const SCRIPT = `
  536. function f() {
  537. var ex;
  538. try {
  539. throw "ex1";
  540. } catch (er1) {
  541. eval("ex = er1");
  542. }
  543. return ex;
  544. }
  545. f();
  546. `
  547. testScript1(SCRIPT, asciiString("ex1"), t)
  548. }
  549. func TestCatchClosureInStashlessFunc(t *testing.T) {
  550. const SCRIPT = `
  551. function f() {
  552. var ex;
  553. try {
  554. throw "ex1";
  555. } catch (er1) {
  556. return function() {
  557. return er1;
  558. }
  559. }
  560. }
  561. f()();
  562. `
  563. testScript1(SCRIPT, asciiString("ex1"), t)
  564. }
  565. func TestCatchVarNotUsedInStashlessFunc(t *testing.T) {
  566. const SCRIPT = `
  567. function f() {
  568. var ex;
  569. try {
  570. throw "ex1";
  571. } catch (er1) {
  572. ex = "ok";
  573. }
  574. return ex;
  575. }
  576. f();
  577. `
  578. testScript1(SCRIPT, asciiString("ok"), t)
  579. }
  580. func TestNew(t *testing.T) {
  581. const SCRIPT = `
  582. function O() {
  583. this.x = 42;
  584. }
  585. new O().x;
  586. `
  587. testScript1(SCRIPT, intToValue(42), t)
  588. }
  589. func TestStringConstructor(t *testing.T) {
  590. const SCRIPT = `
  591. function F() {
  592. return String(33) + " " + String("cows");
  593. }
  594. F();
  595. `
  596. testScript1(SCRIPT, asciiString("33 cows"), t)
  597. }
  598. func TestError(t *testing.T) {
  599. const SCRIPT = `
  600. function F() {
  601. return new Error("test");
  602. }
  603. var e = F();
  604. var rv = e.message == "test" && e.name == "Error";
  605. `
  606. testScript(SCRIPT, valueTrue, t)
  607. }
  608. func TestTypeError(t *testing.T) {
  609. const SCRIPT = `
  610. function F() {
  611. return new TypeError("test");
  612. }
  613. var e = F();
  614. e.message == "test" && e.name == "TypeError";
  615. `
  616. testScript1(SCRIPT, valueTrue, t)
  617. }
  618. func TestToString(t *testing.T) {
  619. const SCRIPT = `
  620. var o = {x: 42};
  621. o.toString = function() {
  622. return String(this.x);
  623. }
  624. var o1 = {};
  625. o.toString() + " ### " + o1.toString();
  626. `
  627. testScript1(SCRIPT, asciiString("42 ### [object Object]"), t)
  628. }
  629. func TestEvalOrder(t *testing.T) {
  630. const SCRIPT = `
  631. var o = {f: function() {return 42}, x: 0};
  632. var trace = "";
  633. function F1() {
  634. trace += "First!";
  635. return o;
  636. }
  637. function F2() {
  638. trace += "Second!";
  639. return "f";
  640. }
  641. function F3() {
  642. trace += "Third!";
  643. }
  644. var rv = F1()[F2()](F3());
  645. rv += trace;
  646. `
  647. testScript(SCRIPT, asciiString("42First!Second!Third!"), t)
  648. }
  649. func TestPostfixIncBracket(t *testing.T) {
  650. const SCRIPT = `
  651. var o = {x: 42};
  652. var trace = "";
  653. function F1() {
  654. trace += "First!";
  655. return o;
  656. }
  657. function F2() {
  658. trace += "Second!";
  659. return "x";
  660. }
  661. var rv = F1()[F2()]++;
  662. rv += trace + o.x;
  663. `
  664. testScript(SCRIPT, asciiString("42First!Second!43"), t)
  665. }
  666. func TestPostfixIncDot(t *testing.T) {
  667. const SCRIPT = `
  668. var o = {x: 42};
  669. var trace = "";
  670. function F1() {
  671. trace += "First!";
  672. return o;
  673. }
  674. var rv = F1().x++;
  675. rv += trace + o.x;
  676. `
  677. testScript(SCRIPT, asciiString("42First!43"), t)
  678. }
  679. func TestPrefixIncBracket(t *testing.T) {
  680. const SCRIPT = `
  681. var o = {x: 42};
  682. var trace = "";
  683. function F1() {
  684. trace += "First!";
  685. return o;
  686. }
  687. function F2() {
  688. trace += "Second!";
  689. return "x";
  690. }
  691. var rv = ++F1()[F2()];
  692. rv += trace + o.x;
  693. `
  694. testScript(SCRIPT, asciiString("43First!Second!43"), t)
  695. }
  696. func TestPrefixIncDot(t *testing.T) {
  697. const SCRIPT = `
  698. var o = {x: 42};
  699. var trace = "";
  700. function F1() {
  701. trace += "First!";
  702. return o;
  703. }
  704. var rv = ++F1().x;
  705. rv += trace + o.x;
  706. `
  707. testScript(SCRIPT, asciiString("43First!43"), t)
  708. }
  709. func TestPostDecObj(t *testing.T) {
  710. const SCRIPT = `
  711. var object = {valueOf: function() {return 1}};
  712. var y = object--;
  713. var ok = false;
  714. if (y === 1) {
  715. ok = true;
  716. }
  717. ok;
  718. `
  719. testScript1(SCRIPT, valueTrue, t)
  720. }
  721. func TestPropAcc1(t *testing.T) {
  722. const SCRIPT = `
  723. 1..toString() === "1"
  724. `
  725. testScript1(SCRIPT, valueTrue, t)
  726. }
  727. func TestEvalDirect(t *testing.T) {
  728. const SCRIPT = `
  729. var rv = false;
  730. function foo(){ rv = true; }
  731. var o = { };
  732. function f() {
  733. try {
  734. eval("o.bar( foo() );");
  735. } catch (e) {
  736. }
  737. }
  738. f();
  739. `
  740. testScript(SCRIPT, valueTrue, t)
  741. }
  742. func TestEvalRet(t *testing.T) {
  743. const SCRIPT = `
  744. eval("for (var i = 0; i < 3; i++) {i}")
  745. `
  746. testScript1(SCRIPT, valueInt(2), t)
  747. }
  748. func TestEvalFunctionDecl(t *testing.T) {
  749. const SCRIPT = `
  750. eval("function F() {}")
  751. `
  752. testScript1(SCRIPT, _undefined, t)
  753. }
  754. func TestEvalFunctionExpr(t *testing.T) {
  755. const SCRIPT = `
  756. eval("(function F() {return 42;})")()
  757. `
  758. testScript1(SCRIPT, intToValue(42), t)
  759. }
  760. func TestLoopRet(t *testing.T) {
  761. const SCRIPT = `
  762. for (var i = 0; i < 20; i++) { if (i > 1) {break;} else { i }}
  763. `
  764. testScript1(SCRIPT, _undefined, t)
  765. }
  766. func TestLoopRet1(t *testing.T) {
  767. const SCRIPT = `
  768. for (var i = 0; i < 20; i++) { }
  769. `
  770. testScript1(SCRIPT, _undefined, t)
  771. }
  772. func TestInstanceof(t *testing.T) {
  773. const SCRIPT = `
  774. var rv;
  775. try {
  776. true();
  777. } catch (e) {
  778. rv = e instanceof TypeError;
  779. }
  780. `
  781. testScript(SCRIPT, valueTrue, t)
  782. }
  783. func TestStrictAssign(t *testing.T) {
  784. const SCRIPT = `
  785. 'use strict';
  786. var rv;
  787. var called = false;
  788. function F() {
  789. called = true;
  790. return 1;
  791. }
  792. try {
  793. x = F();
  794. } catch (e) {
  795. rv = e instanceof ReferenceError;
  796. }
  797. rv += " " + called;
  798. `
  799. testScript(SCRIPT, asciiString("true true"), t)
  800. }
  801. func TestStrictScope(t *testing.T) {
  802. const SCRIPT = `
  803. var rv;
  804. var called = false;
  805. function F() {
  806. 'use strict';
  807. x = 1;
  808. }
  809. try {
  810. F();
  811. } catch (e) {
  812. rv = e instanceof ReferenceError;
  813. }
  814. x = 1;
  815. rv += " " + x;
  816. `
  817. testScript(SCRIPT, asciiString("true 1"), t)
  818. }
  819. func TestStringObj(t *testing.T) {
  820. const SCRIPT = `
  821. var s = new String("test");
  822. s[0] + s[2] + s[1];
  823. `
  824. testScript1(SCRIPT, asciiString("tse"), t)
  825. }
  826. func TestStringPrimitive(t *testing.T) {
  827. const SCRIPT = `
  828. var s = "test";
  829. s[0] + s[2] + s[1];
  830. `
  831. testScript1(SCRIPT, asciiString("tse"), t)
  832. }
  833. func TestCallGlobalObject(t *testing.T) {
  834. const SCRIPT = `
  835. var rv;
  836. try {
  837. this();
  838. } catch (e) {
  839. rv = e instanceof TypeError
  840. }
  841. `
  842. testScript(SCRIPT, valueTrue, t)
  843. }
  844. func TestFuncLength(t *testing.T) {
  845. const SCRIPT = `
  846. function F(x, y) {
  847. }
  848. F.length
  849. `
  850. testScript1(SCRIPT, intToValue(2), t)
  851. }
  852. func TestNativeFuncLength(t *testing.T) {
  853. const SCRIPT = `
  854. eval.length + Object.defineProperty.length + String.length
  855. `
  856. testScript1(SCRIPT, intToValue(5), t)
  857. }
  858. func TestArguments(t *testing.T) {
  859. const SCRIPT = `
  860. function F() {
  861. return arguments.length + " " + arguments[1];
  862. }
  863. F(1,2,3)
  864. `
  865. testScript1(SCRIPT, asciiString("3 2"), t)
  866. }
  867. func TestArgumentsPut(t *testing.T) {
  868. const SCRIPT = `
  869. function F(x, y) {
  870. arguments[0] -= arguments[1];
  871. return x;
  872. }
  873. F(5, 2)
  874. `
  875. testScript1(SCRIPT, intToValue(3), t)
  876. }
  877. func TestArgumentsPutStrict(t *testing.T) {
  878. const SCRIPT = `
  879. function F(x, y) {
  880. 'use strict';
  881. arguments[0] -= arguments[1];
  882. return x;
  883. }
  884. F(5, 2)
  885. `
  886. testScript1(SCRIPT, intToValue(5), t)
  887. }
  888. func TestArgumentsExtra(t *testing.T) {
  889. const SCRIPT = `
  890. function F(x, y) {
  891. return arguments[2];
  892. }
  893. F(1, 2, 42)
  894. `
  895. testScript1(SCRIPT, intToValue(42), t)
  896. }
  897. func TestArgumentsExist(t *testing.T) {
  898. const SCRIPT = `
  899. function F(x, arguments) {
  900. return arguments;
  901. }
  902. F(1, 42)
  903. `
  904. testScript1(SCRIPT, intToValue(42), t)
  905. }
  906. func TestArgumentsDelete(t *testing.T) {
  907. const SCRIPT = `
  908. function f(x) {
  909. delete arguments[0];
  910. arguments[0] = 42;
  911. return x;
  912. }
  913. f(1)
  914. `
  915. testScript1(SCRIPT, intToValue(1), t)
  916. }
  917. func TestWith(t *testing.T) {
  918. const SCRIPT = `
  919. var b = 1;
  920. var o = {a: 41};
  921. with(o) {
  922. a += b;
  923. }
  924. o.a;
  925. `
  926. testScript1(SCRIPT, intToValue(42), t)
  927. }
  928. func TestWithInFunc(t *testing.T) {
  929. const SCRIPT = `
  930. function F() {
  931. var b = 1;
  932. var c = 0;
  933. var o = {a: 40, c: 1};
  934. with(o) {
  935. a += b + c;
  936. }
  937. return o.a;
  938. }
  939. F();
  940. `
  941. testScript1(SCRIPT, intToValue(42), t)
  942. }
  943. func TestAssignNonExtendable(t *testing.T) {
  944. const SCRIPT = `
  945. 'use strict';
  946. function F() {
  947. this.x = 1;
  948. }
  949. var o = new F();
  950. Object.preventExtensions(o);
  951. o.x = 42;
  952. o.x;
  953. `
  954. testScript1(SCRIPT, intToValue(42), t)
  955. }
  956. func TestAssignNonExtendable1(t *testing.T) {
  957. const SCRIPT = `
  958. 'use strict';
  959. function F() {
  960. }
  961. var o = new F();
  962. var rv;
  963. Object.preventExtensions(o);
  964. try {
  965. o.x = 42;
  966. } catch (e) {
  967. rv = e.constructor === TypeError;
  968. }
  969. rv += " " + o.x;
  970. `
  971. testScript(SCRIPT, asciiString("true undefined"), t)
  972. }
  973. func TestAssignStrict(t *testing.T) {
  974. const SCRIPT = `
  975. 'use strict';
  976. try {
  977. eval("eval = 42");
  978. } catch(e) {
  979. var rv = e instanceof SyntaxError
  980. }
  981. `
  982. testScript(SCRIPT, valueTrue, t)
  983. }
  984. func TestIllegalArgmentName(t *testing.T) {
  985. const SCRIPT = `
  986. 'use strict';
  987. try {
  988. eval("function F(eval) {}");
  989. } catch (e) {
  990. var rv = e instanceof SyntaxError
  991. }
  992. `
  993. testScript(SCRIPT, valueTrue, t)
  994. }
  995. func TestFunction(t *testing.T) {
  996. const SCRIPT = `
  997. var f0 = Function("");
  998. var f1 = Function("return ' one'");
  999. var f2 = Function("arg", "return ' ' + arg");
  1000. f0() + f1() + f2("two");
  1001. `
  1002. testScript1(SCRIPT, asciiString("undefined one two"), t)
  1003. }
  1004. func TestFunction1(t *testing.T) {
  1005. const SCRIPT = `
  1006. var f = function f1(count) {
  1007. if (count == 0) {
  1008. return true;
  1009. }
  1010. return f1(count-1);
  1011. }
  1012. f(1);
  1013. `
  1014. testScript1(SCRIPT, valueTrue, t)
  1015. }
  1016. func TestFunction2(t *testing.T) {
  1017. const SCRIPT = `
  1018. var trace = "";
  1019. function f(count) {
  1020. trace += "f("+count+")";
  1021. if (count == 0) {
  1022. return;
  1023. }
  1024. return f(count-1);
  1025. }
  1026. function f1() {
  1027. trace += "f1";
  1028. }
  1029. var f2 = f;
  1030. f = f1;
  1031. f2(1);
  1032. trace;
  1033. `
  1034. testScript1(SCRIPT, asciiString("f(1)f1"), t)
  1035. }
  1036. func TestFunctionToString(t *testing.T) {
  1037. const SCRIPT = `
  1038. Function("arg1", "arg2", "return 42").toString();
  1039. `
  1040. testScript1(SCRIPT, asciiString("function anonymous(arg1,arg2){return 42}"), t)
  1041. }
  1042. func TestObjectLiteral(t *testing.T) {
  1043. const SCRIPT = `
  1044. var getterCalled = false;
  1045. var setterCalled = false;
  1046. var o = {get x() {getterCalled = true}, set x() {setterCalled = true}};
  1047. o.x;
  1048. o.x = 42;
  1049. getterCalled && setterCalled;
  1050. `
  1051. testScript1(SCRIPT, valueTrue, t)
  1052. }
  1053. func TestConst(t *testing.T) {
  1054. const SCRIPT = `
  1055. var v1 = true && true;
  1056. var v2 = 1/(-1 * 0);
  1057. var v3 = 1 == 2 || v1;
  1058. var v4 = true && false
  1059. v1 === true && v2 === -Infinity && v3 === v1 && v4 === false;
  1060. `
  1061. testScript1(SCRIPT, valueTrue, t)
  1062. }
  1063. func TestConstWhile(t *testing.T) {
  1064. const SCRIPT = `
  1065. var c = 0;
  1066. while (2 + 2 === 4) {
  1067. if (++c > 9) {
  1068. break;
  1069. }
  1070. }
  1071. c === 10;
  1072. `
  1073. testScript1(SCRIPT, valueTrue, t)
  1074. }
  1075. func TestConstWhileThrow(t *testing.T) {
  1076. const SCRIPT = `
  1077. var thrown = false;
  1078. try {
  1079. while ('s' in true) {
  1080. break;
  1081. }
  1082. } catch (e) {
  1083. thrown = e instanceof TypeError
  1084. }
  1085. thrown;
  1086. `
  1087. testScript1(SCRIPT, valueTrue, t)
  1088. }
  1089. func TestDupParams(t *testing.T) {
  1090. const SCRIPT = `
  1091. function F(x, y, x) {
  1092. return x;
  1093. }
  1094. F(1, 2);
  1095. `
  1096. testScript1(SCRIPT, _undefined, t)
  1097. }
  1098. func TestUseUnsuppliedParam(t *testing.T) {
  1099. const SCRIPT = `
  1100. function getMessage(message) {
  1101. if (message === undefined) {
  1102. message = '';
  1103. }
  1104. message += " 123 456";
  1105. return message;
  1106. }
  1107. getMessage();
  1108. `
  1109. testScript1(SCRIPT, asciiString(" 123 456"), t)
  1110. }
  1111. func TestForInLoop(t *testing.T) {
  1112. const SCRIPT = `
  1113. function Proto() {}
  1114. Proto.prototype.x = 42;
  1115. var o = new Proto();
  1116. o.y = 44;
  1117. o.x = 45;
  1118. var hasX = false;
  1119. var hasY = false;
  1120. for (var i in o) {
  1121. switch(i) {
  1122. case "x":
  1123. if (hasX) {
  1124. throw new Error("Already has X");
  1125. }
  1126. hasX = true;
  1127. break;
  1128. case "y":
  1129. if (hasY) {
  1130. throw new Error("Already has Y");
  1131. }
  1132. hasY = true;
  1133. break;
  1134. }
  1135. }
  1136. hasX && hasY;
  1137. `
  1138. testScript1(SCRIPT, valueTrue, t)
  1139. }
  1140. func TestForInLoopRet(t *testing.T) {
  1141. const SCRIPT = `
  1142. var o = {};
  1143. o.x = 1;
  1144. o.y = 2;
  1145. for (var i in o) {
  1146. true;
  1147. }
  1148. `
  1149. testScript1(SCRIPT, valueTrue, t)
  1150. }
  1151. func TestWhileLoopResult(t *testing.T) {
  1152. const SCRIPT = `
  1153. while(false);
  1154. `
  1155. testScript1(SCRIPT, _undefined, t)
  1156. }
  1157. func TestSwitch(t *testing.T) {
  1158. const SCRIPT = `
  1159. function F(x) {
  1160. var i = 0;
  1161. switch (x) {
  1162. case 0:
  1163. i++;
  1164. case 1:
  1165. i++;
  1166. default:
  1167. i++;
  1168. case 2:
  1169. i++;
  1170. break;
  1171. case 3:
  1172. i++;
  1173. }
  1174. return i;
  1175. }
  1176. F(0) + F(1) + F(2) + F(4);
  1177. `
  1178. testScript1(SCRIPT, intToValue(10), t)
  1179. }
  1180. func TestSwitchDefFirst(t *testing.T) {
  1181. const SCRIPT = `
  1182. function F(x) {
  1183. var i = 0;
  1184. switch (x) {
  1185. default:
  1186. i++;
  1187. case 0:
  1188. i++;
  1189. case 1:
  1190. i++;
  1191. case 2:
  1192. i++;
  1193. break;
  1194. case 3:
  1195. i++;
  1196. }
  1197. return i;
  1198. }
  1199. F(0) + F(1) + F(2) + F(4);
  1200. `
  1201. testScript1(SCRIPT, intToValue(10), t)
  1202. }
  1203. func TestSwitchResult(t *testing.T) {
  1204. const SCRIPT = `
  1205. var x = 2;
  1206. switch (x) {
  1207. case 0:
  1208. "zero";
  1209. case 1:
  1210. "one";
  1211. case 2:
  1212. "two";
  1213. break;
  1214. case 3:
  1215. "three";
  1216. default:
  1217. "default";
  1218. }
  1219. `
  1220. testScript1(SCRIPT, asciiString("two"), t)
  1221. }
  1222. func TestSwitchNoMatch(t *testing.T) {
  1223. const SCRIPT = `
  1224. var x = 5;
  1225. var result;
  1226. switch (x) {
  1227. case 0:
  1228. result = "2";
  1229. break;
  1230. }
  1231. result;
  1232. `
  1233. testScript1(SCRIPT, _undefined, t)
  1234. }
  1235. func TestGetOwnPropertyNames(t *testing.T) {
  1236. const SCRIPT = `
  1237. var o = {
  1238. prop1: 42,
  1239. prop2: "test"
  1240. }
  1241. var hasProp1 = false;
  1242. var hasProp2 = false;
  1243. var names = Object.getOwnPropertyNames(o);
  1244. for (var i in names) {
  1245. var p = names[i];
  1246. switch(p) {
  1247. case "prop1":
  1248. hasProp1 = true;
  1249. break;
  1250. case "prop2":
  1251. hasProp2 = true;
  1252. break;
  1253. }
  1254. }
  1255. hasProp1 && hasProp2;
  1256. `
  1257. testScript1(SCRIPT, valueTrue, t)
  1258. }
  1259. func TestArrayLiteral(t *testing.T) {
  1260. const SCRIPT = `
  1261. var f1Called = false;
  1262. var f2Called = false;
  1263. var f3Called = false;
  1264. var errorThrown = false;
  1265. function F1() {
  1266. f1Called = true;
  1267. }
  1268. function F2() {
  1269. f2Called = true;
  1270. }
  1271. function F3() {
  1272. f3Called = true;
  1273. }
  1274. try {
  1275. var a = [F1(), x(F3()), F2()];
  1276. } catch(e) {
  1277. if (e instanceof ReferenceError) {
  1278. errorThrown = true;
  1279. } else {
  1280. throw e;
  1281. }
  1282. }
  1283. f1Called && !f2Called && f3Called && errorThrown && a === undefined;
  1284. `
  1285. testScript1(SCRIPT, valueTrue, t)
  1286. }
  1287. func TestJumpOutOfReturn(t *testing.T) {
  1288. const SCRIPT = `
  1289. function f() {
  1290. var a;
  1291. if (a == 0) {
  1292. return true;
  1293. }
  1294. }
  1295. f();
  1296. `
  1297. testScript1(SCRIPT, _undefined, t)
  1298. }
  1299. func TestSwitchJumpOutOfReturn(t *testing.T) {
  1300. const SCRIPT = `
  1301. function f(x) {
  1302. switch(x) {
  1303. case 0:
  1304. break;
  1305. default:
  1306. return x;
  1307. }
  1308. }
  1309. f(0);
  1310. `
  1311. testScript1(SCRIPT, _undefined, t)
  1312. }
  1313. func TestSetToReadOnlyPropertyStrictBracket(t *testing.T) {
  1314. const SCRIPT = `
  1315. 'use strict';
  1316. var o = {};
  1317. var thrown = false;
  1318. Object.defineProperty(o, "test", {value: 42, configurable: true});
  1319. try {
  1320. o["test"] = 43;
  1321. } catch (e) {
  1322. thrown = e instanceof TypeError;
  1323. }
  1324. thrown;
  1325. `
  1326. testScript1(SCRIPT, valueTrue, t)
  1327. }
  1328. func TestSetToReadOnlyPropertyStrictDot(t *testing.T) {
  1329. const SCRIPT = `
  1330. 'use strict';
  1331. var o = {};
  1332. var thrown = false;
  1333. Object.defineProperty(o, "test", {value: 42, configurable: true});
  1334. try {
  1335. o.test = 43;
  1336. } catch (e) {
  1337. thrown = e instanceof TypeError;
  1338. }
  1339. thrown;
  1340. `
  1341. testScript1(SCRIPT, valueTrue, t)
  1342. }
  1343. func TestDeleteNonConfigurablePropertyStrictBracket(t *testing.T) {
  1344. const SCRIPT = `
  1345. 'use strict';
  1346. var o = {};
  1347. var thrown = false;
  1348. Object.defineProperty(o, "test", {value: 42});
  1349. try {
  1350. delete o["test"];
  1351. } catch (e) {
  1352. thrown = e instanceof TypeError;
  1353. }
  1354. thrown;
  1355. `
  1356. testScript1(SCRIPT, valueTrue, t)
  1357. }
  1358. func TestDeleteNonConfigurablePropertyStrictDot(t *testing.T) {
  1359. const SCRIPT = `
  1360. 'use strict';
  1361. var o = {};
  1362. var thrown = false;
  1363. Object.defineProperty(o, "test", {value: 42});
  1364. try {
  1365. delete o.test;
  1366. } catch (e) {
  1367. thrown = e instanceof TypeError;
  1368. }
  1369. thrown;
  1370. `
  1371. testScript1(SCRIPT, valueTrue, t)
  1372. }
  1373. func TestCompound1(t *testing.T) {
  1374. const SCRIPT = `
  1375. var x = 0;
  1376. var scope = {x: 1};
  1377. var f;
  1378. with (scope) {
  1379. f = function() {
  1380. x *= (delete scope.x, 2);
  1381. }
  1382. }
  1383. f();
  1384. scope.x === 2 && x === 0;
  1385. `
  1386. testScript1(SCRIPT, valueTrue, t)
  1387. }
  1388. func TestCompound2(t *testing.T) {
  1389. const SCRIPT = `
  1390. var x;
  1391. x = "x";
  1392. x ^= "1";
  1393. `
  1394. testScript1(SCRIPT, intToValue(1), t)
  1395. }
  1396. func TestDeleteArguments(t *testing.T) {
  1397. defer func() {
  1398. if _, ok := recover().(*CompilerSyntaxError); !ok {
  1399. t.Fatal("Expected syntax error")
  1400. }
  1401. }()
  1402. const SCRIPT = `
  1403. 'use strict';
  1404. function f() {
  1405. delete arguments;
  1406. }
  1407. `
  1408. testScript1(SCRIPT, _undefined, t)
  1409. }
  1410. func TestReturnUndefined(t *testing.T) {
  1411. const SCRIPT = `
  1412. function f() {
  1413. return x;
  1414. }
  1415. var thrown = false;
  1416. try {
  1417. f();
  1418. } catch (e) {
  1419. thrown = e instanceof ReferenceError;
  1420. }
  1421. thrown;
  1422. `
  1423. testScript1(SCRIPT, valueTrue, t)
  1424. }
  1425. func TestForBreak(t *testing.T) {
  1426. const SCRIPT = `
  1427. var supreme, count;
  1428. supreme = 5;
  1429. var __evaluated = eval("for(count=0;;) {if (count===supreme)break;else count++; }");
  1430. if (__evaluated !== void 0) {
  1431. throw new Error('#1: __evaluated === 4. Actual: __evaluated ==='+ __evaluated );
  1432. }
  1433. `
  1434. testScript1(SCRIPT, _undefined, t)
  1435. }
  1436. func TestLargeNumberLiteral(t *testing.T) {
  1437. const SCRIPT = `
  1438. var x = 0x800000000000000000000;
  1439. x.toString();
  1440. `
  1441. testScript1(SCRIPT, asciiString("9.671406556917033e+24"), t)
  1442. }
  1443. func TestIncDelete(t *testing.T) {
  1444. const SCRIPT = `
  1445. var o = {x: 1};
  1446. o.x += (delete o.x, 1);
  1447. o.x;
  1448. `
  1449. testScript1(SCRIPT, intToValue(2), t)
  1450. }
  1451. func TestCompoundAssignRefError(t *testing.T) {
  1452. const SCRIPT = `
  1453. var thrown = false;
  1454. try {
  1455. a *= 1;
  1456. } catch (e) {
  1457. if (e instanceof ReferenceError) {
  1458. thrown = true;
  1459. } else {
  1460. throw e;
  1461. }
  1462. }
  1463. thrown;
  1464. `
  1465. testScript1(SCRIPT, valueTrue, t)
  1466. }
  1467. func TestObjectLiteral__Proto__(t *testing.T) {
  1468. const SCRIPT = `
  1469. var o = {
  1470. __proto__: null,
  1471. test: 42
  1472. }
  1473. Object.getPrototypeOf(o);
  1474. `
  1475. testScript1(SCRIPT, _null, t)
  1476. }
  1477. // FIXME
  1478. /*
  1479. func TestDummyCompile(t *testing.T) {
  1480. const SCRIPT = `
  1481. 'use strict';
  1482. for (;false;) {
  1483. eval = 1;
  1484. }
  1485. `
  1486. defer func() {
  1487. if recover() == nil {
  1488. t.Fatal("Expected panic")
  1489. }
  1490. }()
  1491. testScript1(SCRIPT, _undefined, t)
  1492. }*/
  1493. func BenchmarkCompile(b *testing.B) {
  1494. f, err := os.Open("testdata/S15.10.2.12_A1_T1.js")
  1495. data, err := ioutil.ReadAll(f)
  1496. if err != nil {
  1497. b.Fatal(err)
  1498. }
  1499. f.Close()
  1500. src := string(data)
  1501. for i := 0; i < b.N; i++ {
  1502. _, err := Compile("test.js", src, false)
  1503. if err != nil {
  1504. b.Fatal(err)
  1505. }
  1506. }
  1507. }