Bug 1636796 - Add ScriptStencil::intoScript. r=mgaudet

This performs JSScript allocation by consuming the Stencil. For now we leave
handling of delazification compiles alone.

Differential Revision: https://phabricator.services.mozilla.com/D74572
This commit is contained in:
Ted Campbell 2020-05-11 14:41:52 +00:00
Родитель 967be3648e
Коммит c7ee2ad411
5 изменённых файлов: 58 добавлений и 53 удалений

Просмотреть файл

@ -2433,27 +2433,12 @@ bool BytecodeEmitter::emitScript(ParseNode* body) {
return false;
}
// Create a Stencil and convert it into a JSScript.
SourceExtent extent = sc->getScriptExtent();
BCEScriptStencil stencil(*this, std::move(immutableScriptData));
outputScript = stencil.intoScript(cx, compilationInfo, extent);
RootedObject functionOrGlobal(cx);
if (sc->isFunctionBox()) {
functionOrGlobal = sc->asFunctionBox()->function();
} else {
functionOrGlobal = cx->global();
}
RootedScript script(
cx, JSScript::Create(cx, functionOrGlobal, compilationInfo.sourceObject,
sc->getScriptExtent(), stencil.immutableFlags));
if (!script) {
return false;
}
if (!JSScript::fullyInitFromStencil(cx, compilationInfo, script, stencil)) {
return false;
}
// Script is allocated now.
outputScript = script;
return true;
return !!outputScript;
}
js::UniquePtr<ImmutableScriptData> BytecodeEmitter::createImmutableScriptData(

Просмотреть файл

@ -414,20 +414,6 @@ JSScript* Smoosh::compileGlobalScript(CompilationInfo& compilationInfo,
*unimplemented = false;
RootedScriptSourceObject sso(cx,
frontend::CreateScriptSourceObject(cx, options));
if (!sso) {
return nullptr;
}
RootedObject proto(cx);
if (!GetFunctionPrototype(cx, GeneratorKind::NotGenerator,
FunctionAsyncKind::SyncFunction, &proto)) {
return nullptr;
}
SourceExtent extent = SourceExtent::makeGlobalExtent(length);
Vector<ScopeNote, 0, SystemAllocPolicy> scopeNotes;
if (!scopeNotes.resize(smoosh.scope_notes.len)) {
return nullptr;
@ -461,19 +447,16 @@ JSScript* Smoosh::compileGlobalScript(CompilationInfo& compilationInfo,
return nullptr;
}
SourceExtent extent = SourceExtent::makeGlobalExtent(length);
SmooshScriptStencil stencil(smoosh, compilationInfo);
if (!stencil.init(cx, std::move(immutableScriptData))) {
return nullptr;
}
RootedScript script(cx, JSScript::Create(cx, cx->global(), sso, extent,
stencil.immutableFlags));
RootedScript script(cx, stencil.intoScript(cx, compilationInfo, extent));
if (!script) {
return nullptr;
}
if (!JSScript::fullyInitFromStencil(cx, compilationInfo, script, stencil)) {
return nullptr;
}
#if defined(DEBUG) || defined(JS_JITSPEW)
Sprinter sprinter(cx);

Просмотреть файл

@ -702,34 +702,39 @@ bool FunctionScriptEmitter::emitEndBody() {
bool FunctionScriptEmitter::initScript() {
MOZ_ASSERT(state_ == State::EndBody);
MOZ_ASSERT(!bce_->outputScript);
JSContext* cx = bce_->cx;
js::UniquePtr<ImmutableScriptData> immutableScriptData =
bce_->createImmutableScriptData(bce_->cx);
bce_->createImmutableScriptData(cx);
if (!immutableScriptData) {
return false;
}
BCEScriptStencil stencil(*bce_, std::move(immutableScriptData));
RootedFunction function(bce_->cx, funbox_->function());
RootedScript script(bce_->cx);
if (bce_->emitterMode == BytecodeEmitter::LazyFunction) {
script = JSScript::CastFromLazy(funbox_->function()->baseScript());
} else {
script =
JSScript::Create(bce_->cx, function, bce_->compilationInfo.sourceObject,
funbox_->getScriptExtent(), stencil.immutableFlags);
if (!script) {
return false;
}
}
BCEScriptStencil stencil(*bce_, std::move(immutableScriptData));
RootedScript script(
cx, JSScript::CastFromLazy(funbox_->function()->baseScript()));
if (!JSScript::fullyInitFromStencil(bce_->cx, bce_->compilationInfo, script,
if (!JSScript::fullyInitFromStencil(cx, bce_->compilationInfo, script,
stencil)) {
return false;
}
MOZ_ASSERT(!bce_->outputScript);
bce_->outputScript = script;
} else {
SourceExtent extent = funbox_->getScriptExtent();
BCEScriptStencil stencil(*bce_, std::move(immutableScriptData));
RootedScript script(cx,
stencil.intoScript(cx, bce_->compilationInfo, extent));
if (!script) {
return false;
}
bce_->outputScript = script;
}
#ifdef DEBUG
state_ = State::End;

Просмотреть файл

@ -6,6 +6,7 @@
#include "frontend/Stencil.h"
#include "frontend/CompilationInfo.h"
#include "frontend/SharedContext.h"
#include "js/TracingAPI.h"
#include "vm/EnvironmentObject.h"
@ -214,3 +215,29 @@ void ScriptStencilBase::trace(JSTracer* trc) {
}
}
}
JSScript* ScriptStencil::intoScript(JSContext* cx,
CompilationInfo& compilationInfo,
SourceExtent extent) {
MOZ_ASSERT(immutableScriptData,
"Need generated bytecode to use ScriptStencil::intoScript");
RootedObject functionOrGlobal(cx, cx->global());
if (functionIndex) {
functionOrGlobal =
compilationInfo.funcData[*functionIndex].as<JSFunction*>();
}
RootedScript script(
cx, JSScript::Create(cx, functionOrGlobal, compilationInfo.sourceObject,
extent, immutableFlags));
if (!script) {
return nullptr;
}
if (!JSScript::fullyInitFromStencil(cx, compilationInfo, script, *this)) {
return nullptr;
}
return script;
}

Просмотреть файл

@ -376,6 +376,11 @@ class ScriptStencil : public ScriptStencilBase {
return immutableFlags.hasFlag(ImmutableFlags::IsFunction);
}
// Allocate a JSScript and initialize it with bytecode. This consumes
// allocations within this stencil.
JSScript* intoScript(JSContext* cx, CompilationInfo& compilationInfo,
SourceExtent extent);
// Store all atoms into `atoms`
// `atoms` is the pointer to `this.natoms`-length array of `GCPtrAtom`.
virtual void initAtomMap(GCPtrAtom* atoms) const = 0;