Bug 1377007 - JS shell bindings for binjs-ref;r?jorendorff,arai draft
authorDavid Teller <dteller@mozilla.com>
Mon, 18 Sep 2017 16:41:00 +0200
changeset 712442 73a3b6751eafc6f72d7024c6f65ed5bf2f0eb225
parent 712441 02f2f44b5bafdb1c37f180c8028c871ebca3c7e1
child 712443 0e47c1a7a52d71ed92144ce176d16902ae4df601
push id93334
push userdteller@mozilla.com
push dateSat, 16 Dec 2017 14:44:32 +0000
reviewersjorendorff, arai
bugs1377007
milestone59.0a1
Bug 1377007 - JS shell bindings for binjs-ref;r?jorendorff,arai MozReview-Commit-ID: 4kKbxpqXVSU
js/src/shell/js.cpp
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -69,16 +69,21 @@
 # include "prerror.h"
 # include "prlink.h"
 #endif
 #include "shellmoduleloader.out.h"
 
 #include "builtin/ModuleObject.h"
 #include "builtin/RegExp.h"
 #include "builtin/TestingFunctions.h"
+
+#if defined(JS_BUILD_BINAST)
+#include "frontend/BinSource.h"
+#endif // defined(JS_BUILD_BINAST)
+
 #include "frontend/Parser.h"
 #include "gc/GCInternals.h"
 #include "jit/arm/Simulator-arm.h"
 #include "jit/InlinableNatives.h"
 #include "jit/Ion.h"
 #include "jit/JitcodeMap.h"
 #include "jit/OptimizationTracking.h"
 #include "js/Debug.h"
@@ -4387,16 +4392,74 @@ GetModuleLoadPath(JSContext* cx, unsigne
 
         args.rval().setString(str);
     } else {
         args.rval().setNull();
     }
     return true;
 }
 
+#if defined(JS_BUILD_BINAST)
+
+static bool
+BinParse(JSContext* cx, unsigned argc, Value* vp)
+{
+    using namespace js::frontend;
+
+    CallArgs args = CallArgsFromVp(argc, vp);
+
+    if (args.length() < 1) {
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
+                                  "parse", "0", "s");
+        return false;
+    }
+    if (!args[0].isObject()) {
+        const char* typeName = InformalValueTypeName(args[0]);
+        JS_ReportErrorASCII(cx, "expected object (typed array) to parse, got %s", typeName);
+        return false;
+    }
+
+    RootedObject obj(cx, &args[0].toObject());
+    if (!JS_IsTypedArrayObject(obj)) {
+        const char* typeName = InformalValueTypeName(args[0]);
+        JS_ReportErrorASCII(cx, "expected typed array to parse, got %s", typeName);
+        return false;
+    }
+
+    uint32_t buf_length = 0;
+    bool buf_isSharedMemory = false;
+    uint8_t* buf_data = nullptr;
+    GetArrayBufferViewLengthAndData(obj, &buf_length, &buf_isSharedMemory, &buf_data);
+    MOZ_ASSERT(buf_data);
+
+    CompileOptions options(cx);
+    options.setIntroductionType("js shell bin parse")
+           .setFileAndLine("<ArrayBuffer>", 1);
+
+    UsedNameTracker usedNames(cx);
+    if (!usedNames.init())
+        return false;
+
+    BinASTParser reader(cx, cx->tempLifoAlloc(), usedNames, options);
+
+    JS::Result<ParseNode*> parsed = reader.parse(buf_data, buf_length);
+    if (parsed.isErr())
+        return false;
+
+#ifdef DEBUG
+    Fprinter out(stderr);
+    DumpParseTree(parsed.unwrap(), out);
+#endif
+
+    args.rval().setUndefined();
+    return true;
+}
+
+#endif // defined(JS_BUILD_BINAST)
+
 static bool
 Parse(JSContext* cx, unsigned argc, Value* vp)
 {
     using namespace js::frontend;
 
     CallArgs args = CallArgsFromVp(argc, vp);
 
     if (args.length() < 1) {
@@ -4419,32 +4482,32 @@ Parse(JSContext* cx, unsigned argc, Valu
         return false;
 
     size_t length = scriptContents->length();
     const char16_t* chars = stableChars.twoByteRange().begin().get();
 
     CompileOptions options(cx);
     options.setIntroductionType("js shell parse")
            .setFileAndLine("<string>", 1);
+
     UsedNameTracker usedNames(cx);
     if (!usedNames.init())
         return false;
     Parser<FullParseHandler, char16_t> parser(cx, cx->tempLifoAlloc(), options, chars, length,
-                                              /* foldConstants = */ true, usedNames, nullptr,
+                                              /* foldConstants = */ false, usedNames, nullptr,
                                               nullptr);
     if (!parser.checkOptions())
         return false;
 
-    ParseNode* pn = parser.parse();
+    ParseNode* pn = parser.parse(); // Deallocated once `parser` goes out of scope.
     if (!pn)
         return false;
 #ifdef DEBUG
     js::Fprinter out(stderr);
     DumpParseTree(pn, out);
-    out.putChar('\n');
 #endif
     args.rval().setUndefined();
     return true;
 }
 
 static bool
 SyntaxParse(JSContext* cx, unsigned argc, Value* vp)
 {
@@ -6741,16 +6804,24 @@ static const JSFunctionSpecWithHelp shel
 "  This hook is used to look up a previously loaded module object.  It should\n"
 "  be implemented by the module loader."),
 
     JS_FN_HELP("getModuleLoadPath", GetModuleLoadPath, 0, 0,
 "getModuleLoadPath()",
 "  Return any --module-load-path argument passed to the shell.  Used by the\n"
 "  module loader.\n"),
 
+#if defined(JS_BUILD_BINAST)
+
+JS_FN_HELP("parseBin", BinParse, 1, 0,
+"parseBin(arraybuffer)",
+"  Parses a Binary AST, potentially throwing."),
+
+#endif // defined(JS_BUILD_BINAST)
+
     JS_FN_HELP("parse", Parse, 1, 0,
 "parse(code)",
 "  Parses a string, potentially throwing."),
 
     JS_FN_HELP("syntaxParse", SyntaxParse, 1, 0,
 "syntaxParse(code)",
 "  Check the syntax of a string, returning success value"),