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