michael@0: function errorToString(e) { michael@0: try {} catch (e2) {} michael@0: } michael@0: Object.getOwnPropertyNames(this); michael@0: if (false) { michael@0: for (let x of constructors) michael@0: print(x); michael@0: } michael@0: var tryRunning = tryRunningDirectly; michael@0: function unlikelyToHang(code) { michael@0: var codeL = code.replace(/\s/g, " "); michael@0: return true && code.indexOf("infloop") == -1 && !(codeL.match(/const.*for/)) // can be an infinite loop: function() { const x = 1; for each(x in ({a1:1})) dumpln(3); } michael@0: && !(codeL.match(/for.*const/)) // can be an infinite loop: for each(x in ...); const x; michael@0: && !(codeL.match(/for.*in.*uneval/)) // can be slow to loop through the huge string uneval(this), for example michael@0: && !(codeL.match(/for.*for.*for/)) // nested for loops (including for..in, array comprehensions, etc) can take a while michael@0: && !(codeL.match(/for.*for.*gc/)) michael@0: } michael@0: function whatToTestSpidermonkeyTrunk(code) { michael@0: var codeL = code.replace(/\s/g, " "); michael@0: return { michael@0: allowParse: true, michael@0: allowExec: unlikelyToHang(code), michael@0: allowIter: true, michael@0: expectConsistentOutput: true && code.indexOf("Date") == -1 // time marches on michael@0: && code.indexOf("random") == -1 && code.indexOf("dumpObject") == -1 // shows heap addresses michael@0: && code.indexOf("oomAfterAllocations") == -1 && code.indexOf("ParallelArray") == -1, michael@0: expectConsistentOutputAcrossIter: true && code.indexOf("options") == -1 // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment michael@0: , michael@0: expectConsistentOutputAcrossJITs: true && code.indexOf("'strict") == -1 // bug 743425 michael@0: && code.indexOf("preventExtensions") == -1 // bug 887521 michael@0: && !(codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?) michael@0: }; michael@0: } michael@0: function tryRunningDirectly(f, code, wtt) { michael@0: try { michael@0: eval(code); michael@0: } catch (e) {} michael@0: try { michael@0: var rv = f(); michael@0: tryIteration(rv); michael@0: } catch (runError) { michael@0: var err = errorToString(runError); michael@0: } michael@0: tryEnsureSanity(); michael@0: } michael@0: var realEval = eval; michael@0: var realMath = Math; michael@0: var realFunction = Function; michael@0: var realGC = gc; michael@0: var realUneval = uneval; michael@0: function tryEnsureSanity() { michael@0: try { michael@0: delete this.Math; michael@0: delete this.Function; michael@0: delete this.gc; michael@0: delete this.uneval; michael@0: this.Math = realMath; michael@0: this.eval = realEval; michael@0: this.Function = realFunction; michael@0: this.gc = realGC; michael@0: this.uneval = realUneval; michael@0: } catch (e) {} michael@0: } michael@0: function tryIteration(rv) { michael@0: try { michael@0: var iterCount = 0; michael@0: for /* each */ michael@0: ( /* let */ iterValue in rv) michael@0: print("Iterating succeeded, iterCount == " + iterCount); michael@0: } catch (iterError) {} michael@0: } michael@0: function failsToCompileInTry(code) { michael@0: try { michael@0: new Function(" try { " + code + " } catch(e) { }"); michael@0: } catch (e) {} michael@0: } michael@0: function tryItOut(code) { michael@0: if (count % 1000 == 0) { michael@0: gc(); michael@0: } michael@0: var wtt = whatToTestSpidermonkeyTrunk(code); michael@0: code = code.replace(/\/\*DUPTRY\d+\*\//, function(k) { michael@0: var n = parseInt(k.substr(8), 10); michael@0: print(n); michael@0: return strTimes("try{}catch(e){}", n); michael@0: }) michael@0: try { michael@0: f = new Function(code); michael@0: } catch (compileError) {} michael@0: if (code.indexOf("\n") == -1 && code.indexOf("\r") == -1 && code.indexOf("\f") == -1 && code.indexOf("\0") == -1 && code.indexOf("\u2028") == -1 && code.indexOf("\u2029") == -1 && code.indexOf("<--") == -1 && code.indexOf("-->") == -1 && code.indexOf("//") == -1) { michael@0: var nCode = code; michael@0: if (nCode.indexOf("return") != -1 || nCode.indexOf("yield") != -1 || nCode.indexOf("const") != -1 || failsToCompileInTry(nCode)) nCode = "(function(){" + nCode + "})()" michael@0: } michael@0: tryRunning(f, code, false); michael@0: } michael@0: var count = 0; michael@0: tryItOut(""); michael@0: count = 2 michael@0: tryItOut(""); michael@0: tryItOut(""); michael@0: tryItOut("o") michael@0: tryItOut("") michael@0: tryItOut("") michael@0: tryItOut("\ michael@0: with((/ /-7))\ michael@0: {\ michael@0: for(let mjcpxc=0;mjcpxc<9;++mjcpxc)\ michael@0: {\ michael@0: e=mjcpxc;\ michael@0: yield/x/\ michael@0: }}") michael@0: