Bug 1439855 - Extend JS shell parse command to allow forcing full parsing;r?arai
This is useful mostly for benchmarking.
MozReview-Commit-ID: ZzWA6fxCGN
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3633,17 +3633,18 @@ class JS_FRIEND_API(ReadOnlyCompileOptio
protected:
ReadOnlyCompileOptions()
: TransitiveCompileOptions(),
lineno(1),
column(0),
scriptSourceOffset(0),
isRunOnce(false),
nonSyntacticScope(false),
- noScriptRval(false)
+ noScriptRval(false),
+ allowSyntaxParser(true)
{ }
// Set all POD options (those not requiring reference counts, copies,
// rooting, or other hand-holding) to their values in |rhs|.
void copyPODOptions(const ReadOnlyCompileOptions& rhs);
public:
// Read-only accessors for non-POD options. The proper way to set these
@@ -3670,16 +3671,17 @@ class JS_FRIEND_API(ReadOnlyCompileOptio
// starting and ending offsets within the full text. This
// scriptSourceOffset field lets the frontend convert between these
// offsets and offsets within the substring presented for compilation.
unsigned scriptSourceOffset;
// isRunOnce only applies to non-function scripts.
bool isRunOnce;
bool nonSyntacticScope;
bool noScriptRval;
+ bool allowSyntaxParser;
private:
void operator=(const ReadOnlyCompileOptions&) = delete;
};
/**
* Compilation options, with dynamic lifetime. An instance of this type
* makes a copy of / holds / roots all dynamically allocated resources
@@ -3737,16 +3739,17 @@ class JS_FRIEND_API(OwningCompileOptions
}
OwningCompileOptions& setUTF8(bool u) { utf8 = u; return *this; }
OwningCompileOptions& setColumn(unsigned c) { column = c; return *this; }
OwningCompileOptions& setScriptSourceOffset(unsigned o) { scriptSourceOffset = o; return *this; }
OwningCompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; }
OwningCompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
OwningCompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
OwningCompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
+ OwningCompileOptions& setAllowSyntaxParser(bool clp) { allowSyntaxParser = clp; return *this; }
OwningCompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
OwningCompileOptions& setNonSyntacticScope(bool n) { nonSyntacticScope = n; return *this; }
OwningCompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; }
bool setIntroductionInfo(JSContext* cx, const char* introducerFn, const char* intro,
unsigned line, JSScript* script, uint32_t offset)
{
if (!setIntroducerFilename(cx, introducerFn))
return false;
@@ -3830,16 +3833,17 @@ class MOZ_STACK_CLASS JS_FRIEND_API(Comp
}
CompileOptions& setUTF8(bool u) { utf8 = u; return *this; }
CompileOptions& setColumn(unsigned c) { column = c; return *this; }
CompileOptions& setScriptSourceOffset(unsigned o) { scriptSourceOffset = o; return *this; }
CompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; }
CompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
CompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
CompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
+ CompileOptions& setAllowSyntaxParser(bool clp) { allowSyntaxParser = clp; return *this; }
CompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
CompileOptions& setNonSyntacticScope(bool n) { nonSyntacticScope = n; return *this; }
CompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; }
CompileOptions& setIntroductionInfo(const char* introducerFn, const char* intro,
unsigned line, JSScript* script, uint32_t offset)
{
introducerFilename_ = introducerFn;
introductionType = intro;
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -4404,30 +4404,54 @@ Parse(JSContext* cx, unsigned argc, Valu
return false;
}
if (!args[0].isString()) {
const char* typeName = InformalValueTypeName(args[0]);
JS_ReportErrorASCII(cx, "expected string to parse, got %s", typeName);
return false;
}
+ bool allowSyntaxParser = true;
+
+ if (args.length() >= 2) {
+ if (!args[1].isObject()) {
+ const char* typeName = InformalValueTypeName(args[1]);
+ JS_ReportErrorASCII(cx, "expected object (options) to parse, got %s", typeName);
+ return false;
+ }
+ RootedObject objOptions(cx, &args[1].toObject());
+
+ RootedValue optionAllowSyntaxParser(cx);
+ if (!JS_GetProperty(cx, objOptions, "allowSyntaxParser", &optionAllowSyntaxParser))
+ return false;
+
+ if (optionAllowSyntaxParser.isBoolean()) {
+ allowSyntaxParser = optionAllowSyntaxParser.toBoolean();
+ } else if (!optionAllowSyntaxParser.isUndefined()) {
+ const char* typeName = InformalValueTypeName(optionAllowSyntaxParser);
+ JS_ReportErrorASCII(cx, "option `allowSyntaxParser` should be a boolean, got %s", typeName);
+ return false;
+ }
+ }
+
JSFlatString* scriptContents = args[0].toString()->ensureFlat(cx);
if (!scriptContents)
return false;
AutoStableStringChars stableChars(cx);
if (!stableChars.initTwoByte(cx, scriptContents))
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);
+ .setFileAndLine("<string>", 1)
+ .setAllowSyntaxParser(allowSyntaxParser);
UsedNameTracker usedNames(cx);
if (!usedNames.init())
return false;
Parser<FullParseHandler, char16_t> parser(cx, cx->tempLifoAlloc(), options, chars, length,
/* foldConstants = */ false, usedNames, nullptr,
nullptr);
if (!parser.checkOptions())