compiler_test.go 26 KB

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