зеркало из https://github.com/mozilla/gecko-dev.git
Bug 944121: Abstract JS shell's compilation options parsing out into its own function. r=bhackett
This commit is contained in:
Родитель
bcdbbde4dc
Коммит
f044b1e28b
|
@ -4339,7 +4339,7 @@ JS::OwningCompileOptions::copy(JSContext *cx, const ReadOnlyCompileOptions &rhs)
|
|||
}
|
||||
|
||||
bool
|
||||
JS::OwningCompileOptions::setFileAndLine(JSContext *cx, const char *f, unsigned l)
|
||||
JS::OwningCompileOptions::setFile(JSContext *cx, const char *f)
|
||||
{
|
||||
char *copy = nullptr;
|
||||
if (f) {
|
||||
|
@ -4352,6 +4352,15 @@ JS::OwningCompileOptions::setFileAndLine(JSContext *cx, const char *f, unsigned
|
|||
js_free(const_cast<char *>(filename_));
|
||||
|
||||
filename_ = copy;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
JS::OwningCompileOptions::setFileAndLine(JSContext *cx, const char *f, unsigned l)
|
||||
{
|
||||
if (!setFile(cx, f))
|
||||
return false;
|
||||
|
||||
lineno = l;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -3549,10 +3549,12 @@ class JS_FRIEND_API(OwningCompileOptions) : public ReadOnlyCompileOptions
|
|||
bool copy(JSContext *cx, const ReadOnlyCompileOptions &rhs);
|
||||
|
||||
/* These setters make copies of their string arguments, and are fallible. */
|
||||
bool setFile(JSContext *cx, const char *f);
|
||||
bool setFileAndLine(JSContext *cx, const char *f, unsigned l);
|
||||
bool setSourceMapURL(JSContext *cx, const jschar *s);
|
||||
|
||||
/* These setters are infallible, and can be chained. */
|
||||
OwningCompileOptions &setLine(unsigned l) { lineno = l; return *this; }
|
||||
OwningCompileOptions &setElement(JSObject *e) { elementRoot = e; return *this; }
|
||||
OwningCompileOptions &setElementProperty(JSString *p) { elementPropertyRoot = p; return *this; }
|
||||
OwningCompileOptions &setPrincipals(JSPrincipals *p) {
|
||||
|
@ -3614,6 +3616,8 @@ class MOZ_STACK_CLASS JS_FRIEND_API(CompileOptions) : public ReadOnlyCompileOpti
|
|||
JSObject *element() const MOZ_OVERRIDE { return elementRoot; }
|
||||
JSString *elementProperty() const MOZ_OVERRIDE { return elementPropertyRoot; }
|
||||
|
||||
CompileOptions &setFile(const char *f) { filename_ = f; return *this; }
|
||||
CompileOptions &setLine(unsigned l) { lineno = l; return *this; }
|
||||
CompileOptions &setFileAndLine(const char *f, unsigned l) {
|
||||
filename_ = f; lineno = l; return *this;
|
||||
}
|
||||
|
|
|
@ -765,6 +765,87 @@ LoadScriptRelativeToScript(JSContext *cx, unsigned argc, jsval *vp)
|
|||
return LoadScript(cx, argc, vp, true);
|
||||
}
|
||||
|
||||
// Populate |options| with the options given by |opts|'s properties. If we
|
||||
// need to convert a filename to a C string, let fileNameBytes own the
|
||||
// bytes.
|
||||
static bool
|
||||
ParseCompileOptions(JSContext *cx, CompileOptions &options, HandleObject opts,
|
||||
JSAutoByteString &fileNameBytes)
|
||||
{
|
||||
RootedValue v(cx);
|
||||
RootedString s(cx);
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "compileAndGo", &v))
|
||||
return false;
|
||||
if (!v.isUndefined())
|
||||
options.setCompileAndGo(ToBoolean(v));
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "noScriptRval", &v))
|
||||
return false;
|
||||
if (!v.isUndefined())
|
||||
options.setNoScriptRval(ToBoolean(v));
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "fileName", &v))
|
||||
return false;
|
||||
if (v.isNull()) {
|
||||
options.setFile(nullptr);
|
||||
} else if (!v.isUndefined()) {
|
||||
s = ToString(cx, v);
|
||||
if (!s)
|
||||
return false;
|
||||
char *fileName = fileNameBytes.encodeLatin1(cx, s);
|
||||
if (!fileName)
|
||||
return false;
|
||||
options.setFile(fileName);
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "element", &v))
|
||||
return false;
|
||||
if (v.isObject())
|
||||
options.setElement(&v.toObject());
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "elementProperty", &v))
|
||||
return false;
|
||||
if (!v.isUndefined()) {
|
||||
s = ToString(cx, v);
|
||||
if (!s)
|
||||
return false;
|
||||
options.setElementProperty(s);
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "lineNumber", &v))
|
||||
return false;
|
||||
if (!v.isUndefined()) {
|
||||
uint32_t u;
|
||||
if (!ToUint32(cx, v, &u))
|
||||
return false;
|
||||
options.setLine(u);
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "sourcePolicy", &v))
|
||||
return false;
|
||||
if (!v.isUndefined()) {
|
||||
JSString *s = ToString(cx, v);
|
||||
if (!s)
|
||||
return false;
|
||||
char *policy = JS_EncodeStringToUTF8(cx, s);
|
||||
if (!policy)
|
||||
return false;
|
||||
if (strcmp(policy, "NO_SOURCE") == 0) {
|
||||
options.setSourcePolicy(CompileOptions::NO_SOURCE);
|
||||
} else if (strcmp(policy, "LAZY_SOURCE") == 0) {
|
||||
options.setSourcePolicy(CompileOptions::LAZY_SOURCE);
|
||||
} else if (strcmp(policy, "SAVE_SOURCE") == 0) {
|
||||
options.setSourcePolicy(CompileOptions::SAVE_SOURCE);
|
||||
} else {
|
||||
JS_ReportError(cx, "bad 'sourcePolicy' option: '%s'", policy);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class AutoNewContext
|
||||
{
|
||||
private:
|
||||
|
@ -849,21 +930,17 @@ Evaluate(JSContext *cx, unsigned argc, jsval *vp)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool newContext = false;
|
||||
bool compileAndGo = true;
|
||||
bool noScriptRval = false;
|
||||
const char *fileName = "@evaluate";
|
||||
RootedObject element(cx);
|
||||
RootedString elementProperty(cx);
|
||||
CompileOptions options(cx);
|
||||
JSAutoByteString fileNameBytes;
|
||||
bool newContext = false;
|
||||
RootedString displayURL(cx);
|
||||
RootedString sourceMapURL(cx);
|
||||
unsigned lineNumber = 1;
|
||||
RootedObject global(cx, nullptr);
|
||||
bool catchTermination = false;
|
||||
bool saveFrameChain = false;
|
||||
RootedObject callerGlobal(cx, cx->global());
|
||||
CompileOptions::SourcePolicy sourcePolicy = CompileOptions::SAVE_SOURCE;
|
||||
|
||||
options.setFileAndLine("@evaluate", 1);
|
||||
|
||||
global = JS_GetGlobalForObject(cx, &args.callee());
|
||||
if (!global)
|
||||
|
@ -873,47 +950,14 @@ Evaluate(JSContext *cx, unsigned argc, jsval *vp)
|
|||
RootedObject opts(cx, &args[1].toObject());
|
||||
RootedValue v(cx);
|
||||
|
||||
if (!ParseCompileOptions(cx, options, opts, fileNameBytes))
|
||||
return false;
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "newContext", &v))
|
||||
return false;
|
||||
if (!v.isUndefined())
|
||||
newContext = ToBoolean(v);
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "compileAndGo", &v))
|
||||
return false;
|
||||
if (!v.isUndefined())
|
||||
compileAndGo = ToBoolean(v);
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "noScriptRval", &v))
|
||||
return false;
|
||||
if (!v.isUndefined())
|
||||
noScriptRval = ToBoolean(v);
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "fileName", &v))
|
||||
return false;
|
||||
if (v.isNull()) {
|
||||
fileName = nullptr;
|
||||
} else if (!v.isUndefined()) {
|
||||
JSString *s = ToString(cx, v);
|
||||
if (!s)
|
||||
return false;
|
||||
fileName = fileNameBytes.encodeLatin1(cx, s);
|
||||
if (!fileName)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "element", &v))
|
||||
return false;
|
||||
if (v.isObject())
|
||||
element = &v.toObject();
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "elementProperty", &v))
|
||||
return false;
|
||||
if (!v.isUndefined()) {
|
||||
elementProperty = ToString(cx, v);
|
||||
if (!elementProperty)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "displayURL", &v))
|
||||
return false;
|
||||
if (!v.isUndefined()) {
|
||||
|
@ -930,15 +974,6 @@ Evaluate(JSContext *cx, unsigned argc, jsval *vp)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "lineNumber", &v))
|
||||
return false;
|
||||
if (!v.isUndefined()) {
|
||||
uint32_t u;
|
||||
if (!ToUint32(cx, v, &u))
|
||||
return false;
|
||||
lineNumber = u;
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "global", &v))
|
||||
return false;
|
||||
if (!v.isUndefined()) {
|
||||
|
@ -963,28 +998,6 @@ Evaluate(JSContext *cx, unsigned argc, jsval *vp)
|
|||
return false;
|
||||
if (!v.isUndefined())
|
||||
saveFrameChain = ToBoolean(v);
|
||||
|
||||
if (!JS_GetProperty(cx, opts, "sourcePolicy", &v))
|
||||
return false;
|
||||
if (!v.isUndefined()) {
|
||||
JSString *s = ToString(cx, v);
|
||||
if (!s)
|
||||
return false;
|
||||
char *policy = JS_EncodeStringToUTF8(cx, s);
|
||||
if (!policy)
|
||||
return false;
|
||||
if (strcmp(policy, "NO_SOURCE") == 0) {
|
||||
sourcePolicy = CompileOptions::NO_SOURCE;
|
||||
} else if (strcmp(policy, "LAZY_SOURCE") == 0) {
|
||||
sourcePolicy = CompileOptions::LAZY_SOURCE;
|
||||
} else if (strcmp(policy, "SAVE_SOURCE") == 0) {
|
||||
sourcePolicy = CompileOptions::SAVE_SOURCE;
|
||||
} else {
|
||||
JS_ReportError(cx, "bad 'sourcePolicy' option passed to 'evaluate': '%s'",
|
||||
policy);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RootedString code(cx, args[0].toString());
|
||||
|
@ -1009,19 +1022,13 @@ Evaluate(JSContext *cx, unsigned argc, jsval *vp)
|
|||
JSAutoCompartment ac(cx, global);
|
||||
RootedScript script(cx);
|
||||
|
||||
{
|
||||
JS::AutoSaveContextOptions asco(cx);
|
||||
JS::ContextOptionsRef(cx).setNoScriptRval(noScriptRval);
|
||||
|
||||
CompileOptions options(cx);
|
||||
options.setFileAndLine(fileName, lineNumber)
|
||||
.setElement(element)
|
||||
.setElementProperty(elementProperty)
|
||||
.setSourcePolicy(sourcePolicy)
|
||||
.setCompileAndGo(compileAndGo);
|
||||
if (!options.wrap(cx, cx->compartment()))
|
||||
return false;
|
||||
|
||||
{
|
||||
JS::AutoSaveContextOptions asco(cx);
|
||||
JS::ContextOptionsRef(cx).setNoScriptRval(options.noScriptRval);
|
||||
|
||||
script = JS::Compile(cx, global, options, codeChars, codeLength);
|
||||
if (!script)
|
||||
return false;
|
||||
|
|
Загрузка…
Ссылка в новой задаче