author | Shu-yu Guo <shu@rfrn.org> |
Thu, 13 Nov 2014 14:39:40 -0800 | |
changeset 215678 | f8e316fa65bb1adb3a07cfd8076f9cbbf735657f |
parent 215677 | 1176cc3c3b3476a04b8b9a7f1629c9d8edd4b779 |
child 215679 | 96a2f59f6ce4f9230407e06c97b492f95ddbb091 |
push id | 27823 |
push user | cbook@mozilla.com |
push date | Fri, 14 Nov 2014 11:59:57 +0000 |
treeherder | mozilla-central@bbb68df450c2 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jimb |
bugs | 1063330 |
milestone | 36.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/lib/evalInFrame.js @@ -0,0 +1,32 @@ +var evalInFrame = (function (global) { + var dbgGlobal = newGlobal(); + var dbg = new dbgGlobal.Debugger(); + + return function evalInFrame(upCount, code) { + dbg.addDebuggee(global); + + // Skip ourself. + var frame = dbg.getNewestFrame().older; + for (var i = 0; i < upCount; i++) { + if (!frame.older) + break; + frame = frame.older; + } + + var completion = frame.eval(code); + if (completion.return) { + var v = completion.return; + if (typeof v === "object") + v = v.unsafeDereference(); + return v; + } + if (completion.throw) { + var v = completion.throw; + if (typeof v === "object") + v = v.unsafeDereference(); + throw v; + } + if (completion === null) + terminate(); + }; +})(this);
--- a/js/src/jit-test/tests/auto-regress/bug765483.js +++ b/js/src/jit-test/tests/auto-regress/bug765483.js @@ -1,16 +1,15 @@ // |jit-test| error:ReferenceError; // Binary: cache/js-dbg-64-de23a9fc29db-linux // Flags: --ion-eager // -var g = newGlobal(); -var dbg = new g.Debugger(this); +load(libdir + "evalInFrame.js"); var obj1 = {}, obj2 = {}; obj2['b'+i] = 0; for (var k in obj2) { (function g() { evalInFrame(1, "assertStackIs(['eval-code', f, 'bound(f)', 'global-code'])", true); })(); } for (var i = 0; i != array.length; ++i) array[i]();
--- a/js/src/jit-test/tests/auto-regress/bug800878.js +++ b/js/src/jit-test/tests/auto-regress/bug800878.js @@ -1,11 +1,13 @@ // |jit-test| error:Error // Binary: cache/js-dbg-32-1301a72b1c39-linux // Flags: --ion-eager // +load(libdir + "evalInFrame.js"); + [1,2,3,4,(':'),6,7,8].forEach( function(x) { assertEq(evalInFrame(0, ('^')), x); } );
--- a/js/src/jit-test/tests/basic/bug646968-7.js +++ b/js/src/jit-test/tests/basic/bug646968-7.js @@ -1,10 +1,9 @@ -var g = newGlobal(); -var dbg = new g.Debugger(this); +load(libdir + "evalInFrame.js"); function test(s) { eval(s); let (y = evalInFrame(0, '3'), x = x) { assertEq(x, 5); } } test('var x = 5;');
--- a/js/src/jit-test/tests/basic/bug646968-8.js +++ b/js/src/jit-test/tests/basic/bug646968-8.js @@ -1,8 +1,7 @@ -var g = newGlobal(); -var dbg = new g.Debugger(this); +load(libdir + "evalInFrame.js"); var x = 5; let (x = eval("x++")) { assertEq(evalInFrame(0, "x"), 5); } assertEq(x, 6);
--- a/js/src/jit-test/tests/basic/eif-generator.js +++ b/js/src/jit-test/tests/basic/eif-generator.js @@ -1,12 +1,9 @@ -var global = newGlobal(); -var dbg = new global.Debugger(this); -// Force dbg to observe all execution. -dbg.onDebuggerStatement = function () {}; +load(libdir + "evalInFrame.js"); function f() { let (x = 1) { while (true) { yield evalInFrame(0, "x"); x++; let (y = 1) { yield evalInFrame(0, "++y");
--- a/js/src/jit-test/tests/basic/testBug552248.js +++ b/js/src/jit-test/tests/basic/testBug552248.js @@ -1,12 +1,9 @@ -var global = newGlobal(); -var dbg = new global.Debugger(this); -// Force dbg to observe all execution. -dbg.onDebuggerStatement = function () {}; +load(libdir + "evalInFrame.js"); var a = new Array(); function i(save) { var x = 9; evalInFrame(0, "a.push(x)", save); evalInFrame(1, "a.push(z)", save); evalInFrame(2, "a.push(z)", save);
--- a/js/src/jit-test/tests/basic/testBug663789-2.js +++ b/js/src/jit-test/tests/basic/testBug663789-2.js @@ -1,7 +1,6 @@ -var g = newGlobal(); -var dbg = new g.Debugger(this); +load(libdir + "evalInFrame.js"); o = { toString:function() { return evalInFrame(1, "x") } } var x = 'C'; var s = "aaaaaaaaaa".replace(/a/g, function() { var x = 'B'; return o }); assertEq(s, "CCCCCCCCCC");
--- a/js/src/jit-test/tests/basic/testEvalInFrameEdgeCase.js +++ b/js/src/jit-test/tests/basic/testEvalInFrameEdgeCase.js @@ -1,10 +1,9 @@ -var global = newGlobal(); -var dbg = new global.Debugger(this); +load(libdir + "evalInFrame.js"); function g() { var x = 100; return evalInFrame(2, "x"); } function f() { var x = 42; return evalInFrame.call(null, 0, "g()");
--- a/js/src/jit-test/tests/jaeger/bug563000/eif-call-newvar.js +++ b/js/src/jit-test/tests/jaeger/bug563000/eif-call-newvar.js @@ -1,10 +1,9 @@ -var g = newGlobal(); -var dbg = new g.Debugger(this); +load(libdir + "evalInFrame.js"); function callee() { evalInFrame(1, "var x = 'success'"); } function caller(code) { eval(code); callee(); return x;
--- a/js/src/jit-test/tests/jaeger/bug563000/eif-call-typechange.js +++ b/js/src/jit-test/tests/jaeger/bug563000/eif-call-typechange.js @@ -1,10 +1,9 @@ -var g = newGlobal(); -var dbg = new g.Debugger(this); +load(libdir + "evalInFrame.js"); function callee() { evalInFrame(1, "x = 'success'"); } function caller() { var x = ({ dana : "zuul" }); callee(); return x;
--- a/js/src/jit-test/tests/jaeger/bug563000/eif-call.js +++ b/js/src/jit-test/tests/jaeger/bug563000/eif-call.js @@ -1,10 +1,9 @@ -var g = newGlobal(); -var dbg = new g.Debugger(this); +load(libdir + "evalInFrame.js"); function callee() { evalInFrame(1, "x = 'success'"); } function caller() { var x = "failure"; callee(); return x;
--- a/js/src/jit-test/tests/jaeger/bug563000/eif-getter-newvar.js +++ b/js/src/jit-test/tests/jaeger/bug563000/eif-getter-newvar.js @@ -1,10 +1,9 @@ -var g = newGlobal(); -var dbg = new g.Debugger(this); +load(libdir + "evalInFrame.js"); this.__defineGetter__("someProperty", function () { evalInFrame(1, "var x = 'success'"); }); function caller(obj) { var x = 'ignominy'; obj.someProperty; return x; } assertEq(caller(this), "success");
--- a/js/src/jit-test/tests/jaeger/bug563000/eif-getter-typechange.js +++ b/js/src/jit-test/tests/jaeger/bug563000/eif-getter-typechange.js @@ -1,10 +1,9 @@ -var g = newGlobal(); -var dbg = new g.Debugger(this); +load(libdir + "evalInFrame.js"); this.__defineGetter__("someProperty", function () { evalInFrame(1, "var x = 'success'"); }); function caller(obj) { var x = ({ dana : 'zuul' }); obj.someProperty; return x; } assertEq(caller(this), "success");
--- a/js/src/jit-test/tests/jaeger/bug563000/eif-getter.js +++ b/js/src/jit-test/tests/jaeger/bug563000/eif-getter.js @@ -1,10 +1,9 @@ -var g = newGlobal(); -var dbg = new g.Debugger(this); +load(libdir + "evalInFrame.js"); this.__defineGetter__("someProperty", function () { evalInFrame(1, "x = 'success'"); }); function caller(obj) { var x = "failure"; obj.someProperty; return x; } assertEq(caller(this), "success");
--- a/js/src/jit-test/tests/jaeger/bug563000/eif-global-newvar.js +++ b/js/src/jit-test/tests/jaeger/bug563000/eif-global-newvar.js @@ -1,8 +1,7 @@ -var g = newGlobal(); -var dbg = new g.Debugger(this); +load(libdir + "evalInFrame.js"); function callee() { evalInFrame(1, "var x = 'success'"); } callee(); assertEq(x, "success");
--- a/js/src/jit-test/tests/jaeger/invokeSessionGuard.js +++ b/js/src/jit-test/tests/jaeger/invokeSessionGuard.js @@ -1,11 +1,8 @@ -var g = newGlobal(); -var dbg = new g.Debugger(this); -// Force dbg to observe all execution. -dbg.onDebuggerStatement = function () {}; +load(libdir + "evalInFrame.js"); [1,2,3,4,5,6,7,8].forEach( function(x) { // evalInFrame means lightweight gets call obj assertEq(evalInFrame(0, "x"), x); } );
--- a/js/src/js.msg +++ b/js/src/js.msg @@ -85,17 +85,16 @@ MSG_DEF(JSMSG_INVALID_DESCRIPTOR, 0 MSG_DEF(JSMSG_OBJECT_NOT_EXTENSIBLE, 1, JSEXN_TYPEERR, "{0} is not extensible") MSG_DEF(JSMSG_CANT_REDEFINE_PROP, 1, JSEXN_TYPEERR, "can't redefine non-configurable property '{0}'") MSG_DEF(JSMSG_CANT_APPEND_TO_ARRAY, 0, JSEXN_TYPEERR, "can't add elements past the end of an array if its length property is unwritable") MSG_DEF(JSMSG_CANT_REDEFINE_ARRAY_LENGTH, 0, JSEXN_TYPEERR, "can't redefine array length") MSG_DEF(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH, 0, JSEXN_TYPEERR, "can't define array index property past the end of an array with non-writable length") MSG_DEF(JSMSG_BAD_GET_SET_FIELD, 1, JSEXN_TYPEERR, "property descriptor's {0} field is neither undefined nor a function") MSG_DEF(JSMSG_THROW_TYPE_ERROR, 0, JSEXN_TYPEERR, "'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them") MSG_DEF(JSMSG_NOT_EXPECTED_TYPE, 3, JSEXN_TYPEERR, "{0}: expected {1}, got {2}") -MSG_DEF(JSMSG_NEED_DEBUG_MODE, 0, JSEXN_ERR, "function can be called only if a Debugger is observing all execution") MSG_DEF(JSMSG_NOT_ITERABLE, 1, JSEXN_TYPEERR, "{0} is not iterable") MSG_DEF(JSMSG_ALREADY_HAS_PRAGMA, 2, JSEXN_NONE, "{0} is being assigned a {1}, but already has one") MSG_DEF(JSMSG_NEXT_RETURNED_PRIMITIVE, 0, JSEXN_TYPEERR, "iterator.next() returned a non-object value") MSG_DEF(JSMSG_WRONG_VALUE, 2, JSEXN_ERR, "expected {0} but found {1}") MSG_DEF(JSMSG_SETPROTOTYPEOF_FAIL, 1, JSEXN_TYPEERR, "[[SetPrototypeOf]] failed on {0}") MSG_DEF(JSMSG_INVALID_ARG_TYPE, 3, JSEXN_TYPEERR, "Invalid type: {0} can't be a{1} {2}") MSG_DEF(JSMSG_TERMINATED, 1, JSEXN_ERR, "Script terminated by timeout at:\n{0}")
--- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -2633,80 +2633,16 @@ EvalInContext(JSContext *cx, unsigned ar } if (!cx->compartment()->wrap(cx, args.rval())) return false; return true; } -static bool -EvalInFrame(JSContext *cx, unsigned argc, jsval *vp) -{ - CallArgs args = CallArgsFromVp(argc, vp); - if (!args.get(0).isInt32() || !args.get(1).isString()) { - JS_ReportError(cx, "Invalid arguments to evalInFrame"); - return false; - } - - uint32_t upCount = args[0].toInt32(); - RootedString str(cx, args[1].toString()); - bool saveCurrent = args.get(2).isBoolean() ? args[2].toBoolean() : false; - - if (!cx->compartment()->debugObservesAllExecution()) { - JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, - nullptr, JSMSG_NEED_DEBUG_MODE); - return false; - } - - /* Debug-mode currently disables Ion compilation. */ - ScriptFrameIter fi(cx); - for (uint32_t i = 0; i < upCount; ++i, ++fi) { - ScriptFrameIter next(fi); - ++next; - if (next.done()) - break; - } - - AutoStableStringChars stableChars(cx); - if (!stableChars.initTwoByte(cx, str)) - return JSTRAP_ERROR; - - AbstractFramePtr frame = fi.abstractFramePtr(); - RootedScript fpscript(cx, frame.script()); - - RootedObject scope(cx); - { - RootedObject scopeChain(cx, frame.scopeChain()); - AutoCompartment ac(cx, scopeChain); - scope = GetDebugScopeForFrame(cx, frame, fi.pc()); - } - Rooted<Env*> env(cx, scope); - if (!env) - return false; - - if (!ComputeThis(cx, frame)) - return false; - RootedValue thisv(cx, frame.thisValue()); - - AutoSaveFrameChain sfc(cx); - if (saveCurrent) { - if (!sfc.save()) - return false; - } - - bool ok; - { - AutoCompartment ac(cx, env); - ok = EvaluateInEnv(cx, env, thisv, frame, stableChars.twoByteRange(), fpscript->filename(), - PCToLineNumber(fpscript, fi.pc()), args.rval()); - } - return ok; -} - struct WorkerInput { JSRuntime *runtime; char16_t *chars; size_t length; WorkerInput(JSRuntime *runtime, char16_t *chars, size_t length) : runtime(runtime), chars(chars), length(length) @@ -4409,21 +4345,16 @@ static const JSFunctionSpecWithHelp shel " Get script line extent."), JS_FN_HELP("evalcx", EvalInContext, 1, 0, "evalcx(s[, o])", " Evaluate s in optional sandbox object o.\n" " if (s == '' && !o) return new o with eager standard classes\n" " if (s == 'lazy' && !o) return new o with lazy standard classes"), - JS_FN_HELP("evalInFrame", EvalInFrame, 2, 0, -"evalInFrame(n,str,save)", -" Evaluate 'str' in the nth up frame.\n" -" If 'save' (default false), save the frame chain."), - JS_FN_HELP("evalInWorker", EvalInWorker, 1, 0, "evalInWorker(str)", " Evaluate 'str' in a separate thread with its own runtime.\n"), JS_FN_HELP("shapeOf", ShapeOf, 1, 0, "shapeOf(obj)", " Get the shape of obj (an implementation detail)."),