Commit 24c83d49 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[modules] Setup module exports in Runtime_DeclareModuleExports

This changes how we setup modules from being entirely bytecode based to a
single fixed array with metadata that's passed into a runtime function
DeclareModuleExports, similar to DeclareGlobals. This is preperatory work to
replace the bytecode that calls those functions with explicit calls before we
even start running the code. In the case of modules that will obviate the need
for modules to be generators.

Change-Id: Ibf1c913a9dc78041e3001b174c66ab89226d9c8e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2030733
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66097}
parent e395d169
......@@ -229,12 +229,7 @@ MaybeHandle<Context> NewScriptContext(Isolate* isolate,
Handle<Context> result =
isolate->factory()->NewScriptContext(native_context, scope_info);
int header = scope_info->ContextHeaderLength();
for (int var = 0; var < scope_info->ContextLocalCount(); var++) {
if (scope_info->ContextLocalInitFlag(var) == kNeedsInitialization) {
result->set(header + var, ReadOnlyRoots(isolate).the_hole_value());
}
}
result->Initialize(isolate);
Handle<ScriptContextTable> new_script_context_table =
ScriptContextTable::Extend(script_context, result);
......
This diff is collapsed.
......@@ -24,7 +24,7 @@ enum class SourceRangeKind;
namespace interpreter {
class GlobalDeclarationsBuilder;
class TopLevelDeclarationsBuilder;
class LoopBuilder;
class BlockCoverageBuilder;
class BytecodeJumpTable;
......@@ -50,6 +50,7 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
#undef DECLARE_VISIT
// Visiting function for declarations list and statements are overridden.
void VisitModuleDeclarations(Declaration::List* declarations);
void VisitGlobalDeclarations(Declaration::List* declarations);
void VisitDeclarations(Declaration::List* declarations);
void VisitStatements(const ZonePtrList<Statement>* statments);
......@@ -66,7 +67,7 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
class ExpressionResultScope;
class EffectResultScope;
class FeedbackSlotCache;
class GlobalDeclarationsBuilder;
class TopLevelDeclarationsBuilder;
class IteratorRecord;
class NaryCodeCoverageSlots;
class RegisterAllocationScope;
......@@ -221,6 +222,8 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void BuildThisVariableLoad();
void BuildDeclareCall(Runtime::FunctionId id);
Expression* GetDestructuringDefaultValue(Expression** target);
void BuildDestructuringArrayAssignment(
ArrayLiteral* pattern, Token::Value op,
......@@ -462,9 +465,9 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
return builder()->register_allocator();
}
GlobalDeclarationsBuilder* globals_builder() {
DCHECK_NOT_NULL(globals_builder_);
return globals_builder_;
TopLevelDeclarationsBuilder* top_level_builder() {
DCHECK_NOT_NULL(top_level_builder_);
return top_level_builder_;
}
inline LanguageMode language_mode() const;
inline FunctionKind function_kind() const;
......@@ -494,7 +497,7 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
FeedbackSlotCache* feedback_slot_cache_;
GlobalDeclarationsBuilder* globals_builder_;
TopLevelDeclarationsBuilder* top_level_builder_;
BlockCoverageBuilder* block_coverage_builder_;
ZoneVector<std::pair<FunctionLiteral*, size_t>> function_literals_;
ZoneVector<std::pair<NativeFunctionLiteral*, size_t>>
......
......@@ -36,6 +36,16 @@ Handle<ScriptContextTable> ScriptContextTable::Extend(
return result;
}
void Context::Initialize(Isolate* isolate) {
ScopeInfo scope_info = this->scope_info();
int header = scope_info.ContextHeaderLength();
for (int var = 0; var < scope_info.ContextLocalCount(); var++) {
if (scope_info.ContextLocalInitFlag(var) == kNeedsInitialization) {
set(header + var, ReadOnlyRoots(isolate).the_hole_value());
}
}
}
bool ScriptContextTable::Lookup(Isolate* isolate, ScriptContextTable table,
String name, LookupResult* result) {
DisallowHeapAllocation no_gc;
......
......@@ -507,6 +507,10 @@ class Context : public HeapObject {
return SizeFor(index) - kHeapObjectTag;
}
// Initializes the variable slots of the context. Lexical variables that need
// initialization are filled with the hole.
void Initialize(Isolate* isolate);
// TODO(ishell): eventually migrate to the offset based access instead of
// index-based.
// The default context slot layout; indices are FixedArray slot indices.
......
......@@ -369,9 +369,14 @@ bool SourceTextModule::RunInitializationCode(Isolate* isolate,
Handle<JSFunction> function(JSFunction::cast(module->code()), isolate);
DCHECK_EQ(MODULE_SCOPE, function->shared().scope_info().scope_type());
Handle<Object> receiver = isolate->factory()->undefined_value();
Handle<Object> argv[] = {module};
Handle<ScopeInfo> scope_info(function->shared().scope_info(), isolate);
Handle<Context> context = isolate->factory()->NewModuleContext(
module, isolate->native_context(), scope_info);
function->set_context(*context);
MaybeHandle<Object> maybe_generator =
Execution::Call(isolate, function, receiver, arraysize(argv), argv);
Execution::Call(isolate, function, receiver, 0, {});
Handle<Object> generator;
if (!maybe_generator.ToHandle(&generator)) {
DCHECK(isolate->has_pending_exception());
......
......@@ -570,18 +570,6 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
int beg_pos = scanner()->location().beg_pos;
if (parsing_module_) {
DCHECK(info->is_module());
// Declare the special module parameter.
auto name = ast_value_factory()->empty_string();
bool is_rest = false;
bool is_optional = false;
VariableMode mode = VariableMode::kVar;
bool was_added;
scope->DeclareLocal(name, mode, PARAMETER_VARIABLE, &was_added,
Variable::DefaultInitializationFlag(mode));
DCHECK(was_added);
auto var = scope->DeclareParameter(name, VariableMode::kVar, is_optional,
is_rest, ast_value_factory(), beg_pos);
var->AllocateTo(VariableLocation::PARAMETER, 0);
PrepareGeneratorVariables();
Expression* initial_yield =
......@@ -663,7 +651,7 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
}
}
int parameter_count = parsing_module_ ? 1 : 0;
int parameter_count = 0;
result = factory()->NewScriptOrEvalFunctionLiteral(
scope, body, function_state.expected_property_count(), parameter_count);
result->set_suspend_count(function_state.suspend_count());
......
......@@ -45,11 +45,10 @@ Object ThrowRedeclarationError(Isolate* isolate, Handle<String> name,
}
// May throw a RedeclarationError.
Object DeclareGlobal(
Isolate* isolate, Handle<JSGlobalObject> global, Handle<String> name,
Handle<Object> value, PropertyAttributes attr, bool is_var,
RedeclarationType redeclaration_type,
Handle<FeedbackVector> feedback_vector = Handle<FeedbackVector>()) {
Object DeclareGlobal(Isolate* isolate, Handle<JSGlobalObject> global,
Handle<String> name, Handle<Object> value,
PropertyAttributes attr, bool is_var,
RedeclarationType redeclaration_type) {
Handle<ScriptContextTable> script_contexts(
global->native_context().script_context_table(), isolate);
ScriptContextTable::LookupResult lookup;
......@@ -118,20 +117,70 @@ Object DeclareGlobal(
return ReadOnlyRoots(isolate).undefined_value();
}
Object DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations,
Handle<JSFunction> closure) {
} // namespace
RUNTIME_FUNCTION(Runtime_DeclareModuleExports) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(FixedArray, declarations, 0);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 1);
Handle<ClosureFeedbackCellArray> closure_feedback_cell_array =
Handle<ClosureFeedbackCellArray>::null();
if (closure->has_feedback_vector()) {
closure_feedback_cell_array = Handle<ClosureFeedbackCellArray>(
closure->feedback_vector().closure_feedback_cell_array(), isolate);
} else {
closure_feedback_cell_array = Handle<ClosureFeedbackCellArray>(
closure->closure_feedback_cell_array(), isolate);
}
Handle<Context> context(isolate->context(), isolate);
DCHECK(context->IsModuleContext());
Handle<FixedArray> exports(
SourceTextModule::cast(context->extension()).regular_exports(), isolate);
int length = declarations->length();
FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i++, {
Object decl = declarations->get(i);
int index;
Object value;
if (decl.IsSmi()) {
index = Smi::ToInt(decl);
value = ReadOnlyRoots(isolate).the_hole_value();
} else {
Handle<SharedFunctionInfo> sfi(
SharedFunctionInfo::cast(declarations->get(i)), isolate);
int feedback_index = Smi::ToInt(declarations->get(++i));
index = Smi::ToInt(declarations->get(++i));
Handle<FeedbackCell> feedback_cell =
closure_feedback_cell_array->GetFeedbackCell(feedback_index);
value = *isolate->factory()->NewFunctionFromSharedFunctionInfo(
sfi, context, feedback_cell, AllocationType::kOld);
}
Cell::cast(exports->get(index - 1)).set_value(value);
});
return ReadOnlyRoots(isolate).undefined_value();
}
RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(FixedArray, declarations, 0);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 1);
Handle<JSGlobalObject> global(isolate->global_object());
Handle<Context> context(isolate->context(), isolate);
Handle<FeedbackVector> feedback_vector = Handle<FeedbackVector>::null();
Handle<ClosureFeedbackCellArray> closure_feedback_cell_array =
Handle<ClosureFeedbackCellArray>::null();
if (closure->has_feedback_vector()) {
feedback_vector =
Handle<FeedbackVector>(closure->feedback_vector(), isolate);
closure_feedback_cell_array = Handle<ClosureFeedbackCellArray>(
feedback_vector->closure_feedback_cell_array(), isolate);
closure->feedback_vector().closure_feedback_cell_array(), isolate);
} else {
closure_feedback_cell_array = Handle<ClosureFeedbackCellArray>(
closure->closure_feedback_cell_array(), isolate);
......@@ -168,27 +217,14 @@ Object DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations,
// ES#sec-globaldeclarationinstantiation 5.d:
// If hasRestrictedGlobal is true, throw a SyntaxError exception.
Object result =
DeclareGlobal(isolate, global, name, value, attr, is_var,
RedeclarationType::kSyntaxError, feedback_vector);
Object result = DeclareGlobal(isolate, global, name, value, attr, is_var,
RedeclarationType::kSyntaxError);
if (isolate->has_pending_exception()) return result;
});
return ReadOnlyRoots(isolate).undefined_value();
}
} // namespace
RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(FixedArray, declarations, 0);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 1);
return DeclareGlobals(isolate, declarations, closure);
}
namespace {
Object DeclareEvalHelper(Isolate* isolate, Handle<String> name,
......@@ -619,19 +655,6 @@ RUNTIME_FUNCTION(Runtime_PushWithContext) {
return *context;
}
RUNTIME_FUNCTION(Runtime_PushModuleContext) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(SourceTextModule, module, 0);
CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
Handle<NativeContext> outer(NativeContext::cast(isolate->context()), isolate);
Handle<Context> context =
isolate->factory()->NewModuleContext(module, outer, scope_info);
isolate->set_context(*context);
return *context;
}
RUNTIME_FUNCTION(Runtime_PushCatchContext) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
......
......@@ -387,6 +387,7 @@ namespace internal {
F(DeclareEvalFunction, 2, 1) \
F(DeclareEvalVar, 1, 1) \
F(DeclareGlobals, 2, 1) \
F(DeclareModuleExports, 2, 1) \
F(DeleteLookupSlot, 1, 1) \
F(LoadLookupSlot, 1, 1) \
F(LoadLookupSlotInsideTypeof, 1, 1) \
......@@ -401,7 +402,6 @@ namespace internal {
F(NewStrictArguments, 1, 1) \
F(PushBlockContext, 1, 1) \
F(PushCatchContext, 2, 1) \
F(PushModuleContext, 2, 1) \
F(PushWithContext, 2, 1) \
F(StoreGlobalNoHoleCheckForReplLet, 2, 1) \
F(StoreLookupSlot_Sloppy, 2, 1) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment