diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 452451db5fe9..4b22922e73fc 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -611,6 +611,14 @@ js::XDRScript(XDRState* xdr, HandleObject enclosingScope, HandleScript enc if (mode == XDR_ENCODE) { script = scriptp.get(); MOZ_ASSERT_IF(enclosingScript, enclosingScript->compartment() == script->compartment()); + MOZ_ASSERT(script->functionNonDelazifying() == fun); + + if (!fun && script->treatAsRunOnce() && script->hasRunOnce()) { + JS_ReportError(cx, + "Can't serialize a run-once non-function script " + "that has already run"); + return false; + } nargs = script->bindings.numArgs(); nblocklocals = script->bindings.numBlockScoped(); @@ -2962,6 +2970,12 @@ js::CloneScript(JSContext* cx, HandleObject enclosingScope, HandleFunction fun, PollutedGlobalScopeOption polluted /* = HasCleanGlobalScope */, NewObjectKind newKind /* = GenericObject */) { + if (src->treatAsRunOnce() && !src->functionNonDelazifying()) { + // Toplevel run-once scripts may not be cloned. + JS_ReportError(cx, "No cloning toplevel run-once scripts"); + return nullptr; + } + /* NB: Keep this in sync with XDRScript. */ /* Some embeddings are not careful to use ExposeObjectToActiveJS as needed. */ diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 75267f6b8058..2c28d9b41d97 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -955,7 +955,9 @@ class JSScript : public js::gc::TenuredCell // Script has singleton objects. bool hasSingletons_:1; - // Script is a lambda to treat as running once. + // Script is a lambda to treat as running once or a global or eval script + // that will only run once. Which one it is can be disambiguated by + // checking whether function_ is null. bool treatAsRunOnce_:1; // If treatAsRunOnce, whether script has executed.