Commit 429ff47e authored by neis's avatar neis Committed by Commit bot

Revert of [modules] Basic support of exports (patchset #10 id:180001 of...

Revert of [modules] Basic support of exports (patchset #10 id:180001 of https://codereview.chromium.org/2302783002/ )

Reason for revert:
Failures related to deopt.

Original issue's description:
> [modules] Basic support of exports
>
> This adds partial support of exports to the runtime system and
> to the interpreter. It introduces a new HeapObject JSModule that
> maps each of the module's export names to a Cell containing the
> exported value.
>
> Several aspects of this implementation are subject to change in
> follow-up CLs.
>
> BUG=v8:1569
>
> Committed: https://crrev.com/241a0412eed919395a2e163b30b9b66071ce5c17
> Cr-Commit-Position: refs/heads/master@{#39341}

TBR=adamk@chromium.org,rmcilroy@chromium.org,ulan@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:1569

Review-Url: https://codereview.chromium.org/2328283002
Cr-Commit-Position: refs/heads/master@{#39345}
parent 153dde4f
......@@ -1846,22 +1846,11 @@ MaybeLocal<Value> Script::Run(Local<Context> context) {
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
i::Handle<i::Object> receiver;
i::Handle<i::Object> receiver = isolate->global_proxy();
Local<Value> result;
if (fun->shared()->scope_info()->scope_type() == i::MODULE_SCOPE) {
receiver = isolate->factory()->undefined_value();
i::Handle<i::Object> argv[] = {
handle(isolate->native_context()->current_module())};
has_pending_exception = !ToLocal<Value>(
i::Execution::Call(isolate, fun, receiver, 1, argv), &result);
} else {
receiver = isolate->global_proxy();
has_pending_exception = !ToLocal<Value>(
i::Execution::Call(isolate, fun, receiver, 0, nullptr), &result);
}
has_pending_exception =
!ToLocal<Value>(i::Execution::Call(isolate, fun, receiver, 0, NULL),
&result);
RETURN_ON_FAILED_EXECUTION(Value);
RETURN_ESCAPED(result);
}
......@@ -2002,34 +1991,7 @@ MaybeLocal<Script> ScriptCompiler::CompileModule(Local<Context> context,
Local<UnboundScript> generic;
if (!maybe.ToLocal(&generic)) return MaybeLocal<Script>();
v8::Context::Scope scope(context);
auto result = generic->BindToCurrentContext();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::Handle<i::JSModule> module = i_isolate->factory()->NewJSModule();
// TODO(neis): Storing the module into the native context is a temporary hack
// to pass it to the Script::Run function. This will be removed once we
// support modules in the API.
i_isolate->native_context()->set_current_module(*module);
i::Handle<i::SharedFunctionInfo> shared =
i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(*generic));
i::Handle<i::FixedArray> regular_exports =
i::handle(shared->scope_info()->ModuleDescriptorInfo()->regular_exports(),
i_isolate);
// TODO(neis): This will create multiple cells for the same local variable if
// exported under multiple names, which is wrong but cannot be observed at the
// moment. This will be fixed by doing the full-fledged linking here once we
// get there.
for (int i = 0; i < regular_exports->length(); ++i) {
i::Handle<i::ModuleInfoEntry> entry =
i::handle(i::ModuleInfoEntry::cast(regular_exports->get(i)), i_isolate);
DCHECK(entry->import_name()->IsUndefined(i_isolate));
i::Handle<i::String> export_name =
handle(i::String::cast(entry->export_name()), i_isolate);
i::JSModule::CreateExport(module, export_name);
}
return result;
return generic->BindToCurrentContext();
}
......
......@@ -3378,12 +3378,11 @@ class AstNodeFactory final BASE_EMBEDDED {
// the Function constructor.
FunctionLiteral* NewScriptOrEvalFunctionLiteral(
DeclarationScope* scope, ZoneList<Statement*>* body,
int materialized_literal_count, int expected_property_count,
int parameter_count) {
int materialized_literal_count, int expected_property_count) {
return new (zone_) FunctionLiteral(
zone_, ast_value_factory_->empty_string(), ast_value_factory_, scope,
body, materialized_literal_count, expected_property_count,
parameter_count, FunctionLiteral::kAnonymousExpression,
body, materialized_literal_count, expected_property_count, 0,
FunctionLiteral::kAnonymousExpression,
FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction, 0,
false);
......
......@@ -87,28 +87,27 @@ const AstRawString* FromStringOrUndefined(Isolate* isolate,
} // namespace
Handle<ModuleInfoEntry> ModuleDescriptor::Entry::Serialize(
Isolate* isolate) const {
return ModuleInfoEntry::New(isolate,
ToStringOrUndefined(isolate, export_name),
ToStringOrUndefined(isolate, local_name),
ToStringOrUndefined(isolate, import_name),
ToStringOrUndefined(isolate, module_request));
Handle<FixedArray> ModuleDescriptor::Entry::Serialize(Isolate* isolate) const {
Handle<FixedArray> result = isolate->factory()->NewFixedArray(4);
result->set(0, *ToStringOrUndefined(isolate, export_name));
result->set(1, *ToStringOrUndefined(isolate, local_name));
result->set(2, *ToStringOrUndefined(isolate, import_name));
result->set(3, *ToStringOrUndefined(isolate, module_request));
return result;
}
ModuleDescriptor::Entry* ModuleDescriptor::Entry::Deserialize(
Isolate* isolate, AstValueFactory* avfactory,
Handle<ModuleInfoEntry> entry) {
Entry* result = new (avfactory->zone()) Entry(Scanner::Location::invalid());
result->export_name = FromStringOrUndefined(
isolate, avfactory, handle(entry->export_name(), isolate));
result->local_name = FromStringOrUndefined(
isolate, avfactory, handle(entry->local_name(), isolate));
result->import_name = FromStringOrUndefined(
isolate, avfactory, handle(entry->import_name(), isolate));
result->module_request = FromStringOrUndefined(
isolate, avfactory, handle(entry->module_request(), isolate));
return result;
Isolate* isolate, AstValueFactory* avfactory, Handle<FixedArray> data) {
Entry* entry = new (avfactory->zone()) Entry(Scanner::Location::invalid());
entry->export_name =
FromStringOrUndefined(isolate, avfactory, handle(data->get(0), isolate));
entry->local_name =
FromStringOrUndefined(isolate, avfactory, handle(data->get(1), isolate));
entry->import_name =
FromStringOrUndefined(isolate, avfactory, handle(data->get(2), isolate));
entry->module_request =
FromStringOrUndefined(isolate, avfactory, handle(data->get(3), isolate));
return entry;
}
void ModuleDescriptor::MakeIndirectExportsExplicit(Zone* zone) {
......
......@@ -14,7 +14,7 @@ namespace internal {
class AstRawString;
class ModuleInfoEntry;
class ModuleDescriptor : public ZoneObject {
public:
......@@ -80,7 +80,6 @@ class ModuleDescriptor : public ZoneObject {
const AstRawString* import_name;
const AstRawString* module_request;
// TODO(neis): Remove local_name component?
explicit Entry(Scanner::Location loc)
: location(loc),
export_name(nullptr),
......@@ -88,12 +87,9 @@ class ModuleDescriptor : public ZoneObject {
import_name(nullptr),
module_request(nullptr) {}
// (De-)serialization support.
// Note that the location value is not preserved as it's only needed by the
// parser. (A Deserialize'd entry has an invalid location.)
Handle<ModuleInfoEntry> Serialize(Isolate* isolate) const;
Handle<FixedArray> Serialize(Isolate* isolate) const;
static Entry* Deserialize(Isolate* isolate, AstValueFactory* avfactory,
Handle<ModuleInfoEntry> entry);
Handle<FixedArray> data);
};
// Empty imports and namespace imports.
......
......@@ -517,7 +517,7 @@ ScopeInfo* ScopeInfo::OuterScopeInfo() {
ModuleInfo* ScopeInfo::ModuleDescriptorInfo() {
DCHECK(scope_type() == MODULE_SCOPE);
return ModuleInfo::cast(get(ModuleInfoIndex()));
return static_cast<ModuleInfo*>(get(ModuleInfoIndex()));
}
String* ScopeInfo::ParameterName(int var) {
......@@ -811,26 +811,12 @@ void ScopeInfo::Print() {
PrintList("context slots", Context::MIN_CONTEXT_SLOTS,
ContextLocalNamesIndex(),
ContextLocalNamesIndex() + ContextLocalCount(), this);
// TODO(neis): Print module stuff if present.
}
PrintF("}\n");
}
#endif // DEBUG
Handle<ModuleInfoEntry> ModuleInfoEntry::New(Isolate* isolate,
Handle<Object> export_name,
Handle<Object> local_name,
Handle<Object> import_name,
Handle<Object> module_request) {
Handle<ModuleInfoEntry> result = isolate->factory()->NewModuleInfoEntry();
result->set(kExportNameIndex, *export_name);
result->set(kLocalNameIndex, *local_name);
result->set(kImportNameIndex, *import_name);
result->set(kModuleRequestIndex, *module_request);
return result;
}
Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, ModuleDescriptor* descr) {
// Serialize special exports.
Handle<FixedArray> special_exports =
......
......@@ -171,8 +171,8 @@ ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
// Deserialize special exports.
Handle<FixedArray> special_exports = handle(module_info->special_exports());
for (int i = 0, n = special_exports->length(); i < n; ++i) {
Handle<ModuleInfoEntry> serialized_entry(
ModuleInfoEntry::cast(special_exports->get(i)), isolate);
Handle<FixedArray> serialized_entry(
FixedArray::cast(special_exports->get(i)), isolate);
module_descriptor_->AddSpecialExport(
ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
serialized_entry),
......@@ -182,8 +182,8 @@ ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
// Deserialize regular exports.
Handle<FixedArray> regular_exports = handle(module_info->regular_exports());
for (int i = 0, n = regular_exports->length(); i < n; ++i) {
Handle<ModuleInfoEntry> serialized_entry(
ModuleInfoEntry::cast(regular_exports->get(i)), isolate);
Handle<FixedArray> serialized_entry(
FixedArray::cast(regular_exports->get(i)), isolate);
module_descriptor_->AddRegularExport(ModuleDescriptor::Entry::Deserialize(
isolate, avfactory, serialized_entry));
}
......@@ -829,7 +829,7 @@ Variable* DeclarationScope::DeclareParameter(
const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest,
bool* is_duplicate, AstValueFactory* ast_value_factory) {
DCHECK(!already_resolved_);
DCHECK(is_function_scope() || is_module_scope());
DCHECK(is_function_scope());
DCHECK(!has_rest_);
DCHECK(!is_optional || !is_rest);
Variable* var;
......@@ -1164,16 +1164,6 @@ DeclarationScope* Scope::GetClosureScope() {
return scope->AsDeclarationScope();
}
ModuleScope* Scope::GetModuleScope() {
Scope* scope = this;
DCHECK(!scope->is_script_scope());
while (!scope->is_module_scope()) {
scope = scope->outer_scope();
DCHECK_NOT_NULL(scope);
}
return scope->AsModuleScope();
}
DeclarationScope* Scope::GetReceiverScope() {
Scope* scope = this;
while (!scope->is_script_scope() &&
......
......@@ -371,9 +371,6 @@ class Scope: public ZoneObject {
// 'this' is bound, and what determines the function kind.
DeclarationScope* GetReceiverScope();
// Find the module scope, assuming there is one.
ModuleScope* GetModuleScope();
// Analyze() must have been called once to create the ScopeInfo.
Handle<ScopeInfo> scope_info() {
DCHECK(!scope_info_.is_null());
......@@ -680,9 +677,9 @@ class DeclarationScope : public Scope {
}
// Parameters. The left-most parameter has index 0.
// Only valid for function and module scopes.
// Only valid for function scopes.
Variable* parameter(int index) const {
DCHECK(is_function_scope() || is_module_scope());
DCHECK(is_function_scope());
return params_[index];
}
......
......@@ -102,11 +102,6 @@ class Variable final : public ZoneObject {
int index() const { return index_; }
bool IsExport() const {
DCHECK(location() == VariableLocation::MODULE);
return index() == 0;
}
void AllocateTo(VariableLocation location, int index) {
DCHECK(IsUnallocated() ||
(this->location() == location && this->index() == index));
......
......@@ -57,8 +57,7 @@ bool ScriptContextTable::Lookup(Handle<ScriptContextTable> table,
bool Context::is_declaration_context() {
if (IsFunctionContext() || IsNativeContext() || IsScriptContext() ||
IsModuleContext()) {
if (IsFunctionContext() || IsNativeContext() || IsScriptContext()) {
return true;
}
if (!IsBlockContext()) return false;
......@@ -124,13 +123,6 @@ ScopeInfo* Context::scope_info() {
return ScopeInfo::cast(object);
}
JSModule* Context::module() {
Context* current = this;
while (!current->IsModuleContext()) {
current = current->previous();
}
return JSModule::cast(current->extension());
}
String* Context::catch_name() {
DCHECK(IsCatchContext());
......@@ -197,7 +189,6 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
int* index, PropertyAttributes* attributes,
InitializationFlag* init_flag,
VariableMode* variable_mode) {
DCHECK(!IsModuleContext());
Isolate* isolate = GetIsolate();
Handle<Context> context(this, isolate);
......
......@@ -227,7 +227,6 @@ enum ContextLookupFlags {
V(UINT8_ARRAY_FUN_INDEX, JSFunction, uint8_array_fun) \
V(UINT8_CLAMPED_ARRAY_FUN_INDEX, JSFunction, uint8_clamped_array_fun) \
V(UINT8X16_FUNCTION_INDEX, JSFunction, uint8x16_function) \
V(CURRENT_MODULE_INDEX, JSModule, current_module) \
NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(V) \
NATIVE_CONTEXT_IMPORTED_FIELDS(V)
......@@ -399,10 +398,6 @@ class Context: public FixedArray {
ScopeInfo* scope_info();
String* catch_name();
// Find the module context (assuming there is one) and return the associated
// module object.
JSModule* module();
// Get the context where var declarations will be hoisted to, which
// may be the context itself.
Context* declaration_context();
......
......@@ -362,7 +362,7 @@ bool ScopeIterator::SetVariableValue(Handle<String> variable_name,
case ScopeIterator::ScopeTypeEval:
return SetInnerScopeVariableValue(variable_name, new_value);
case ScopeIterator::ScopeTypeModule:
// TODO(neis): Implement.
// TODO(2399): should we implement it?
break;
}
return false;
......@@ -617,8 +617,6 @@ MaybeHandle<JSObject> ScopeIterator::MaterializeModuleScope() {
// Fill all context locals.
CopyContextLocalsToScopeObject(scope_info, context, module_scope);
// TODO(neis): Also collect stack locals as well as imports and exports.
return module_scope;
}
......
......@@ -789,19 +789,15 @@ Handle<ScriptContextTable> Factory::NewScriptContextTable() {
return context_table;
}
Handle<Context> Factory::NewModuleContext(Handle<JSModule> module,
Handle<JSFunction> function,
Handle<ScopeInfo> scope_info) {
Handle<Context> Factory::NewModuleContext(Handle<ScopeInfo> scope_info) {
DCHECK_EQ(scope_info->scope_type(), MODULE_SCOPE);
Handle<FixedArray> array =
NewFixedArray(scope_info->ContextLength(), TENURED);
array->set_map_no_write_barrier(*module_context_map());
// Instance link will be set later.
Handle<Context> context = Handle<Context>::cast(array);
context->set_closure(*function);
context->set_previous(function->context());
context->set_extension(*module);
context->set_native_context(function->native_context());
DCHECK(context->IsModuleContext());
context->set_extension(*the_hole_value());
return context;
}
......@@ -1402,16 +1398,11 @@ Handle<ScopeInfo> Factory::NewScopeInfo(int length) {
return scope_info;
}
Handle<ModuleInfoEntry> Factory::NewModuleInfoEntry() {
Handle<FixedArray> array = NewFixedArray(ModuleInfoEntry::kLength, TENURED);
array->set_map_no_write_barrier(*module_info_entry_map());
return Handle<ModuleInfoEntry>::cast(array);
}
Handle<ModuleInfo> Factory::NewModuleInfo() {
Handle<FixedArray> array = NewFixedArray(ModuleInfo::kLength, TENURED);
array->set_map_no_write_barrier(*module_info_map());
return Handle<ModuleInfo>::cast(array);
Handle<ModuleInfo> module_info = Handle<ModuleInfo>::cast(array);
return module_info;
}
Handle<JSObject> Factory::NewExternal(void* value) {
......@@ -1704,11 +1695,6 @@ Handle<JSGeneratorObject> Factory::NewJSGeneratorObject(
JSGeneratorObject);
}
Handle<JSModule> Factory::NewJSModule() {
Handle<JSModule> module =
Handle<JSModule>::cast(NewJSObjectFromMap(js_module_map(), TENURED));
return module;
}
Handle<JSArrayBuffer> Factory::NewJSArrayBuffer(SharedFlag shared,
PretenureFlag pretenure) {
......
......@@ -257,9 +257,7 @@ class Factory final {
Handle<ScriptContextTable> NewScriptContextTable();
// Create a module context.
Handle<Context> NewModuleContext(Handle<JSModule> module,
Handle<JSFunction> function,
Handle<ScopeInfo> scope_info);
Handle<Context> NewModuleContext(Handle<ScopeInfo> scope_info);
// Create a function context.
Handle<Context> NewFunctionContext(int length, Handle<JSFunction> function);
......@@ -477,8 +475,6 @@ class Factory final {
Handle<JSGeneratorObject> NewJSGeneratorObject(Handle<JSFunction> function);
Handle<JSModule> NewJSModule();
Handle<JSArrayBuffer> NewJSArrayBuffer(
SharedFlag shared = SharedFlag::kNotShared,
PretenureFlag pretenure = NOT_TENURED);
......@@ -563,7 +559,6 @@ class Factory final {
// Create a serialized scope info.
Handle<ScopeInfo> NewScopeInfo(int length);
Handle<ModuleInfoEntry> NewModuleInfoEntry();
Handle<ModuleInfo> NewModuleInfo();
// Create an External object for V8's external API.
......
......@@ -2307,9 +2307,7 @@ bool Heap::CreateInitialMaps() {
DCHECK_NE(fixed_array_map(), fixed_cow_array_map());
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, scope_info)
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_info_entry)
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_info)
ALLOCATE_MAP(JS_MODULE_TYPE, JSModule::kSize, js_module)
ALLOCATE_PRIMITIVE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number,
Context::NUMBER_FUNCTION_INDEX)
ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, HeapNumber::kSize,
......
......@@ -48,9 +48,7 @@ using v8::MemoryPressureLevel;
V(Map, one_byte_string_map, OneByteStringMap) \
V(Map, one_byte_internalized_string_map, OneByteInternalizedStringMap) \
V(Map, scope_info_map, ScopeInfoMap) \
V(Map, module_info_entry_map, ModuleInfoEntryMap) \
V(Map, module_info_map, ModuleInfoMap) \
V(Map, js_module_map, JSModuleMap) \
V(Map, shared_function_info_map, SharedFunctionInfoMap) \
V(Map, code_map, CodeMap) \
V(Map, function_context_map, FunctionContextMap) \
......@@ -277,9 +275,7 @@ using v8::MemoryPressureLevel;
V(FixedArrayMap) \
V(CodeMap) \
V(ScopeInfoMap) \
V(ModuleInfoEntryMap) \
V(ModuleInfoMap) \
V(JSModuleMap) \
V(FixedCOWArrayMap) \
V(FixedDoubleArrayMap) \
V(WeakCellMap) \
......
......@@ -743,6 +743,7 @@ void BytecodeGenerator::GenerateBytecode(uintptr_t stack_limit) {
VisitGeneratorPrologue();
}
// Build function context only if there are context allocated variables.
if (scope()->NeedsContext()) {
// Push a new inner context scope for the function.
BuildNewLocalActivationContext();
......@@ -939,8 +940,7 @@ void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
break;
}
case VariableLocation::MODULE:
// Nothing to do here.
break;
UNREACHABLE();
}
}
......@@ -979,11 +979,7 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
break;
}
case VariableLocation::MODULE:
DCHECK(variable->mode() == LET);
VisitForAccumulatorValue(decl->fun());
VisitVariableAssignment(variable, Token::INIT,
FeedbackVectorSlot::Invalid());
break;
UNREACHABLE();
}
}
......@@ -1982,21 +1978,8 @@ void BytecodeGenerator::VisitVariableLoad(Variable* variable,
builder()->LoadLookupSlot(variable->name(), typeof_mode);
break;
}
case VariableLocation::MODULE: {
ModuleDescriptor* descriptor = scope()->GetModuleScope()->module();
if (variable->IsExport()) {
auto it = descriptor->regular_exports().find(variable->raw_name());
DCHECK(it != descriptor->regular_exports().end());
Register export_name = register_allocator()->NewRegister();
builder()
->LoadLiteral(it->second->export_name->string())
.StoreAccumulatorInRegister(export_name)
.CallRuntime(Runtime::kLoadModuleExport, export_name, 1);
} else {
UNIMPLEMENTED();
}
break;
}
case VariableLocation::MODULE:
UNREACHABLE();
}
execution_result()->SetResultInAccumulator();
}
......@@ -2194,33 +2177,8 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
builder()->StoreLookupSlot(variable->name(), language_mode());
break;
}
case VariableLocation::MODULE: {
DCHECK(IsDeclaredVariableMode(mode));
if (mode == CONST && op != Token::INIT) {
builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0);
break;
}
// If we don't throw above, we know that we're dealing with an
// export because imports are const and we do not generate initializing
// assignments for them.
DCHECK(variable->IsExport());
ModuleDescriptor* mod = scope()->GetModuleScope()->module();
auto it = mod->regular_exports().find(variable->raw_name());
DCHECK(it != mod->regular_exports().end());
register_allocator()->PrepareForConsecutiveAllocations(2);
Register export_name = register_allocator()->NextConsecutiveRegister();
Register value = register_allocator()->NextConsecutiveRegister();
builder()
->StoreAccumulatorInRegister(value)
.LoadLiteral(it->second->export_name->string())
.StoreAccumulatorInRegister(export_name)
.CallRuntime(Runtime::kStoreModuleExport, export_name, 2);
break;
}
case VariableLocation::MODULE:
UNREACHABLE();
}
}
......@@ -3177,36 +3135,18 @@ void BytecodeGenerator::BuildNewLocalActivationContext() {
AccumulatorResultScope accumulator_execution_result(this);
Scope* scope = this->scope();
// Create the appropriate context.
// Allocate a new local context.
if (scope->is_script_scope()) {
RegisterAllocationScope register_scope(this);
register_allocator()->PrepareForConsecutiveAllocations(2);
Register closure = register_allocator()->NextConsecutiveRegister();
Register scope_info = register_allocator()->NextConsecutiveRegister();
Register closure = register_allocator()->NewRegister();
Register scope_info = register_allocator()->NewRegister();
DCHECK(Register::AreContiguous(closure, scope_info));
builder()
->LoadAccumulatorWithRegister(Register::function_closure())
.StoreAccumulatorInRegister(closure)
.LoadLiteral(scope->scope_info())
.StoreAccumulatorInRegister(scope_info)
.CallRuntime(Runtime::kNewScriptContext, closure, 2);
} else if (scope->is_module_scope()) {
// We don't need to do anything for the outer script scope.
DCHECK(scope->outer_scope()->is_script_scope());
RegisterAllocationScope register_scope(this);
register_allocator()->PrepareForConsecutiveAllocations(3);
Register module = register_allocator()->NextConsecutiveRegister();
Register closure = register_allocator()->NextConsecutiveRegister();
Register scope_info = register_allocator()->NextConsecutiveRegister();
// A JSFunction representing a module is called with the module object as
// its sole argument, which we pass on to PushModuleContext.
builder()
->MoveRegister(builder()->Parameter(1), module)
.LoadAccumulatorWithRegister(Register::function_closure())
.StoreAccumulatorInRegister(closure)
.LoadLiteral(scope->scope_info())
.StoreAccumulatorInRegister(scope_info)
.CallRuntime(Runtime::kPushModuleContext, module, 3);
} else {
int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
builder()->CreateFunctionContext(slot_count);
......@@ -3353,7 +3293,8 @@ void BytecodeGenerator::VisitFunctionClosureForContext() {
AccumulatorResultScope accumulator_execution_result(this);
DeclarationScope* closure_scope =
execution_context()->scope()->GetClosureScope();
if (closure_scope->is_script_scope()) {
if (closure_scope->is_script_scope() ||
closure_scope->is_module_scope()) {
// Contexts nested in the native context have a canonical empty function as
// their closure, not the anonymous closure containing the global code.
Register native_context = register_allocator()->NewRegister();
......@@ -3369,8 +3310,7 @@ void BytecodeGenerator::VisitFunctionClosureForContext() {
builder()->LoadContextSlot(execution_context()->reg(),
Context::CLOSURE_INDEX);
} else {
DCHECK(closure_scope->is_function_scope() ||
closure_scope->is_module_scope());
DCHECK(closure_scope->is_function_scope());
builder()->LoadAccumulatorWithRegister(Register::function_closure());
}
execution_result()->SetResultInAccumulator();
......
......@@ -166,9 +166,6 @@ void HeapObject::HeapObjectVerify() {
case JS_PROXY_TYPE:
JSProxy::cast(this)->JSProxyVerify();
break;
case JS_MODULE_TYPE:
JSModule::cast(this)->JSModuleVerify();
break;
case FOREIGN_TYPE:
Foreign::cast(this)->ForeignVerify();
break;
......@@ -834,7 +831,6 @@ void JSRegExp::JSRegExpVerify() {
}
}
void JSModule::JSModuleVerify() { CHECK(IsJSModule()); }
void JSProxy::JSProxyVerify() {
CHECK(IsJSProxy());
......
......@@ -793,10 +793,6 @@ bool HeapObject::IsScopeInfo() const {
return map() == GetHeap()->scope_info_map();
}
bool HeapObject::IsModuleInfoEntry() const {
return map() == GetHeap()->module_info_entry_map();
}
bool HeapObject::IsModuleInfo() const {
return map() == GetHeap()->module_info_map();
}
......@@ -3276,7 +3272,6 @@ CAST_ACCESSOR(JSGlobalProxy)
CAST_ACCESSOR(JSMap)
CAST_ACCESSOR(JSMapIterator)
CAST_ACCESSOR(JSMessageObject)
CAST_ACCESSOR(JSModule)
CAST_ACCESSOR(JSObject)
CAST_ACCESSOR(JSProxy)
CAST_ACCESSOR(JSReceiver)
......@@ -3290,7 +3285,6 @@ CAST_ACCESSOR(JSWeakMap)
CAST_ACCESSOR(JSWeakSet)
CAST_ACCESSOR(LayoutDescriptor)
CAST_ACCESSOR(Map)
CAST_ACCESSOR(ModuleInfoEntry)
CAST_ACCESSOR(ModuleInfo)
CAST_ACCESSOR(Name)
CAST_ACCESSOR(NameDictionary)
......@@ -6655,8 +6649,6 @@ bool JSGeneratorObject::is_executing() const {
return continuation() == kGeneratorExecuting;
}
TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
ACCESSORS(JSValue, value, Object, kValueOffset)
......@@ -7929,16 +7921,6 @@ bool ScopeInfo::HasSimpleParameters() {
FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(SCOPE_INFO_FIELD_ACCESSORS)
#undef SCOPE_INFO_FIELD_ACCESSORS
Object* ModuleInfoEntry::export_name() const { return get(kExportNameIndex); }
Object* ModuleInfoEntry::local_name() const { return get(kLocalNameIndex); }
Object* ModuleInfoEntry::import_name() const { return get(kImportNameIndex); }
Object* ModuleInfoEntry::module_request() const {
return get(kModuleRequestIndex);
}
FixedArray* ModuleInfo::special_exports() const {
return FixedArray::cast(get(kSpecialExportsIndex));
}
......
......@@ -19470,28 +19470,5 @@ bool JSReceiver::HasProxyInPrototype(Isolate* isolate) {
return false;
}
void JSModule::CreateExport(Handle<JSModule> module, Handle<String> name) {
Isolate* isolate = module->GetIsolate();
Handle<Cell> cell =
isolate->factory()->NewCell(isolate->factory()->undefined_value());
LookupIterator it(module, name);
JSObject::CreateDataProperty(&it, cell, Object::THROW_ON_ERROR).ToChecked();
}
void JSModule::StoreExport(Handle<JSModule> module, Handle<String> name,
Handle<Object> value) {
LookupIterator it(module, name);
Handle<Cell> cell = Handle<Cell>::cast(JSObject::GetDataProperty(&it));
cell->set_value(*value);
}
Handle<Object> JSModule::LoadExport(Handle<JSModule> module,
Handle<String> name) {
Isolate* isolate = module->GetIsolate();
LookupIterator it(module, name);
Handle<Cell> cell = Handle<Cell>::cast(JSObject::GetDataProperty(&it));
return handle(cell->value(), isolate);
}
} // namespace internal
} // namespace v8
......@@ -70,7 +70,6 @@
// - JSValue
// - JSDate
// - JSMessageObject
// - JSModule
// - JSProxy
// - FixedArrayBase
// - ByteArray
......@@ -95,7 +94,6 @@
// - TemplateList
// - TransitionArray
// - ScopeInfo
// - ModuleInfoEntry
// - ModuleInfo
// - ScriptContextTable
// - WeakFixedArray
......@@ -881,7 +879,6 @@ class LiteralsArray;
class LookupIterator;
class FieldType;
class ModuleDescriptor;
class ModuleInfoEntry;
class ModuleInfo;
class ObjectHashTable;
class ObjectVisitor;
......@@ -964,7 +961,6 @@ template <class C> inline bool Is(Object* obj);
V(JSObject) \
V(JSContextExtensionObject) \
V(JSGeneratorObject) \
V(JSModule) \
V(Map) \
V(DescriptorArray) \
V(FrameArray) \
......@@ -984,7 +980,6 @@ template <class C> inline bool Is(Object* obj);
V(ScriptContextTable) \
V(NativeContext) \
V(ScopeInfo) \
V(ModuleInfoEntry) \
V(ModuleInfo) \
V(JSBoundFunction) \
V(JSFunction) \
......@@ -4417,7 +4412,7 @@ class ScopeInfo : public FixedArray {
// The layout of the static part of a ScopeInfo is as follows. Each entry is
// numeric and occupies one array slot.
// 1. A set of properties of the scope.
// 1. A set of properties of the scope
// 2. The number of parameters. For non-function scopes this is 0.
// 3. The number of non-parameter variables allocated on the stack.
// 4. The number of non-parameter and parameter variables allocated in the
......@@ -4535,30 +4530,6 @@ class ScopeInfo : public FixedArray {
friend class ScopeIterator;
};
class ModuleInfoEntry : public FixedArray {
public:
DECLARE_CAST(ModuleInfoEntry)
static Handle<ModuleInfoEntry> New(Isolate* isolate,
Handle<Object> export_name,
Handle<Object> local_name,
Handle<Object> import_name,
Handle<Object> module_request);
inline Object* export_name() const;
inline Object* local_name() const;
inline Object* import_name() const;
inline Object* module_request() const;
private:
friend class Factory;
enum {
kExportNameIndex,
kLocalNameIndex,
kImportNameIndex,
kModuleRequestIndex,
kLength
};
};
// ModuleInfo is to ModuleDescriptor what ScopeInfo is to Scope.
class ModuleInfo : public FixedArray {
public:
......@@ -6366,7 +6337,6 @@ class Map: public HeapObject {
inline bool IsJSFunctionMap();
inline bool IsStringMap();
inline bool IsJSProxyMap();
inline bool IsJSModuleMap();
inline bool IsJSGlobalProxyMap();
inline bool IsJSGlobalObjectMap();
inline bool IsJSTypedArrayMap();
......@@ -7844,21 +7814,6 @@ class JSGeneratorObject: public JSObject {
DISALLOW_IMPLICIT_CONSTRUCTORS(JSGeneratorObject);
};
// A JSModule object is a mapping from export names to cells
// This is still very much in flux.
class JSModule : public JSObject {
public:
DECLARE_CAST(JSModule)
DECLARE_VERIFIER(JSModule)
static const int kSize = JSObject::kHeaderSize;
static void CreateExport(Handle<JSModule> module, Handle<String> name);
static void StoreExport(Handle<JSModule> module, Handle<String> name,
Handle<Object> value);
static Handle<Object> LoadExport(Handle<JSModule> module,
Handle<String> name);
};
// JSBoundFunction describes a bound function exotic object.
class JSBoundFunction : public JSObject {
......
......@@ -742,16 +742,6 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
int beg_pos = scanner()->location().beg_pos;
parsing_module_ = info->is_module();
if (parsing_module_) {
// Declare the special module parameter.
auto name = ast_value_factory()->empty_string();
bool is_duplicate;
bool is_rest = false;
bool is_optional = false;
auto var = scope->DeclareParameter(name, VAR, is_optional, is_rest,
&is_duplicate, ast_value_factory());
DCHECK(!is_duplicate);
var->AllocateTo(VariableLocation::PARAMETER, 0);
ParseModuleItemList(body, &ok);
ok = ok &&
module()->Validate(this->scope()->AsModuleScope(),
......@@ -795,10 +785,9 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
if (ok) {
RewriteDestructuringAssignments();
int parameter_count = parsing_module_ ? 1 : 0;
result = factory()->NewScriptOrEvalFunctionLiteral(
scope, body, function_state.materialized_literal_count(),
function_state.expected_property_count(), parameter_count);
function_state.expected_property_count());
}
}
......
......@@ -928,23 +928,5 @@ RUNTIME_FUNCTION(Runtime_CreateDataProperty) {
return *value;
}
RUNTIME_FUNCTION(Runtime_LoadModuleExport) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
Handle<JSModule> module(isolate->context()->module());
return *JSModule::LoadExport(module, name);
}
RUNTIME_FUNCTION(Runtime_StoreModuleExport) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
Handle<JSModule> module(isolate->context()->module());
JSModule::StoreExport(module, name, value);
return isolate->heap()->undefined_value();
}
} // namespace internal
} // namespace v8
......@@ -699,19 +699,6 @@ RUNTIME_FUNCTION(Runtime_PushWithContext) {
return *context;
}
RUNTIME_FUNCTION(Runtime_PushModuleContext) {
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSModule, module, 0);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 1);
CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 2);
DCHECK(function->context() == isolate->context());
Handle<Context> context =
isolate->factory()->NewModuleContext(module, function, scope_info);
isolate->set_context(*context);
return *context;
}
RUNTIME_FUNCTION(Runtime_PushCatchContext) {
HandleScope scope(isolate);
......
......@@ -416,9 +416,7 @@ namespace internal {
F(HasInPrototypeChain, 2, 1) \
F(CreateIterResultObject, 2, 1) \
F(IsAccessCheckNeeded, 1, 1) \
F(CreateDataProperty, 3, 1) \
F(LoadModuleExport, 1, 1) \
F(StoreModuleExport, 2, 1)
F(CreateDataProperty, 3, 1)
#define FOR_EACH_INTRINSIC_OPERATORS(F) \
F(Multiply, 2, 1) \
......@@ -477,7 +475,6 @@ namespace internal {
F(NewClosure_Tenured, 1, 1) \
F(NewScriptContext, 2, 1) \
F(NewFunctionContext, 1, 1) \
F(PushModuleContext, 3, 1) \
F(PushWithContext, 3, 1) \
F(PushCatchContext, 4, 1) \
F(PushBlockContext, 2, 1) \
......
......@@ -79,7 +79,7 @@ bytecodes: [
/* 15 S> */ B(LdrUndefined), R(0),
B(CreateArrayLiteral), U8(0), U8(0), U8(1),
B(Star), R(1),
B(CallJSRuntime), U8(135), R(0), U8(2),
B(CallJSRuntime), U8(134), R(0), U8(2),
/* 44 S> */ B(Return),
]
constant pool: [
......
......@@ -805,12 +805,6 @@
'es6/tail-call-megatest*': [SKIP],
}], # variant == ignition_turbofan and msan
['variant != ignition', {
# Ongoing implementation of modules.
# https://bugs.chromium.org/p/v8/issues/detail?id=1569
'modules-*': [SKIP],
}], # variants != ignition
##############################################################################
['gcov_coverage', {
# Tests taking too long.
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// MODULE
export var myvar = "VAR";
assertEquals("VAR", myvar);
assertEquals("VAR", eval("myvar"));
(() => assertEquals("VAR", myvar))();
export let mylet = "LET";
assertEquals("LET", mylet);
assertEquals("LET", eval("mylet"));
(() => assertEquals("LET", mylet))();
export const myconst = "CONST";
assertEquals("CONST", myconst);
assertEquals("CONST", eval("myconst"));
(() => assertEquals("CONST", myconst))();
myvar = 1;
assertEquals(1, myvar);
assertEquals(1, eval("myvar"));
(() => assertEquals(1, myvar))();
(() => myvar = 2)();
assertEquals(2, myvar);
(() => assertEquals(2, myvar))();
{
let f = () => assertEquals(2, myvar);
f();
}
mylet = 1;
assertEquals(1, mylet);
assertEquals(1, eval("mylet"));
(() => assertEquals(1, mylet))();
(() => mylet = 2)();
assertEquals(2, mylet);
assertEquals(2, eval("mylet"));
(() => assertEquals(2, mylet))();
{
let f = () => assertEquals(2, mylet);
f();
}
assertThrows(() => myconst = 1, TypeError);
assertEquals("CONST", myconst);
assertEquals("CONST", eval("myconst"));
(() => assertEquals("CONST", myconst))();
{
let f = () => assertEquals("CONST", myconst);
f();
}
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// MODULE
export function foo() { return 42 }
assertEquals(42, foo());
foo = 1;
assertEquals(1, foo);
let gaga = 43;
export {gaga as gugu};
assertEquals(43, gaga);
export default (function bar() { return 43 })
assertThrows(() => bar(), ReferenceError);
assertThrows("default", SyntaxError);
assertThrows("*default*", SyntaxError);
var bla = 44;
var blu = 45;
export {bla};
export {bla as blu};
export {bla as bli};
assertEquals(44, bla);
assertEquals(45, blu);
bla = 46;
assertEquals(46, bla);
assertEquals(45, blu);
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// MODULE
export { myvar, mylet, myconst };
var myvar = "VAR";
assertEquals("VAR", myvar);
let mylet = "LET";
assertEquals("LET", mylet);
const myconst = "CONST";
assertEquals("CONST", myconst);
function* gaga() { yield 1 }
assertEquals(1, gaga().next().value);
export {gaga};
export default gaga;
export {gaga as gigi};
assertEquals(1, gaga().next().value);
export let gugu = 42;
{
assertEquals(42, gugu);
}
try {
assertEquals(42, gugu);
} catch(_) {
assertUnreachable();
}
try {
throw {};
} catch(_) {
assertEquals(42, gugu);
}
try {
throw {};
} catch({x=gugu}) {
assertEquals(42, x);
}
assertEquals(5, eval("var x = 5; x"));
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// MODULE
assertEquals(undefined, this);
......@@ -26,7 +26,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[
[ALWAYS, {
###################### NEEDS INVESTIGATION #######################
......@@ -313,6 +312,13 @@
'built-ins/Function/prototype/toString/setter-object': [FAIL],
'built-ins/Function/prototype/toString/unicode': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=1569
'language/eval-code/direct/export': [SKIP],
'language/eval-code/direct/import': [SKIP],
'language/eval-code/indirect/export': [SKIP],
'language/eval-code/indirect/import': [SKIP],
'language/module-code/*': [SKIP],
# https://bugs.chromium.org/p/v8/issues/detail?id=5012
# http://bugs.icu-project.org/trac/ticket/12671
'intl402/Intl/getCanonicalLocales/weird-cases': [FAIL],
......@@ -625,21 +631,4 @@
'built-ins/ArrayBuffer/length-is-too-large-throws': [SKIP],
}], # asan == True or msan == True or tsan == True
# Module-related tests
# https://bugs.chromium.org/p/v8/issues/detail?id=1569
['variant != ignition', {
'language/eval-code/direct/export': [SKIP],
'language/eval-code/direct/import': [SKIP],
'language/eval-code/indirect/export': [SKIP],
'language/eval-code/indirect/import': [SKIP],
'language/module-code/*': [SKIP],
}], # 'variant != ignition'
['variant == ignition', {
'language/module-code/comment-*': [SKIP],
'language/module-code/eval-*': [SKIP],
'language/module-code/instn-*': [SKIP],
'language/module-code/namespace/*': [SKIP],
'language/module-code/parse-err-*': [SKIP],
}], # 'variant == ignition'
]
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