123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184 |
- package goja
- import (
- "github.com/dop251/goja/parser"
- "io/ioutil"
- "os"
- "testing"
- )
- func testScript(script string, expectedResult Value, t *testing.T) {
- prg, err := parser.ParseFile(nil, "test.js", script, 0)
- if err != nil {
- t.Fatal(err)
- }
- c := newCompiler()
- c.compile(prg)
- r := &Runtime{}
- r.init()
- vm := r.vm
- vm.prg = c.p
- vm.prg.dumpCode(t.Logf)
- vm.run()
- vm.pop()
- t.Logf("stack size: %d", len(vm.stack))
- t.Logf("stashAllocs: %d", vm.stashAllocs)
- v := vm.r.globalObject.self.getStr("rv", nil)
- if v == nil {
- v = _undefined
- }
- if !v.SameAs(expectedResult) {
- t.Fatalf("Result: %+v, expected: %+v", v, expectedResult)
- }
- if vm.sp != 0 {
- t.Fatalf("sp: %d", vm.sp)
- }
- }
- func testScript1(script string, expectedResult Value, t *testing.T) {
- prg, err := parser.ParseFile(nil, "test.js", script, 0)
- if err != nil {
- t.Fatal(err)
- }
- c := newCompiler()
- c.compile(prg)
- r := &Runtime{}
- r.init()
- vm := r.vm
- vm.prg = c.p
- vm.prg.dumpCode(t.Logf)
- vm.run()
- v := vm.pop()
- t.Logf("stack size: %d", len(vm.stack))
- t.Logf("stashAllocs: %d", vm.stashAllocs)
- if v == nil && expectedResult != nil || !v.SameAs(expectedResult) {
- t.Fatalf("Result: %+v, expected: %+v", v, expectedResult)
- }
- if vm.sp != 0 {
- t.Fatalf("sp: %d", vm.sp)
- }
- if l := len(vm.iterStack); l > 0 {
- t.Fatalf("iter stack is not empty: %d", l)
- }
- }
- func TestEmptyProgram(t *testing.T) {
- const SCRIPT = `
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestErrorProto(t *testing.T) {
- const SCRIPT = `
- var e = new TypeError();
- e.name;
- `
- testScript1(SCRIPT, asciiString("TypeError"), t)
- }
- func TestThis1(t *testing.T) {
- const SCRIPT = `
- function independent() {
- return this.prop;
- }
- var o = {};
- o.b = {g: independent, prop: 42};
- var rv = o.b.g();
- `
- testScript(SCRIPT, intToValue(42), t)
- }
- func TestThis2(t *testing.T) {
- const SCRIPT = `
- var o = {
- prop: 37,
- f: function() {
- return this.prop;
- }
- };
- var rv = o.f();
- `
- testScript(SCRIPT, intToValue(37), t)
- }
- func TestThisStrict(t *testing.T) {
- const SCRIPT = `
- "use strict";
- Object.defineProperty(Object.prototype, "x", { get: function () { return this; } });
- (5).x === 5;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestThisNoStrict(t *testing.T) {
- const SCRIPT = `
- Object.defineProperty(Object.prototype, "x", { get: function () { return this; } });
- (5).x == 5;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestCallLessArgs(t *testing.T) {
- const SCRIPT = `
- function A(a, b, c) {
- return String(a) + " " + String(b) + " " + String(c);
- }
- var rv = A(1, 2);
- `
- testScript(SCRIPT, asciiString("1 2 undefined"), t)
- }
- func TestCallMoreArgs(t *testing.T) {
- const SCRIPT = `
- function A(a, b) {
- var c = 4;
- return a - b + c;
- }
- var rv = A(1, 2, 3);
- `
- testScript(SCRIPT, intToValue(3), t)
- }
- func TestCallMoreArgsDynamic(t *testing.T) {
- const SCRIPT = `
- function A(a, b) {
- var c = 4;
- if (false) {
- eval("");
- }
- return a - b + c;
- }
- var rv = A(1, 2, 3);
- `
- testScript(SCRIPT, intToValue(3), t)
- }
- func TestCallLessArgsDynamic(t *testing.T) {
- const SCRIPT = `
- function A(a, b, c) {
- // Make it stashful
- function B() {
- return a;
- }
- return String(a) + " " + String(b) + " " + String(c);
- }
- var rv = A(1, 2);
- `
- testScript(SCRIPT, asciiString("1 2 undefined"), t)
- }
- func TestCallLessArgsDynamicLocalVar(t *testing.T) {
- const SCRIPT = `
- function f(param) {
- var a = 42;
- if (false) {
- eval("");
- }
- return a;
- }
- f();
- `
- testScript1(SCRIPT, intToValue(42), t)
- }
- /*
- func TestFib(t *testing.T) {
- testScript(TEST_FIB, valueInt(9227465), t)
- }
- */
- func TestNativeCall(t *testing.T) {
- const SCRIPT = `
- var o = Object(1);
- Object.defineProperty(o, "test", {value: 42});
- var rv = o.test;
- `
- testScript(SCRIPT, intToValue(42), t)
- }
- func TestJSCall(t *testing.T) {
- const SCRIPT = `
- function getter() {
- return this.x;
- }
- var o = Object(1);
- o.x = 42;
- Object.defineProperty(o, "test", {get: getter});
- var rv = o.test;
- `
- testScript(SCRIPT, intToValue(42), t)
- }
- func TestLoop1(t *testing.T) {
- const SCRIPT = `
- function A() {
- var x = 1;
- for (var i = 0; i < 1; i++) {
- var x = 2;
- }
- return x;
- }
- var rv = A();
- `
- testScript(SCRIPT, intToValue(2), t)
- }
- func TestLoopBreak(t *testing.T) {
- const SCRIPT = `
- function A() {
- var x = 1;
- for (var i = 0; i < 1; i++) {
- break;
- var x = 2;
- }
- return x;
- }
- var rv = A();
- `
- testScript(SCRIPT, intToValue(1), t)
- }
- func TestForLoopOptionalExpr(t *testing.T) {
- const SCRIPT = `
- function A() {
- var x = 1;
- for (;;) {
- break;
- var x = 2;
- }
- return x;
- }
- var rv = A();
- `
- testScript(SCRIPT, intToValue(1), t)
- }
- func TestBlockBreak(t *testing.T) {
- const SCRIPT = `
- var rv = 0;
- B1: {
- rv = 1;
- B2: {
- rv = 2;
- break B1;
- }
- rv = 3;
- }
- `
- testScript(SCRIPT, intToValue(2), t)
- }
- func TestTry(t *testing.T) {
- const SCRIPT = `
- function A() {
- var x = 1;
- try {
- x = 2;
- } catch(e) {
- x = 3;
- } finally {
- x = 4;
- }
- return x;
- }
- var rv = A();
- `
- testScript(SCRIPT, intToValue(4), t)
- }
- func TestTryCatch(t *testing.T) {
- const SCRIPT = `
- function A() {
- var x;
- try {
- throw 4;
- } catch(e) {
- x = e;
- }
- return x;
- }
- var rv = A();
- `
- testScript(SCRIPT, intToValue(4), t)
- }
- func TestTryExceptionInCatch(t *testing.T) {
- const SCRIPT = `
- function A() {
- var x;
- try {
- throw 4;
- } catch(e) {
- throw 5;
- }
- return x;
- }
- var rv;
- try {
- A();
- } catch (e) {
- rv = e;
- }
- `
- testScript(SCRIPT, intToValue(5), t)
- }
- func TestTryContinueInFinally(t *testing.T) {
- const SCRIPT = `
- var c3 = 0, fin3 = 0;
- while (c3 < 2) {
- try {
- throw "ex1";
- } catch(er1) {
- c3 += 1;
- } finally {
- fin3 = 1;
- continue;
- }
- fin3 = 0;
- }
- fin3;
- `
- testScript1(SCRIPT, intToValue(1), t)
- }
- func TestCatchLexicalEnv(t *testing.T) {
- const SCRIPT = `
- function F() {
- try {
- throw 1;
- } catch (e) {
- var x = e;
- }
- return x;
- }
- F();
- `
- testScript1(SCRIPT, intToValue(1), t)
- }
- func TestThrowType(t *testing.T) {
- const SCRIPT = `
- function Exception(message) {
- this.message = message;
- }
- function A() {
- try {
- throw new Exception("boo!");
- } catch(e) {
- return e;
- }
- }
- var thrown = A();
- var rv = thrown !== null && typeof thrown === "object" && thrown.constructor === Exception;
- `
- testScript(SCRIPT, valueTrue, t)
- }
- func TestThrowConstructorName(t *testing.T) {
- const SCRIPT = `
- function Exception(message) {
- this.message = message;
- }
- function A() {
- try {
- throw new Exception("boo!");
- } catch(e) {
- return e;
- }
- }
- A().constructor.name;
- `
- testScript1(SCRIPT, asciiString("Exception"), t)
- }
- func TestThrowNativeConstructorName(t *testing.T) {
- const SCRIPT = `
- function A() {
- try {
- throw new TypeError();
- } catch(e) {
- return e;
- }
- }
- A().constructor.name;
- `
- testScript1(SCRIPT, asciiString("TypeError"), t)
- }
- func TestEmptyTryNoCatch(t *testing.T) {
- const SCRIPT = `
- var called = false;
- try {
- } finally {
- called = true;
- }
- called;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestIfElse(t *testing.T) {
- const SCRIPT = `
- var rv;
- if (rv === undefined) {
- rv = "passed";
- } else {
- rv = "failed";
- }
- `
- testScript(SCRIPT, asciiString("passed"), t)
- }
- func TestIfElseRetVal(t *testing.T) {
- const SCRIPT = `
- var x;
- if (x === undefined) {
- "passed";
- } else {
- "failed";
- }
- `
- testScript1(SCRIPT, asciiString("passed"), t)
- }
- func TestWhileReturnValue(t *testing.T) {
- const SCRIPT = `
- var x = 0;
- while(true) {
- x = 1;
- break;
- }
- `
- testScript1(SCRIPT, intToValue(1), t)
- }
- func TestIfElseLabel(t *testing.T) {
- const SCRIPT = `
- var x = 0;
- abc: if (true) {
- x = 1;
- break abc;
- }
- `
- testScript1(SCRIPT, intToValue(1), t)
- }
- func TestIfMultipleLabels(t *testing.T) {
- const SCRIPT = `
- var x = 0;
- xyz:abc: if (true) {
- break xyz;
- }
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestBreakOutOfTry(t *testing.T) {
- const SCRIPT = `
- function A() {
- var x = 1;
- B: {
- try {
- x = 2;
- } catch(e) {
- x = 3;
- } finally {
- break B;
- x = 4;
- }
- }
- return x;
- }
- A();
- `
- testScript1(SCRIPT, intToValue(2), t)
- }
- func TestReturnOutOfTryNested(t *testing.T) {
- const SCRIPT = `
- function A() {
- function nested() {
- try {
- return 1;
- } catch(e) {
- return 2;
- }
- }
- return nested();
- }
- A();
- `
- testScript1(SCRIPT, intToValue(1), t)
- }
- func TestContinueLoop(t *testing.T) {
- const SCRIPT = `
- function A() {
- var r = 0;
- for (var i = 0; i < 5; i++) {
- if (i > 1) {
- continue;
- }
- r++;
- }
- return r;
- }
- A();
- `
- testScript1(SCRIPT, intToValue(2), t)
- }
- func TestContinueOutOfTry(t *testing.T) {
- const SCRIPT = `
- function A() {
- var r = 0;
- for (var i = 0; i < 5; i++) {
- try {
- if (i > 1) {
- continue;
- }
- } catch(e) {
- return 99;
- }
- r++;
- }
- return r;
- }
- A();
- `
- testScript1(SCRIPT, intToValue(2), t)
- }
- func TestThisInCatch(t *testing.T) {
- const SCRIPT = `
- function O() {
- try {
- f();
- } catch (e) {
- this.value = e.toString();
- }
- }
- function f() {
- throw "ex";
- }
- var o = new O();
- o.value;
- `
- testScript1(SCRIPT, asciiString("ex"), t)
- }
- func TestNestedTry(t *testing.T) {
- const SCRIPT = `
- var ex;
- try {
- throw "ex1";
- } catch (er1) {
- try {
- throw "ex2";
- } catch (er1) {
- ex = er1;
- }
- }
- ex;
- `
- testScript1(SCRIPT, asciiString("ex2"), t)
- }
- func TestNestedTryInStashlessFunc(t *testing.T) {
- const SCRIPT = `
- function f() {
- var ex1, ex2;
- try {
- throw "ex1";
- } catch (er1) {
- try {
- throw "ex2";
- } catch (er1) {
- ex2 = er1;
- }
- ex1 = er1;
- }
- return ex1 == "ex1" && ex2 == "ex2";
- }
- f();
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestEvalInCatchInStashlessFunc(t *testing.T) {
- const SCRIPT = `
- function f() {
- var ex;
- try {
- throw "ex1";
- } catch (er1) {
- eval("ex = er1");
- }
- return ex;
- }
- f();
- `
- testScript1(SCRIPT, asciiString("ex1"), t)
- }
- func TestCatchClosureInStashlessFunc(t *testing.T) {
- const SCRIPT = `
- function f() {
- var ex;
- try {
- throw "ex1";
- } catch (er1) {
- return function() {
- return er1;
- }
- }
- }
- f()();
- `
- testScript1(SCRIPT, asciiString("ex1"), t)
- }
- func TestCatchVarNotUsedInStashlessFunc(t *testing.T) {
- const SCRIPT = `
- function f() {
- var ex;
- try {
- throw "ex1";
- } catch (er1) {
- ex = "ok";
- }
- return ex;
- }
- f();
- `
- testScript1(SCRIPT, asciiString("ok"), t)
- }
- func TestNew(t *testing.T) {
- const SCRIPT = `
- function O() {
- this.x = 42;
- }
- new O().x;
- `
- testScript1(SCRIPT, intToValue(42), t)
- }
- func TestStringConstructor(t *testing.T) {
- const SCRIPT = `
- function F() {
- return String(33) + " " + String("cows");
- }
- F();
- `
- testScript1(SCRIPT, asciiString("33 cows"), t)
- }
- func TestError(t *testing.T) {
- const SCRIPT = `
- function F() {
- return new Error("test");
- }
- var e = F();
- var rv = e.message == "test" && e.name == "Error";
- `
- testScript(SCRIPT, valueTrue, t)
- }
- func TestTypeError(t *testing.T) {
- const SCRIPT = `
- function F() {
- return new TypeError("test");
- }
- var e = F();
- e.message == "test" && e.name == "TypeError";
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestToString(t *testing.T) {
- const SCRIPT = `
- var o = {x: 42};
- o.toString = function() {
- return String(this.x);
- }
- var o1 = {};
- o.toString() + " ### " + o1.toString();
- `
- testScript1(SCRIPT, asciiString("42 ### [object Object]"), t)
- }
- func TestEvalOrder(t *testing.T) {
- const SCRIPT = `
- var o = {f: function() {return 42}, x: 0};
- var trace = "";
- function F1() {
- trace += "First!";
- return o;
- }
- function F2() {
- trace += "Second!";
- return "f";
- }
- function F3() {
- trace += "Third!";
- }
- var rv = F1()[F2()](F3());
- rv += trace;
- `
- testScript(SCRIPT, asciiString("42First!Second!Third!"), t)
- }
- func TestPostfixIncBracket(t *testing.T) {
- const SCRIPT = `
- var o = {x: 42};
- var trace = "";
- function F1() {
- trace += "First!";
- return o;
- }
- function F2() {
- trace += "Second!";
- return "x";
- }
- var rv = F1()[F2()]++;
- rv += trace + o.x;
- `
- testScript(SCRIPT, asciiString("42First!Second!43"), t)
- }
- func TestPostfixIncDot(t *testing.T) {
- const SCRIPT = `
- var o = {x: 42};
- var trace = "";
- function F1() {
- trace += "First!";
- return o;
- }
- var rv = F1().x++;
- rv += trace + o.x;
- `
- testScript(SCRIPT, asciiString("42First!43"), t)
- }
- func TestPrefixIncBracket(t *testing.T) {
- const SCRIPT = `
- var o = {x: 42};
- var trace = "";
- function F1() {
- trace += "First!";
- return o;
- }
- function F2() {
- trace += "Second!";
- return "x";
- }
- var rv = ++F1()[F2()];
- rv += trace + o.x;
- `
- testScript(SCRIPT, asciiString("43First!Second!43"), t)
- }
- func TestPrefixIncDot(t *testing.T) {
- const SCRIPT = `
- var o = {x: 42};
- var trace = "";
- function F1() {
- trace += "First!";
- return o;
- }
- var rv = ++F1().x;
- rv += trace + o.x;
- `
- testScript(SCRIPT, asciiString("43First!43"), t)
- }
- func TestPostDecObj(t *testing.T) {
- const SCRIPT = `
- var object = {valueOf: function() {return 1}};
- var y = object--;
- var ok = false;
- if (y === 1) {
- ok = true;
- }
- ok;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestPropAcc1(t *testing.T) {
- const SCRIPT = `
- 1..toString()
- `
- testScript1(SCRIPT, asciiString("1"), t)
- }
- func TestEvalDirect(t *testing.T) {
- const SCRIPT = `
- var rv = false;
- function foo(){ rv = true; }
- var o = { };
- function f() {
- try {
- eval("o.bar( foo() );");
- } catch (e) {
- }
- }
- f();
- `
- testScript(SCRIPT, valueTrue, t)
- }
- func TestEvalRet(t *testing.T) {
- const SCRIPT = `
- eval("for (var i = 0; i < 3; i++) {i}")
- `
- testScript1(SCRIPT, valueInt(2), t)
- }
- func TestEvalFunctionDecl(t *testing.T) {
- const SCRIPT = `
- eval("function F() {}")
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestEvalFunctionExpr(t *testing.T) {
- const SCRIPT = `
- eval("(function F() {return 42;})")()
- `
- testScript1(SCRIPT, intToValue(42), t)
- }
- func TestForLoopRet(t *testing.T) {
- const SCRIPT = `
- for (var i = 0; i < 20; i++) { if (i > 2) {break;} else { i }}
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestForLoopRet1(t *testing.T) {
- const SCRIPT = `
- for (var i = 0; i < 20; i++) { if (i > 2) {42;; {L:{break;}}} else { i }}
- `
- testScript1(SCRIPT, intToValue(42), t)
- }
- func TestForInLoopRet(t *testing.T) {
- const SCRIPT = `
- var o = [1, 2, 3, 4];
- for (var i in o) { if (i > 2) {break;} else { i }}
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestForInLoopRet1(t *testing.T) {
- const SCRIPT = `
- var o = {};
- o.x = 1;
- o.y = 2;
- for (var i in o) {
- true;
- }
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestDoWhileLoopRet(t *testing.T) {
- const SCRIPT = `
- var i = 0;
- do {
- if (i > 2) {
- break;
- } else {
- i;
- }
- } while (i++ < 20);
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestDoWhileContinueRet(t *testing.T) {
- const SCRIPT = `
- var i = 0;
- do {
- if (i > 2) {
- true;
- continue;
- } else {
- i;
- }
- } while (i++ < 20);
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestWhileLoopRet(t *testing.T) {
- const SCRIPT = `
- var i; while (i < 20) { if (i > 2) {break;} else { i++ }}
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestLoopRet1(t *testing.T) {
- const SCRIPT = `
- for (var i = 0; i < 20; i++) { }
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestInstanceof(t *testing.T) {
- const SCRIPT = `
- var rv;
- try {
- true();
- } catch (e) {
- rv = e instanceof TypeError;
- }
- `
- testScript(SCRIPT, valueTrue, t)
- }
- func TestStrictAssign(t *testing.T) {
- const SCRIPT = `
- 'use strict';
- var rv;
- var called = false;
- function F() {
- called = true;
- return 1;
- }
- try {
- x = F();
- } catch (e) {
- rv = e instanceof ReferenceError;
- }
- rv += " " + called;
- `
- testScript(SCRIPT, asciiString("true true"), t)
- }
- func TestStrictScope(t *testing.T) {
- const SCRIPT = `
- var rv;
- var called = false;
- function F() {
- 'use strict';
- x = 1;
- }
- try {
- F();
- } catch (e) {
- rv = e instanceof ReferenceError;
- }
- x = 1;
- rv += " " + x;
- `
- testScript(SCRIPT, asciiString("true 1"), t)
- }
- func TestStringObj(t *testing.T) {
- const SCRIPT = `
- var s = new String("test");
- s[0] + s[2] + s[1];
- `
- testScript1(SCRIPT, asciiString("tse"), t)
- }
- func TestStringPrimitive(t *testing.T) {
- const SCRIPT = `
- var s = "test";
- s[0] + s[2] + s[1];
- `
- testScript1(SCRIPT, asciiString("tse"), t)
- }
- func TestCallGlobalObject(t *testing.T) {
- const SCRIPT = `
- var rv;
- try {
- this();
- } catch (e) {
- rv = e instanceof TypeError
- }
- `
- testScript(SCRIPT, valueTrue, t)
- }
- func TestFuncLength(t *testing.T) {
- const SCRIPT = `
- function F(x, y) {
- }
- F.length
- `
- testScript1(SCRIPT, intToValue(2), t)
- }
- func TestNativeFuncLength(t *testing.T) {
- const SCRIPT = `
- eval.length + Object.defineProperty.length + String.length
- `
- testScript1(SCRIPT, intToValue(5), t)
- }
- func TestArguments(t *testing.T) {
- const SCRIPT = `
- function F() {
- return arguments.length + " " + arguments[1];
- }
- F(1,2,3)
- `
- testScript1(SCRIPT, asciiString("3 2"), t)
- }
- func TestArgumentsPut(t *testing.T) {
- const SCRIPT = `
- function F(x, y) {
- arguments[0] -= arguments[1];
- return x;
- }
- F(5, 2)
- `
- testScript1(SCRIPT, intToValue(3), t)
- }
- func TestArgumentsPutStrict(t *testing.T) {
- const SCRIPT = `
- function F(x, y) {
- 'use strict';
- arguments[0] -= arguments[1];
- return x;
- }
- F(5, 2)
- `
- testScript1(SCRIPT, intToValue(5), t)
- }
- func TestArgumentsExtra(t *testing.T) {
- const SCRIPT = `
- function F(x, y) {
- return arguments[2];
- }
- F(1, 2, 42)
- `
- testScript1(SCRIPT, intToValue(42), t)
- }
- func TestArgumentsExist(t *testing.T) {
- const SCRIPT = `
- function F(x, arguments) {
- return arguments;
- }
- F(1, 42)
- `
- testScript1(SCRIPT, intToValue(42), t)
- }
- func TestArgumentsDelete(t *testing.T) {
- const SCRIPT = `
- function f(x) {
- delete arguments[0];
- arguments[0] = 42;
- return x;
- }
- f(1)
- `
- testScript1(SCRIPT, intToValue(1), t)
- }
- func TestWith(t *testing.T) {
- const SCRIPT = `
- var b = 1;
- var o = {a: 41};
- with(o) {
- a += b;
- }
- o.a;
- `
- testScript1(SCRIPT, intToValue(42), t)
- }
- func TestWithInFunc(t *testing.T) {
- const SCRIPT = `
- function F() {
- var b = 1;
- var c = 0;
- var o = {a: 40, c: 1};
- with(o) {
- a += b + c;
- }
- return o.a;
- }
- F();
- `
- testScript1(SCRIPT, intToValue(42), t)
- }
- func TestAssignNonExtendable(t *testing.T) {
- const SCRIPT = `
- 'use strict';
- function F() {
- this.x = 1;
- }
- var o = new F();
- Object.preventExtensions(o);
- o.x = 42;
- o.x;
- `
- testScript1(SCRIPT, intToValue(42), t)
- }
- func TestAssignNonExtendable1(t *testing.T) {
- const SCRIPT = `
- 'use strict';
- function F() {
- }
- var o = new F();
- var rv;
- Object.preventExtensions(o);
- try {
- o.x = 42;
- } catch (e) {
- rv = e.constructor === TypeError;
- }
- rv += " " + o.x;
- `
- testScript(SCRIPT, asciiString("true undefined"), t)
- }
- func TestAssignStrict(t *testing.T) {
- const SCRIPT = `
- 'use strict';
- try {
- eval("eval = 42");
- } catch(e) {
- var rv = e instanceof SyntaxError
- }
- `
- testScript(SCRIPT, valueTrue, t)
- }
- func TestIllegalArgmentName(t *testing.T) {
- const SCRIPT = `
- 'use strict';
- try {
- eval("function F(eval) {}");
- } catch (e) {
- var rv = e instanceof SyntaxError
- }
- `
- testScript(SCRIPT, valueTrue, t)
- }
- func TestFunction(t *testing.T) {
- const SCRIPT = `
- var f0 = Function("");
- var f1 = Function("return ' one'");
- var f2 = Function("arg", "return ' ' + arg");
- f0() + f1() + f2("two");
- `
- testScript1(SCRIPT, asciiString("undefined one two"), t)
- }
- func TestFunction1(t *testing.T) {
- const SCRIPT = `
- var f = function f1(count) {
- if (count == 0) {
- return true;
- }
- return f1(count-1);
- }
- f(1);
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestFunction2(t *testing.T) {
- const SCRIPT = `
- var trace = "";
- function f(count) {
- trace += "f("+count+")";
- if (count == 0) {
- return;
- }
- return f(count-1);
- }
- function f1() {
- trace += "f1";
- }
- var f2 = f;
- f = f1;
- f2(1);
- trace;
- `
- testScript1(SCRIPT, asciiString("f(1)f1"), t)
- }
- func TestFunctionToString(t *testing.T) {
- const SCRIPT = `
- Function("arg1", "arg2", "return 42").toString();
- `
- testScript1(SCRIPT, asciiString("function anonymous(arg1,arg2){return 42}"), t)
- }
- func TestObjectLiteral(t *testing.T) {
- const SCRIPT = `
- var getterCalled = false;
- var setterCalled = false;
- var o = {get x() {getterCalled = true}, set x() {setterCalled = true}};
- o.x;
- o.x = 42;
- getterCalled && setterCalled;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestConst(t *testing.T) {
- const SCRIPT = `
- var v1 = true && true;
- var v2 = 1/(-1 * 0);
- var v3 = 1 == 2 || v1;
- var v4 = true && false
- v1 === true && v2 === -Infinity && v3 === v1 && v4 === false;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestConstWhile(t *testing.T) {
- const SCRIPT = `
- var c = 0;
- while (2 + 2 === 4) {
- if (++c > 9) {
- break;
- }
- }
- c === 10;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestConstWhileThrow(t *testing.T) {
- const SCRIPT = `
- var thrown = false;
- try {
- while ('s' in true) {
- break;
- }
- } catch (e) {
- thrown = e instanceof TypeError
- }
- thrown;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestDupParams(t *testing.T) {
- const SCRIPT = `
- function F(x, y, x) {
- return x;
- }
- F(1, 2);
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestUseUnsuppliedParam(t *testing.T) {
- const SCRIPT = `
- function getMessage(message) {
- if (message === undefined) {
- message = '';
- }
- message += " 123 456";
- return message;
- }
- getMessage();
- `
- testScript1(SCRIPT, asciiString(" 123 456"), t)
- }
- func TestForInLoop(t *testing.T) {
- const SCRIPT = `
- function Proto() {}
- Proto.prototype.x = 42;
- var o = new Proto();
- o.y = 44;
- o.x = 45;
- var hasX = false;
- var hasY = false;
- for (var i in o) {
- switch(i) {
- case "x":
- if (hasX) {
- throw new Error("Already has X");
- }
- hasX = true;
- break;
- case "y":
- if (hasY) {
- throw new Error("Already has Y");
- }
- hasY = true;
- break;
- }
- }
- hasX && hasY;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestWhileLoopResult(t *testing.T) {
- const SCRIPT = `
- while(false);
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestEmptySwitch(t *testing.T) {
- const SCRIPT = `
- switch(1){}
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestEmptyDoWhile(t *testing.T) {
- const SCRIPT = `
- do {} while(false)
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestSwitch(t *testing.T) {
- const SCRIPT = `
- function F(x) {
- var i = 0;
- switch (x) {
- case 0:
- i++;
- case 1:
- i++;
- default:
- i++;
- case 2:
- i++;
- break;
- case 3:
- i++;
- }
- return i;
- }
- F(0) + F(1) + F(2) + F(4);
- `
- testScript1(SCRIPT, intToValue(10), t)
- }
- func TestSwitchDefFirst(t *testing.T) {
- const SCRIPT = `
- function F(x) {
- var i = 0;
- switch (x) {
- default:
- i++;
- case 0:
- i++;
- case 1:
- i++;
- case 2:
- i++;
- break;
- case 3:
- i++;
- }
- return i;
- }
- F(0) + F(1) + F(2) + F(4);
- `
- testScript1(SCRIPT, intToValue(10), t)
- }
- func TestSwitchResult(t *testing.T) {
- const SCRIPT = `
- var x = 2;
- switch (x) {
- case 0:
- "zero";
- case 1:
- "one";
- case 2:
- "two";
- break;
- case 3:
- "three";
- default:
- "default";
- }
- `
- testScript1(SCRIPT, asciiString("two"), t)
- }
- func TestSwitchResult1(t *testing.T) {
- const SCRIPT = `
- var x = 0;
- switch (x) { case 0: "two"; case 1: break}
- `
- testScript1(SCRIPT, asciiString("two"), t)
- }
- func TestIfBreakResult(t *testing.T) {
- const SCRIPT = `
- L: {if (true) {42;} break L;}
- `
- testScript1(SCRIPT, intToValue(42), t)
- }
- func TestSwitchNoMatch(t *testing.T) {
- const SCRIPT = `
- var result;
- var x;
- switch (x) {
- case 0:
- result = "2";
- break;
- }
- result;
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestSwitchNoMatchNoDefault(t *testing.T) {
- const SCRIPT = `
- switch (1) {
- case 0:
- }
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestSwitchNoMatchNoDefaultNoResult(t *testing.T) {
- const SCRIPT = `
- switch (1) {
- case 0:
- }
- 42;
- `
- testScript1(SCRIPT, intToValue(42), t)
- }
- func TestSwitchNoMatchNoDefaultNoResultMatch(t *testing.T) {
- const SCRIPT = `
- switch (1) {
- case 1:
- }
- 42;
- `
- testScript1(SCRIPT, intToValue(42), t)
- }
- func TestEmptySwitchNoResult(t *testing.T) {
- const SCRIPT = `
- switch (1) {}
- 42;
- `
- testScript1(SCRIPT, intToValue(42), t)
- }
- func TestGetOwnPropertyNames(t *testing.T) {
- const SCRIPT = `
- var o = {
- prop1: 42,
- prop2: "test"
- }
- var hasProp1 = false;
- var hasProp2 = false;
- var names = Object.getOwnPropertyNames(o);
- for (var i in names) {
- var p = names[i];
- switch(p) {
- case "prop1":
- hasProp1 = true;
- break;
- case "prop2":
- hasProp2 = true;
- break;
- }
- }
- hasProp1 && hasProp2;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestArrayLiteral(t *testing.T) {
- const SCRIPT = `
- var f1Called = false;
- var f2Called = false;
- var f3Called = false;
- var errorThrown = false;
- function F1() {
- f1Called = true;
- }
- function F2() {
- f2Called = true;
- }
- function F3() {
- f3Called = true;
- }
- try {
- var a = [F1(), x(F3()), F2()];
- } catch(e) {
- if (e instanceof ReferenceError) {
- errorThrown = true;
- } else {
- throw e;
- }
- }
- f1Called && !f2Called && f3Called && errorThrown && a === undefined;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestJumpOutOfReturn(t *testing.T) {
- const SCRIPT = `
- function f() {
- var a;
- if (a == 0) {
- return true;
- }
- }
- f();
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestSwitchJumpOutOfReturn(t *testing.T) {
- const SCRIPT = `
- function f(x) {
- switch(x) {
- case 0:
- break;
- default:
- return x;
- }
- }
- f(0);
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestSetToReadOnlyPropertyStrictBracket(t *testing.T) {
- const SCRIPT = `
- 'use strict';
- var o = {};
- var thrown = false;
- Object.defineProperty(o, "test", {value: 42, configurable: true});
- try {
- o["test"] = 43;
- } catch (e) {
- thrown = e instanceof TypeError;
- }
- thrown;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestSetToReadOnlyPropertyStrictDot(t *testing.T) {
- const SCRIPT = `
- 'use strict';
- var o = {};
- var thrown = false;
- Object.defineProperty(o, "test", {value: 42, configurable: true});
- try {
- o.test = 43;
- } catch (e) {
- thrown = e instanceof TypeError;
- }
- thrown;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestDeleteNonConfigurablePropertyStrictBracket(t *testing.T) {
- const SCRIPT = `
- 'use strict';
- var o = {};
- var thrown = false;
- Object.defineProperty(o, "test", {value: 42});
- try {
- delete o["test"];
- } catch (e) {
- thrown = e instanceof TypeError;
- }
- thrown;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestDeleteNonConfigurablePropertyStrictDot(t *testing.T) {
- const SCRIPT = `
- 'use strict';
- var o = {};
- var thrown = false;
- Object.defineProperty(o, "test", {value: 42});
- try {
- delete o.test;
- } catch (e) {
- thrown = e instanceof TypeError;
- }
- thrown;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestCompound1(t *testing.T) {
- const SCRIPT = `
- var x = 0;
- var scope = {x: 1};
- var f;
- with (scope) {
- f = function() {
- x *= (delete scope.x, 2);
- }
- }
- f();
- scope.x === 2 && x === 0;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestCompound2(t *testing.T) {
- const SCRIPT = `
- var x;
- x = "x";
- x ^= "1";
- `
- testScript1(SCRIPT, intToValue(1), t)
- }
- func TestDeleteArguments(t *testing.T) {
- defer func() {
- if _, ok := recover().(*CompilerSyntaxError); !ok {
- t.Fatal("Expected syntax error")
- }
- }()
- const SCRIPT = `
- 'use strict';
- function f() {
- delete arguments;
- }
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestReturnUndefined(t *testing.T) {
- const SCRIPT = `
- function f() {
- return x;
- }
- var thrown = false;
- try {
- f();
- } catch (e) {
- thrown = e instanceof ReferenceError;
- }
- thrown;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestForBreak(t *testing.T) {
- const SCRIPT = `
- var supreme, count;
- supreme = 5;
- var __evaluated = eval("for(count=0;;) {if (count===supreme)break;else count++; }");
- if (__evaluated !== void 0) {
- throw new Error('#1: __evaluated === 4. Actual: __evaluated ==='+ __evaluated );
- }
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestLargeNumberLiteral(t *testing.T) {
- const SCRIPT = `
- var x = 0x800000000000000000000;
- x.toString();
- `
- testScript1(SCRIPT, asciiString("9.671406556917033e+24"), t)
- }
- func TestIncDelete(t *testing.T) {
- const SCRIPT = `
- var o = {x: 1};
- o.x += (delete o.x, 1);
- o.x;
- `
- testScript1(SCRIPT, intToValue(2), t)
- }
- func TestCompoundAssignRefError(t *testing.T) {
- const SCRIPT = `
- var thrown = false;
- try {
- a *= 1;
- } catch (e) {
- if (e instanceof ReferenceError) {
- thrown = true;
- } else {
- throw e;
- }
- }
- thrown;
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestObjectLiteral__Proto__(t *testing.T) {
- const SCRIPT = `
- var o = {
- __proto__: null,
- test: 42
- }
- Object.getPrototypeOf(o);
- `
- testScript1(SCRIPT, _null, t)
- }
- func TestEmptyCodeError(t *testing.T) {
- if _, err := New().RunString(`i`); err == nil {
- t.Fatal("Expected an error")
- } else {
- if e := err.Error(); e != "ReferenceError: i is not defined at <eval>:1:1(0)" {
- t.Fatalf("Unexpected error: '%s'", e)
- }
- }
- }
- func TestForOfArray(t *testing.T) {
- const SCRIPT = `
- var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
- var i = 0;
-
- for (var value of array) {
- assert.sameValue(value, array[i], 'element at index ' + i);
- i++;
- }
-
- assert.sameValue(i, 8, 'Visits all elements');
- `
- testScript1(TESTLIB+SCRIPT, _undefined, t)
- }
- func TestForOfReturn(t *testing.T) {
- const SCRIPT = `
- var callCount = 0;
- var iterationCount = 0;
- var iterable = {};
- var x = {
- set attr(_) {
- throw new Test262Error();
- }
- };
-
- iterable[Symbol.iterator] = function() {
- return {
- next: function() {
- return { done: false, value: 0 };
- },
- return: function() {
- callCount += 1;
- }
- }
- };
-
- assert.throws(Test262Error, function() {
- for (x.attr of iterable) {
- iterationCount += 1;
- }
- });
-
- assert.sameValue(iterationCount, 0, 'The loop body is not evaluated');
- assert.sameValue(callCount, 1, 'Iterator is closed');
- `
- testScript1(TESTLIB+SCRIPT, _undefined, t)
- }
- func TestReturnFromForInLoop(t *testing.T) {
- const SCRIPT = `
- (function f() {
- for (var i in {a: 1}) {
- return true;
- }
- })();
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestReturnFromForOfLoop(t *testing.T) {
- const SCRIPT = `
- (function f() {
- for (var i of [1]) {
- return true;
- }
- })();
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestIfStackLeaks(t *testing.T) {
- const SCRIPT = `
- var t = 0;
- if (t === 0) {
- t;
- }
- `
- testScript1(SCRIPT, _positiveZero, t)
- }
- func TestWithCallee(t *testing.T) {
- const SCRIPT = `
- function O() {
- var that = this;
- this.m = function() {
- return this === that;
- }
- }
- with(new O()) {
- m();
- }
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestEvalCallee(t *testing.T) {
- const SCRIPT = `
- (function () {
- 'use strict';
- var v = function() {
- return this === undefined;
- };
- return eval('v()');
- })();
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func TestTryEmptyCatchStackLeak(t *testing.T) {
- const SCRIPT = `
- (function() {
- var f;
- // Make sure the outer function is not stashless as retStashless masks all stack leaks.
- (function() {
- f++;
- })();
- try {
- throw new Error();
- } catch(e) {}
- })();
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestFalsyLoopBreak(t *testing.T) {
- const SCRIPT = `
- while(false) {
- break;
- }
- for(;false;) {
- break;
- }
- undefined;
- `
- MustCompile("", SCRIPT, false)
- }
- func TestFalsyLoopBreakWithResult(t *testing.T) {
- const SCRIPT = `
- while(false) {
- break;
- }
- `
- testScript1(SCRIPT, _undefined, t)
- }
- func TestDummyCompile(t *testing.T) {
- const SCRIPT = `
- 'use strict';
-
- for (;false;) {
- eval = 1;
- }
- `
- _, err := Compile("", SCRIPT, false)
- if err == nil {
- t.Fatal("expected error")
- }
- }
- func TestDummyCompileForUpdate(t *testing.T) {
- const SCRIPT = `
- 'use strict';
-
- for (;false;eval=1) {
- }
- `
- _, err := Compile("", SCRIPT, false)
- if err == nil {
- t.Fatal("expected error")
- }
- }
- func TestObjectLiteralWithNumericKeys(t *testing.T) {
- const SCRIPT = `
- var o = {1e3: true};
- var keys = Object.keys(o);
- var o1 = {get 1e3() {return true;}};
- var keys1 = Object.keys(o1);
- var o2 = {1e21: true};
- var keys2 = Object.keys(o2);
- keys.length === 1 && keys[0] === "1000" &&
- keys1.length === 1 && keys1[0] === "1000" && o1[1e3] === true &&
- keys2.length === 1 && keys2[0] === "1e+21";
- `
- testScript1(SCRIPT, valueTrue, t)
- }
- func BenchmarkCompile(b *testing.B) {
- f, err := os.Open("testdata/S15.10.2.12_A1_T1.js")
- data, err := ioutil.ReadAll(f)
- if err != nil {
- b.Fatal(err)
- }
- f.Close()
- src := string(data)
- for i := 0; i < b.N; i++ {
- _, err := Compile("test.js", src, false)
- if err != nil {
- b.Fatal(err)
- }
- }
- }
|