Bug 1468384 - Add an .isModule getter to Debugger.Script. r=jorendorff draft
authorLogan F Smyth <loganfsmyth@gmail.com>
Fri, 27 Jul 2018 08:55:59 -0700
changeset 823570 926ef89a3101bbf25a467c0acd043ac36618f374
parent 814704 afdeb0288690f0acde2ba6bd008f860e1acdd026
push id117727
push userbmo:loganfsmyth@gmail.com
push dateFri, 27 Jul 2018 16:30:21 +0000
reviewersjorendorff
bugs1468384
milestone63.0a1
Bug 1468384 - Add an .isModule getter to Debugger.Script. r=jorendorff MozReview-Commit-ID: G8icLlhg1Lv
js/src/doc/Debugger/Debugger.Script.md
js/src/jit-test/tests/debug/Script-isModule-01.js
js/src/jit-test/tests/debug/Script-isModule-02.js
js/src/jit-test/tests/debug/Script-isModule-03.js
js/src/jit-test/tests/debug/Script-isModule-04.js
js/src/vm/Debugger.cpp
--- a/js/src/doc/Debugger/Debugger.Script.md
+++ b/js/src/doc/Debugger/Debugger.Script.md
@@ -88,16 +88,20 @@ from its prototype:
 `isGeneratorFunction`
 :   True if this instance refers to a `JSScript` for a function defined with a
     `function*` expression or statement. False otherwise.
 
 `isAsyncFunction`
 :   True if this instance refers to a `JSScript` for an async function, defined
     with an `async function` expression or statement. False otherwise.
 
+`isModule`
+:   True if this instance refers to a `JSScript` that was parsed and loaded
+    as an ECMAScript module. False otherwise.
+
 `displayName`
 :   **If the instance refers to a `JSScript`**, this is the script's display
     name, if it has one. If the script has no display name &mdash; for example,
     if it is a top-level `eval` script &mdash; this is `undefined`.
 
     If the script's function has a given name, its display name is the same as
     its function's given name.
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Script-isModule-01.js
@@ -0,0 +1,14 @@
+// Debugger.Object.prototype.isModule
+
+const g = newGlobal();
+const dbg = Debugger(g);
+let count = 0;
+dbg.onNewScript = function (script) {
+    count += 1;
+    assertEq(script.isModule, true);
+};
+const m = g.parseModule("");
+m.declarationInstantiation();
+m.evaluation();
+assertEq(count, 1);
+
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Script-isModule-02.js
@@ -0,0 +1,11 @@
+// Debugger.Object.prototype.isModule
+
+const g = newGlobal();
+const dbg = Debugger(g);
+let count = 0;
+dbg.onNewScript = function (script) {
+    count += 1;
+    assertEq(script.isModule, false);
+};
+const m = g.eval("");
+assertEq(count, 1);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Script-isModule-03.js
@@ -0,0 +1,18 @@
+// Debugger.Object.prototype.isModule
+
+const g = newGlobal();
+const dbg = Debugger(g);
+let count = 0;
+dbg.onNewScript = function (script) {
+    count += 1;
+    assertEq(script.isModule, true);
+
+    dbg.onNewScript = function (script) {
+        count += 1;
+        assertEq(script.isModule, false);
+    };
+};
+const m = g.parseModule("eval('')");
+m.declarationInstantiation();
+m.evaluation();
+assertEq(count, 2);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Script-isModule-04.js
@@ -0,0 +1,19 @@
+// Debugger.Object.prototype.isModule
+
+const g = newGlobal();
+const dbg = Debugger(g);
+let count = 0;
+dbg.onNewScript = function (script) {
+    count += 1;
+    assertEq(script.isModule, true);
+};
+dbg.onDebuggerStatement = function (frame) {
+    const { script } = frame;
+
+    assertEq(script.isModule, false);
+};
+const m = g.parseModule("(function(){ debugger; })()");
+m.declarationInstantiation();
+m.evaluation();
+
+assertEq(count, 1);
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -5397,16 +5397,24 @@ static bool
 DebuggerScript_getIsAsyncFunction(JSContext* cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get isAsyncFunction)", args, obj, script);
     args.rval().setBoolean(script->isAsync());
     return true;
 }
 
 static bool
+DebuggerScript_getIsModule(JSContext* cx, unsigned argc, Value* vp)
+{
+    THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get isModule)", args, obj, script);
+    args.rval().setBoolean(!!script->module());
+    return true;
+}
+
+static bool
 DebuggerScript_getDisplayName(JSContext* cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get displayName)", args, obj, script);
     Debugger* dbg = Debugger::fromChildJSObject(obj);
 
     JSFunction* func = script->functionNonDelazifying();
     JSString* name = func ? func->displayAtom() : nullptr;
     if (!name) {
@@ -6842,16 +6850,17 @@ DebuggerScript_construct(JSContext* cx, 
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NO_CONSTRUCTOR,
                               "Debugger.Script");
     return false;
 }
 
 static const JSPropertySpec DebuggerScript_properties[] = {
     JS_PSG("isGeneratorFunction", DebuggerScript_getIsGeneratorFunction, 0),
     JS_PSG("isAsyncFunction", DebuggerScript_getIsAsyncFunction, 0),
+    JS_PSG("isModule", DebuggerScript_getIsModule, 0),
     JS_PSG("displayName", DebuggerScript_getDisplayName, 0),
     JS_PSG("url", DebuggerScript_getUrl, 0),
     JS_PSG("startLine", DebuggerScript_getStartLine, 0),
     JS_PSG("lineCount", DebuggerScript_getLineCount, 0),
     JS_PSG("source", DebuggerScript_getSource, 0),
     JS_PSG("sourceStart", DebuggerScript_getSourceStart, 0),
     JS_PSG("sourceLength", DebuggerScript_getSourceLength, 0),
     JS_PSG("global", DebuggerScript_getGlobal, 0),