зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
967be3648e
Коммит
c7ee2ad411
|
@ -2433,27 +2433,12 @@ bool BytecodeEmitter::emitScript(ParseNode* body) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a Stencil and convert it into a JSScript.
|
||||||
|
SourceExtent extent = sc->getScriptExtent();
|
||||||
BCEScriptStencil stencil(*this, std::move(immutableScriptData));
|
BCEScriptStencil stencil(*this, std::move(immutableScriptData));
|
||||||
|
outputScript = stencil.intoScript(cx, compilationInfo, extent);
|
||||||
|
|
||||||
RootedObject functionOrGlobal(cx);
|
return !!outputScript;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
js::UniquePtr<ImmutableScriptData> BytecodeEmitter::createImmutableScriptData(
|
js::UniquePtr<ImmutableScriptData> BytecodeEmitter::createImmutableScriptData(
|
||||||
|
|
|
@ -414,20 +414,6 @@ JSScript* Smoosh::compileGlobalScript(CompilationInfo& compilationInfo,
|
||||||
|
|
||||||
*unimplemented = false;
|
*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;
|
Vector<ScopeNote, 0, SystemAllocPolicy> scopeNotes;
|
||||||
if (!scopeNotes.resize(smoosh.scope_notes.len)) {
|
if (!scopeNotes.resize(smoosh.scope_notes.len)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -461,19 +447,16 @@ JSScript* Smoosh::compileGlobalScript(CompilationInfo& compilationInfo,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SourceExtent extent = SourceExtent::makeGlobalExtent(length);
|
||||||
SmooshScriptStencil stencil(smoosh, compilationInfo);
|
SmooshScriptStencil stencil(smoosh, compilationInfo);
|
||||||
if (!stencil.init(cx, std::move(immutableScriptData))) {
|
if (!stencil.init(cx, std::move(immutableScriptData))) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
RootedScript script(cx, JSScript::Create(cx, cx->global(), sso, extent,
|
RootedScript script(cx, stencil.intoScript(cx, compilationInfo, extent));
|
||||||
stencil.immutableFlags));
|
|
||||||
if (!script) {
|
if (!script) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (!JSScript::fullyInitFromStencil(cx, compilationInfo, script, stencil)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(DEBUG) || defined(JS_JITSPEW)
|
#if defined(DEBUG) || defined(JS_JITSPEW)
|
||||||
Sprinter sprinter(cx);
|
Sprinter sprinter(cx);
|
||||||
|
|
|
@ -702,34 +702,39 @@ bool FunctionScriptEmitter::emitEndBody() {
|
||||||
|
|
||||||
bool FunctionScriptEmitter::initScript() {
|
bool FunctionScriptEmitter::initScript() {
|
||||||
MOZ_ASSERT(state_ == State::EndBody);
|
MOZ_ASSERT(state_ == State::EndBody);
|
||||||
|
MOZ_ASSERT(!bce_->outputScript);
|
||||||
|
|
||||||
|
JSContext* cx = bce_->cx;
|
||||||
|
|
||||||
js::UniquePtr<ImmutableScriptData> immutableScriptData =
|
js::UniquePtr<ImmutableScriptData> immutableScriptData =
|
||||||
bce_->createImmutableScriptData(bce_->cx);
|
bce_->createImmutableScriptData(cx);
|
||||||
if (!immutableScriptData) {
|
if (!immutableScriptData) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BCEScriptStencil stencil(*bce_, std::move(immutableScriptData));
|
|
||||||
|
|
||||||
RootedFunction function(bce_->cx, funbox_->function());
|
|
||||||
RootedScript script(bce_->cx);
|
|
||||||
if (bce_->emitterMode == BytecodeEmitter::LazyFunction) {
|
if (bce_->emitterMode == BytecodeEmitter::LazyFunction) {
|
||||||
script = JSScript::CastFromLazy(funbox_->function()->baseScript());
|
BCEScriptStencil stencil(*bce_, std::move(immutableScriptData));
|
||||||
|
RootedScript script(
|
||||||
|
cx, JSScript::CastFromLazy(funbox_->function()->baseScript()));
|
||||||
|
|
||||||
|
if (!JSScript::fullyInitFromStencil(cx, bce_->compilationInfo, script,
|
||||||
|
stencil)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bce_->outputScript = script;
|
||||||
} else {
|
} else {
|
||||||
script =
|
SourceExtent extent = funbox_->getScriptExtent();
|
||||||
JSScript::Create(bce_->cx, function, bce_->compilationInfo.sourceObject,
|
BCEScriptStencil stencil(*bce_, std::move(immutableScriptData));
|
||||||
funbox_->getScriptExtent(), stencil.immutableFlags);
|
|
||||||
|
RootedScript script(cx,
|
||||||
|
stencil.intoScript(cx, bce_->compilationInfo, extent));
|
||||||
if (!script) {
|
if (!script) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!JSScript::fullyInitFromStencil(bce_->cx, bce_->compilationInfo, script,
|
bce_->outputScript = script;
|
||||||
stencil)) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(!bce_->outputScript);
|
|
||||||
bce_->outputScript = script;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
state_ = State::End;
|
state_ = State::End;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "frontend/Stencil.h"
|
#include "frontend/Stencil.h"
|
||||||
|
|
||||||
|
#include "frontend/CompilationInfo.h"
|
||||||
#include "frontend/SharedContext.h"
|
#include "frontend/SharedContext.h"
|
||||||
#include "js/TracingAPI.h"
|
#include "js/TracingAPI.h"
|
||||||
#include "vm/EnvironmentObject.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);
|
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`
|
// Store all atoms into `atoms`
|
||||||
// `atoms` is the pointer to `this.natoms`-length array of `GCPtrAtom`.
|
// `atoms` is the pointer to `this.natoms`-length array of `GCPtrAtom`.
|
||||||
virtual void initAtomMap(GCPtrAtom* atoms) const = 0;
|
virtual void initAtomMap(GCPtrAtom* atoms) const = 0;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче