diff --git a/js/src/vm/JSScript.cpp b/js/src/vm/JSScript.cpp index ab41bef83f63..82fef62abd15 100644 --- a/js/src/vm/JSScript.cpp +++ b/js/src/vm/JSScript.cpp @@ -3588,8 +3588,6 @@ bool JSScript::fullyInitFromEmitter(JSContext* cx, HandleScript script, return false; } - uint32_t natoms = bce->atomIndices->count(); - // Initialize POD fields script->lineno_ = bce->firstLine; script->mainOffset_ = bce->mainOffset(); @@ -3619,19 +3617,10 @@ bool JSScript::fullyInitFromEmitter(JSContext* cx, HandleScript script, return false; } - // The + 1 is to account for the final SN_MAKE_TERMINATOR that is appended - // when the notes are copied to their final destination by copySrcNotes. - uint32_t nsrcnotes = bce->notes().length() + 1; - uint32_t codeLength = bce->code().length(); - if (!script->createSharedScriptData(cx, codeLength, nsrcnotes, natoms)) { + // Create and initialize SharedScriptData + if (!SharedScriptData::InitFromEmitter(cx, script, bce)) { return false; } - - jsbytecode* code = script->code(); - PodCopy(code, bce->code().begin(), codeLength); - bce->copySrcNotes((jssrcnote*)(code + script->length()), nsrcnotes); - InitAtomMap(*bce->atomIndices, script->atoms()); - if (!script->shareScriptData(cx)) { return false; } @@ -4554,6 +4543,30 @@ bool JSScript::hasBreakpointsAt(jsbytecode* pc) { return site->enabledCount > 0; } +/* static */ bool SharedScriptData::InitFromEmitter( + JSContext* cx, js::HandleScript script, frontend::BytecodeEmitter* bce) { + uint32_t natoms = bce->atomIndices->count(); + uint32_t codeLength = bce->code().length(); + + // The + 1 is to account for the final SN_MAKE_TERMINATOR that is appended + // when the notes are copied to their final destination by copySrcNotes. + uint32_t noteLength = bce->notes().length() + 1; + + // Create and initialize SharedScriptData + if (!script->createSharedScriptData(cx, codeLength, noteLength, natoms)) { + return false; + } + + js::SharedScriptData* data = script->scriptData_; + + // Initialize trailing arrays + std::copy_n(bce->code().begin(), codeLength, data->code()); + bce->copySrcNotes(data->notes(), noteLength); + InitAtomMap(*bce->atomIndices, data->atoms()); + + return true; +} + void SharedScriptData::traceChildren(JSTracer* trc) { MOZ_ASSERT(refCount() != 0); for (uint32_t i = 0; i < natoms(); ++i) { diff --git a/js/src/vm/JSScript.h b/js/src/vm/JSScript.h index f7c0efdce7ca..802a106d5d01 100644 --- a/js/src/vm/JSScript.h +++ b/js/src/vm/JSScript.h @@ -1523,6 +1523,9 @@ class SharedScriptData { static MOZ_MUST_USE XDRResult XDR(js::XDRState* xdr, js::HandleScript script); + static bool InitFromEmitter(JSContext* cx, js::HandleScript script, + js::frontend::BytecodeEmitter* bce); + // Mark this SharedScriptData for use in a new zone void markForCrossZone(JSContext* cx); @@ -1857,6 +1860,10 @@ class JSScript : public js::gc::TenuredCell { friend js::XDRResult js::SharedScriptData::XDR(js::XDRState* xdr, js::HandleScript script); + friend bool js::SharedScriptData::InitFromEmitter( + JSContext* cx, js::HandleScript script, + js::frontend::BytecodeEmitter* bce); + template friend js::XDRResult js::PrivateScriptData::XDR( js::XDRState* xdr, js::HandleScript script,