void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = declaration->proxy()->var();
+ Interface* interface = declaration->module()->interface();
DCHECK(variable->location() == Variable::CONTEXT);
- DCHECK(variable->interface()->IsFrozen());
+ DCHECK(interface->IsFrozen());
Comment cmnt(masm_, "[ ModuleDeclaration");
EmitDebugCheckDeclarationContext(variable);
// Load instance object.
__ LoadContext(r1, scope_->ContextChainLength(scope_->ScriptScope()));
- __ ldr(r1, ContextOperand(r1, variable->interface()->Index()));
+ __ ldr(r1, ContextOperand(r1, interface->Index()));
__ ldr(r1, ContextOperand(r1, Context::EXTENSION_INDEX));
// Assign it.
void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = declaration->proxy()->var();
+ Interface* interface = declaration->module()->interface();
DCHECK(variable->location() == Variable::CONTEXT);
- DCHECK(variable->interface()->IsFrozen());
+ DCHECK(interface->IsFrozen());
Comment cmnt(masm_, "[ ModuleDeclaration");
EmitDebugCheckDeclarationContext(variable);
// Load instance object.
__ LoadContext(x1, scope_->ContextChainLength(scope_->ScriptScope()));
- __ Ldr(x1, ContextMemOperand(x1, variable->interface()->Index()));
+ __ Ldr(x1, ContextMemOperand(x1, interface->Index()));
__ Ldr(x1, ContextMemOperand(x1, Context::EXTENSION_INDEX));
// Assign it.
}
-void AstNumberingVisitor::VisitModuleVariable(ModuleVariable* node) {
- IncrementNodeCount();
- DisableOptimization(kModuleVariable);
- Visit(node->proxy());
-}
-
-
void AstNumberingVisitor::VisitModulePath(ModulePath* node) {
IncrementNodeCount();
DisableOptimization(kModulePath);
IsAssignedField::encode(false) |
IsResolvedField::encode(false)),
variable_feedback_slot_(FeedbackVectorICSlot::Invalid()),
- raw_name_(var->raw_name()),
- interface_(var->interface()) {
+ raw_name_(var->raw_name()) {
BindTo(var);
}
VariableProxy::VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
- Interface* interface, int position)
+ int position)
: Expression(zone, position),
bit_field_(IsThisField::encode(is_this) | IsAssignedField::encode(false) |
IsResolvedField::encode(false)),
variable_feedback_slot_(FeedbackVectorICSlot::Invalid()),
- raw_name_(name),
- interface_(interface) {}
+ raw_name_(name) {}
void VariableProxy::BindTo(Variable* var) {
- DCHECK(!FLAG_harmony_modules || interface_->IsUnified(var->interface()));
DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name());
set_var(var);
set_is_resolved();
#define MODULE_NODE_LIST(V) \
V(ModuleLiteral) \
- V(ModuleVariable) \
V(ModulePath) \
V(ModuleUrl)
}
protected:
- ModuleDeclaration(Zone* zone,
- VariableProxy* proxy,
- Module* module,
- Scope* scope,
- int pos)
- : Declaration(zone, proxy, MODULE, scope, pos),
- module_(module) {
- }
+ ModuleDeclaration(Zone* zone, VariableProxy* proxy, Module* module,
+ Scope* scope, int pos)
+ : Declaration(zone, proxy, CONST, scope, pos), module_(module) {}
private:
Module* module_;
protected:
Module(Zone* zone, int pos)
: AstNode(pos),
- interface_(Interface::NewModule(zone)),
+ interface_(Interface::New(zone)),
body_(NULL) {}
Module(Zone* zone, Interface* interface, int pos, Block* body = NULL)
: AstNode(pos),
};
-class ModuleVariable FINAL : public Module {
- public:
- DECLARE_NODE_TYPE(ModuleVariable)
-
- VariableProxy* proxy() const { return proxy_; }
-
- protected:
- inline ModuleVariable(Zone* zone, VariableProxy* proxy, int pos);
-
- private:
- VariableProxy* proxy_;
-};
-
-
class ModulePath FINAL : public Module {
public:
DECLARE_NODE_TYPE(ModulePath)
public:
DECLARE_NODE_TYPE(ModuleStatement)
- VariableProxy* proxy() const { return proxy_; }
Block* body() const { return body_; }
protected:
- ModuleStatement(Zone* zone, VariableProxy* proxy, Block* body, int pos)
- : Statement(zone, pos),
- proxy_(proxy),
- body_(body) {
- }
+ ModuleStatement(Zone* zone, Block* body, int pos)
+ : Statement(zone, pos), body_(body) {}
private:
- VariableProxy* proxy_;
Block* body_;
};
bit_field_ = IsResolvedField::update(bit_field_, true);
}
- Interface* interface() const { return interface_; }
-
- // Bind this proxy to the variable var. Interfaces must match.
+ // Bind this proxy to the variable var.
void BindTo(Variable* var);
bool UsesVariableFeedbackSlot() const {
VariableProxy(Zone* zone, Variable* var, int position);
VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
- Interface* interface, int position);
+ int position);
class IsThisField : public BitField8<bool, 0, 1> {};
class IsAssignedField : public BitField8<bool, 1, 1> {};
const AstRawString* raw_name_; // if !is_resolved_
Variable* var_; // if is_resolved_
};
- Interface* interface_;
};
};
-// ----------------------------------------------------------------------------
-// Out-of-line inline constructors (to side-step cyclic dependencies).
-
-inline ModuleVariable::ModuleVariable(Zone* zone, VariableProxy* proxy, int pos)
- : Module(zone, proxy->interface(), pos),
- proxy_(proxy) {
-}
-
-
// ----------------------------------------------------------------------------
// Basic visitor
// - leaf node visitors are abstract.
return new (zone_) ModuleLiteral(zone_, body, interface, pos);
}
- ModuleVariable* NewModuleVariable(VariableProxy* proxy, int pos) {
- return new (zone_) ModuleVariable(zone_, proxy, pos);
- }
-
ModulePath* NewModulePath(Module* origin, const AstRawString* name, int pos) {
return new (zone_) ModulePath(zone_, origin, name, pos);
}
return NULL;
}
- ModuleStatement* NewModuleStatement(
- VariableProxy* proxy, Block* body, int pos) {
- return new (zone_) ModuleStatement(zone_, proxy, body, pos);
+ ModuleStatement* NewModuleStatement(Block* body, int pos) {
+ return new (zone_) ModuleStatement(zone_, body, pos);
}
ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
VariableProxy* NewVariableProxy(const AstRawString* name,
bool is_this,
- Interface* interface = Interface::NewValue(),
int position = RelocInfo::kNoPosition) {
- return new (zone_) VariableProxy(zone_, name, is_this, interface, position);
+ return new (zone_) VariableProxy(zone_, name, is_this, position);
}
Property* NewProperty(Expression* obj, Expression* key, int pos) {
void AstGraphBuilder::VisitModuleLiteral(ModuleLiteral* modl) { UNREACHABLE(); }
-void AstGraphBuilder::VisitModuleVariable(ModuleVariable* modl) {
- UNREACHABLE();
-}
-
-
void AstGraphBuilder::VisitModulePath(ModulePath* modl) { UNREACHABLE(); }
void ALAA::VisitModuleDeclaration(ModuleDeclaration* leaf) {}
void ALAA::VisitImportDeclaration(ImportDeclaration* leaf) {}
void ALAA::VisitExportDeclaration(ExportDeclaration* leaf) {}
-void ALAA::VisitModuleVariable(ModuleVariable* leaf) {}
void ALAA::VisitModulePath(ModulePath* leaf) {}
void ALAA::VisitModuleUrl(ModuleUrl* leaf) {}
void ALAA::VisitEmptyStatement(EmptyStatement* leaf) {}
// -- Interesting nodes-------------------------------------------------------
// ---------------------------------------------------------------------------
void ALAA::VisitModuleStatement(ModuleStatement* stmt) {
- Visit(stmt->body());
// TODO(turbofan): can a module appear in a loop?
- AnalyzeAssignment(stmt->proxy()->var());
+ Visit(stmt->body());
}
? IMMUTABLE_CHECK_INITIALIZED_HARMONY
: IMMUTABLE_IS_INITIALIZED_HARMONY;
break;
- case MODULE:
- *attributes = READ_ONLY;
- *binding_flags = IMMUTABLE_IS_INITIALIZED_HARMONY;
- break;
case DYNAMIC:
case DYNAMIC_GLOBAL:
case DYNAMIC_LOCAL:
}
-void BreakableStatementChecker::VisitModuleVariable(ModuleVariable* module) {
-}
-
-
void BreakableStatementChecker::VisitModulePath(ModulePath* module) {
}
Comment cmnt(masm_, "[ Link nested modules");
Scope* scope = module->body()->scope();
Interface* interface = scope->interface();
- DCHECK(interface->IsModule() && interface->IsFrozen());
+ DCHECK(interface->IsFrozen());
interface->Allocate(scope->module_var()->index());
}
-void FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) {
- // Nothing to do.
- // The instance object is resolved statically through the module's interface.
-}
-
-
void FullCodeGenerator::VisitModulePath(ModulePath* module) {
// Nothing to do.
// The instance object is resolved statically through the module's interface.
Scope* scope = module->body()->scope();
Interface* interface = scope_->interface();
- DCHECK(interface->IsModule() && interface->IsFrozen());
+ DCHECK(interface->IsFrozen());
DCHECK(!modules_.is_null());
DCHECK(module_index_ < modules_->length());
interface->Allocate(scope->module_var()->index());
void FullCodeGenerator::VisitModuleStatement(ModuleStatement* stmt) {
Comment cmnt(masm_, "[ Module context");
- __ Push(Smi::FromInt(stmt->proxy()->interface()->Index()));
+ DCHECK(stmt->body()->scope()->is_module_scope());
+
+ __ Push(Smi::FromInt(stmt->body()->scope()->interface()->Index()));
__ Push(Smi::FromInt(0));
__ CallRuntime(Runtime::kPushModuleContext, 2);
StoreToFrameField(
CONST_LEGACY, // declared via legacy 'const' declarations
- LET, // declared via 'let' declarations (first lexical)
+ LET, // declared via 'let' declarations
CONST, // declared via 'const' declarations
- MODULE, // declared via 'module' declaration (last lexical)
-
// Variables introduced by the compiler:
INTERNAL, // like VAR, but not user-visible (may or may not
// be in a context)
inline bool IsDeclaredVariableMode(VariableMode mode) {
- return mode >= VAR && mode <= MODULE;
+ return mode >= VAR && mode <= CONST;
}
inline bool IsLexicalVariableMode(VariableMode mode) {
- return mode >= LET && mode <= MODULE;
+ return mode == LET || mode == CONST;
}
inline bool IsImmutableVariableMode(VariableMode mode) {
- return (mode >= CONST && mode <= MODULE) || mode == CONST_LEGACY;
+ return mode == CONST || mode == CONST_LEGACY;
}
}
-void HOptimizedGraphBuilder::VisitModuleVariable(ModuleVariable* module) {
- UNREACHABLE();
-}
-
-
void HOptimizedGraphBuilder::VisitModulePath(ModulePath* module) {
UNREACHABLE();
}
void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = declaration->proxy()->var();
+ Interface* interface = declaration->module()->interface();
DCHECK(variable->location() == Variable::CONTEXT);
- DCHECK(variable->interface()->IsFrozen());
+ DCHECK(interface->IsFrozen());
Comment cmnt(masm_, "[ ModuleDeclaration");
EmitDebugCheckDeclarationContext(variable);
// Load instance object.
__ LoadContext(eax, scope_->ContextChainLength(scope_->ScriptScope()));
- __ mov(eax, ContextOperand(eax, variable->interface()->Index()));
+ __ mov(eax, ContextOperand(eax, interface->Index()));
__ mov(eax, ContextOperand(eax, Context::EXTENSION_INDEX));
// Assign it.
#include "src/interface.h"
-#include "src/base/lazy-instance.h"
+#include "src/ast-value-factory.h"
namespace v8 {
namespace internal {
-// ---------------------------------------------------------------------------
-// Initialization.
-
-struct Interface::Cache {
- template<int flags>
- struct Create {
- static void Construct(Interface* ptr) { ::new (ptr) Interface(flags); }
- };
- typedef Create<VALUE + FROZEN> ValueCreate;
- typedef Create<VALUE + CONST + FROZEN> ConstCreate;
-
- static base::LazyInstance<Interface, ValueCreate>::type value_interface;
- static base::LazyInstance<Interface, ConstCreate>::type const_interface;
-};
-
-
-base::LazyInstance<Interface, Interface::Cache::ValueCreate>::type
- Interface::Cache::value_interface = LAZY_INSTANCE_INITIALIZER;
-
-base::LazyInstance<Interface, Interface::Cache::ConstCreate>::type
- Interface::Cache::const_interface = LAZY_INSTANCE_INITIALIZER;
-
-
-Interface* Interface::NewValue() {
- return Cache::value_interface.Pointer(); // Cached.
-}
-
-
-Interface* Interface::NewConst() {
- return Cache::const_interface.Pointer(); // Cached.
-}
-
-
-// ---------------------------------------------------------------------------
-// Lookup.
-
-Interface* Interface::Lookup(Handle<String> name, Zone* zone) {
- DCHECK(IsModule());
- ZoneHashMap* map = Chase()->exports_;
- if (map == nullptr) return nullptr;
- ZoneAllocationPolicy allocator(zone);
- ZoneHashMap::Entry* p =
- map->Lookup(name.location(), name->Hash(), false, allocator);
- if (p == nullptr) return nullptr;
- DCHECK(*static_cast<String**>(p->key) == *name);
- DCHECK(p->value != nullptr);
- return static_cast<Interface*>(p->value);
-}
-
-
// ---------------------------------------------------------------------------
// Addition.
#endif
-void Interface::DoAdd(const void* name, uint32_t hash, Interface* interface,
- Zone* zone, bool* ok) {
- MakeModule(ok);
- if (!*ok) return;
+void Interface::Add(const AstRawString* name, Zone* zone, bool* ok) {
+ void* key = const_cast<AstRawString*>(name);
#ifdef DEBUG
if (FLAG_print_interface_details) {
PrintF("%*s# Adding...\n", Nesting::current(), "");
PrintF("%*sthis = ", Nesting::current(), "");
this->Print(Nesting::current());
- const AstRawString* raw = static_cast<const AstRawString*>(name);
- PrintF("%*s%.*s : ", Nesting::current(), "",
- raw->length(), raw->raw_data());
- interface->Print(Nesting::current());
+ PrintF("%*s%.*s : ", Nesting::current(), "", name->length(),
+ name->raw_data());
}
#endif
- ZoneHashMap** map = &Chase()->exports_;
+ ZoneHashMap** map = &exports_;
ZoneAllocationPolicy allocator(zone);
if (*map == nullptr) {
}
ZoneHashMap::Entry* p =
- (*map)->Lookup(const_cast<void*>(name), hash, !IsFrozen(), allocator);
- if (p == nullptr) {
- // This didn't have name but was frozen already, that's an error.
+ (*map)->Lookup(key, name->hash(), !IsFrozen(), allocator);
+ if (p == nullptr || p->value != nullptr) {
*ok = false;
- } else if (p->value == nullptr) {
- p->value = interface;
- } else {
-#ifdef DEBUG
- Nesting nested;
-#endif
- static_cast<Interface*>(p->value)->Unify(interface, zone, ok);
- }
-
-#ifdef DEBUG
- if (FLAG_print_interface_details) {
- PrintF("%*sthis' = ", Nesting::current(), "");
- this->Print(Nesting::current());
- PrintF("%*s# Added.\n", Nesting::current(), "");
- }
-#endif
-}
-
-
-// ---------------------------------------------------------------------------
-// Unification.
-
-void Interface::Unify(Interface* that, Zone* zone, bool* ok) {
- if (this->forward_) return this->Chase()->Unify(that, zone, ok);
- if (that->forward_) return this->Unify(that->Chase(), zone, ok);
- DCHECK(this->forward_ == nullptr);
- DCHECK(that->forward_ == nullptr);
-
- *ok = true;
- if (this == that) return;
- if (this->IsValue()) {
- that->MakeValue(ok);
- if (*ok && this->IsConst()) that->MakeConst(ok);
- return;
- }
- if (that->IsValue()) {
- this->MakeValue(ok);
- if (*ok && that->IsConst()) this->MakeConst(ok);
- return;
}
-#ifdef DEBUG
- if (FLAG_print_interface_details) {
- PrintF("%*s# Unifying...\n", Nesting::current(), "");
- PrintF("%*sthis = ", Nesting::current(), "");
- this->Print(Nesting::current());
- PrintF("%*sthat = ", Nesting::current(), "");
- that->Print(Nesting::current());
- }
-#endif
-
- // Merge the smaller interface into the larger, for performance.
- if (this->exports_ != nullptr && (that->exports_ == nullptr ||
- this->exports_->occupancy() >= that->exports_->occupancy())) {
- this->DoUnify(that, ok, zone);
- } else {
- that->DoUnify(this, ok, zone);
- }
+ p->value = key;
#ifdef DEBUG
if (FLAG_print_interface_details) {
PrintF("%*sthis' = ", Nesting::current(), "");
this->Print(Nesting::current());
- PrintF("%*sthat' = ", Nesting::current(), "");
- that->Print(Nesting::current());
- PrintF("%*s# Unified.\n", Nesting::current(), "");
+ PrintF("%*s# Added.\n", Nesting::current(), "");
}
#endif
}
-void Interface::DoUnify(Interface* that, bool* ok, Zone* zone) {
- DCHECK(this->forward_ == nullptr);
- DCHECK(that->forward_ == nullptr);
- DCHECK(!this->IsValue());
- DCHECK(!that->IsValue());
- DCHECK(this->index_ == -1);
- DCHECK(that->index_ == -1);
- DCHECK(*ok);
-
-#ifdef DEBUG
- Nesting nested;
-#endif
-
- // Try to merge all members from that into this.
- ZoneHashMap* map = that->exports_;
- if (map != nullptr) {
- for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
- this->DoAdd(p->key, p->hash, static_cast<Interface*>(p->value), zone, ok);
- if (!*ok) return;
- }
- }
-
- // If the new interface is larger than that's, then there were members in
- // 'this' which 'that' didn't have. If 'that' was frozen that is an error.
- int this_size = this->exports_ == nullptr ? 0 : this->exports_->occupancy();
- int that_size = map == nullptr ? 0 : map->occupancy();
- if (that->IsFrozen() && this_size > that_size) {
- *ok = false;
- return;
- }
-
- // Merge interfaces.
- this->flags_ |= that->flags_;
- that->forward_ = this;
-}
-
-
// ---------------------------------------------------------------------------
// Printing.
int n0 = n > 0 ? n : 0;
if (FLAG_print_interface_details) {
- PrintF("%p", static_cast<void*>(this));
- for (Interface* link = this->forward_; link != nullptr;
- link = link->forward_) {
- PrintF("->%p", static_cast<void*>(link));
- }
- PrintF(" ");
+ PrintF("%p ", static_cast<void*>(this));
}
- if (IsUnknown()) {
- PrintF("unknown\n");
- } else if (IsConst()) {
- PrintF("const\n");
- } else if (IsValue()) {
- PrintF("value\n");
- } else if (IsModule()) {
- PrintF("module %d %s{", Index(), IsFrozen() ? "" : "(unresolved) ");
- ZoneHashMap* map = Chase()->exports_;
- if (map == nullptr || map->occupancy() == 0) {
- PrintF("}\n");
- } else if (n < 0 || n0 >= 2 * FLAG_print_interface_depth) {
- // Avoid infinite recursion on cyclic types.
- PrintF("...}\n");
- } else {
- PrintF("\n");
- for (ZoneHashMap::Entry* p = map->Start();
- p != nullptr; p = map->Next(p)) {
- String* name = *static_cast<String**>(p->key);
- Interface* interface = static_cast<Interface*>(p->value);
- PrintF("%*s%s : ", n0 + 2, "", name->ToAsciiArray());
- interface->Print(n0 + 2);
- }
- PrintF("%*s}\n", n0, "");
+ PrintF("module %d %s{", Index(), IsFrozen() ? "" : "(unresolved) ");
+ ZoneHashMap* map = exports_;
+ if (map == nullptr || map->occupancy() == 0) {
+ PrintF("}\n");
+ } else if (n < 0 || n0 >= 2 * FLAG_print_interface_depth) {
+ // Avoid infinite recursion on cyclic types.
+ PrintF("...}\n");
+ } else {
+ PrintF("\n");
+ for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
+ String* name = *static_cast<String**>(p->key);
+ PrintF("%*s%s : ", n0 + 2, "", name->ToAsciiArray());
}
+ PrintF("%*s}\n", n0, "");
}
}
#endif
#ifndef V8_INTERFACE_H_
#define V8_INTERFACE_H_
-#include "src/ast-value-factory.h"
+#include "src/zone.h"
namespace v8 {
namespace internal {
-// This class implements the following abstract grammar of interfaces
-// (i.e. module types):
-// interface ::= UNDETERMINED | VALUE | CONST | MODULE(exports)
-// exports ::= {name : interface, ...}
-// A frozen type is one that is fully determined. Unification does not
-// allow to turn non-const values into const, or adding additional exports to
-// frozen interfaces. Otherwise, unifying modules merges their exports.
-// Undetermined types are unification variables that can be unified freely.
-// There is a natural subsort lattice that reflects the increase of knowledge:
-//
-// undetermined
-// // | \\ .
-// value (frozen) module
-// // \\ / \ //
-// const fr.value fr.module
-// \\ /
-// fr.const
-//
-// where the bold lines are the only transitions allowed.
+class AstRawString;
+
+// This class represents the interface of a module: a set of exported names.
+//
+// TODO(adamk): Rename this to ModuleRecord, ModuleDescriptor, or similar.
class Interface : public ZoneObject {
public:
// ---------------------------------------------------------------------------
// Factory methods.
- static Interface* NewUnknown(Zone* zone) {
- return new(zone) Interface(NONE);
- }
-
- static Interface* NewValue();
-
- static Interface* NewConst();
-
- static Interface* NewModule(Zone* zone) {
- return new(zone) Interface(MODULE);
- }
+ static Interface* New(Zone* zone) { return new (zone) Interface(); }
// ---------------------------------------------------------------------------
// Mutators.
- // Add a name to the list of exports. If it already exists, unify with
- // interface, otherwise insert unless this is closed.
- void Add(const AstRawString* name, Interface* interface, Zone* zone,
- bool* ok) {
- DoAdd(name, name->hash(), interface, zone, ok);
- }
-
- // Unify with another interface. If successful, both interface objects will
- // represent the same type, and changes to one are reflected in the other.
- void Unify(Interface* that, Zone* zone, bool* ok);
-
- // Determine this interface to be a value interface.
- void MakeValue(bool* ok) {
- *ok = !IsModule();
- if (*ok) Chase()->flags_ |= VALUE;
- }
-
- // Determine this interface to be an immutable interface.
- void MakeConst(bool* ok) {
- *ok = !IsModule() && (IsConst() || !IsFrozen());
- if (*ok) Chase()->flags_ |= VALUE + CONST;
- }
-
- // Determine this interface to be a module interface.
- void MakeModule(bool* ok) {
- *ok = !IsValue();
- if (*ok) Chase()->flags_ |= MODULE;
- }
+ // Add a name to the list of exports. If it already exists, or this interface
+ // is frozen, that's an error.
+ void Add(const AstRawString* name, Zone* zone, bool* ok);
// Do not allow any further refinements, directly or through unification.
- void Freeze(bool* ok) {
- *ok = IsValue() || IsModule();
- if (*ok) Chase()->flags_ |= FROZEN;
- }
+ void Freeze() { frozen_ = true; }
// Assign an index.
void Allocate(int index) {
- DCHECK(IsModule() && IsFrozen() && Chase()->index_ == -1);
- Chase()->index_ = index;
+ DCHECK(IsFrozen() && index_ == -1);
+ index_ = index;
}
// ---------------------------------------------------------------------------
// Accessors.
- // Check whether this is still a fully undetermined type.
- bool IsUnknown() { return Chase()->flags_ == NONE; }
-
- // Check whether this is a value type.
- bool IsValue() { return Chase()->flags_ & VALUE; }
-
- // Check whether this is a constant type.
- bool IsConst() { return Chase()->flags_ & CONST; }
-
- // Check whether this is a module type.
- bool IsModule() { return Chase()->flags_ & MODULE; }
-
// Check whether this is closed (i.e. fully determined).
- bool IsFrozen() { return Chase()->flags_ & FROZEN; }
-
- bool IsUnified(Interface* that) {
- return Chase() == that->Chase()
- || (this->IsValue() == that->IsValue() &&
- this->IsConst() == that->IsConst());
- }
+ bool IsFrozen() { return frozen_; }
int Length() {
- DCHECK(IsModule() && IsFrozen());
- ZoneHashMap* exports = Chase()->exports_;
+ DCHECK(IsFrozen());
+ ZoneHashMap* exports = exports_;
return exports ? exports->occupancy() : 0;
}
// The context slot in the hosting script context pointing to this module.
int Index() {
- DCHECK(IsModule() && IsFrozen());
- return Chase()->index_;
+ DCHECK(IsFrozen());
+ return index_;
}
- // Look up an exported name. Returns NULL if not (yet) defined.
- Interface* Lookup(Handle<String> name, Zone* zone);
-
// ---------------------------------------------------------------------------
// Iterators.
DCHECK(!done());
return static_cast<const AstRawString*>(entry_->key);
}
- Interface* interface() const {
- DCHECK(!done());
- return static_cast<Interface*>(entry_->value);
- }
void Advance() { entry_ = exports_->Next(entry_); }
private:
// ---------------------------------------------------------------------------
// Implementation.
private:
- struct Cache;
-
- enum Flags { // All flags are monotonic
- NONE = 0,
- VALUE = 1, // This type describes a value
- CONST = 2, // This type describes a constant
- MODULE = 4, // This type describes a module
- FROZEN = 8 // This type is fully determined
- };
-
- int flags_;
- Interface* forward_; // Unification link
+ bool frozen_;
ZoneHashMap* exports_; // Module exports and their types (allocated lazily)
int index_;
- explicit Interface(int flags)
- : flags_(flags),
- forward_(NULL),
- exports_(NULL),
- index_(-1) {
+ Interface() : frozen_(false), exports_(NULL), index_(-1) {
#ifdef DEBUG
if (FLAG_print_interface_details)
PrintF("# Creating %p\n", static_cast<void*>(this));
#endif
}
-
- Interface* Chase() {
- Interface* result = this;
- while (result->forward_ != NULL) result = result->forward_;
- if (result != this) forward_ = result; // On-the-fly path compression.
- return result;
- }
-
- void DoAdd(const void* name, uint32_t hash, Interface* interface, Zone* zone,
- bool* ok);
- void DoUnify(Interface* that, bool* ok, Zone* zone);
};
} } // namespace v8::internal
symbol_to_primitive: ["Cannot convert a Symbol wrapper object to a primitive value"],
symbol_to_number: ["Cannot convert a Symbol value to a number"],
invalid_module_path: ["Module does not export '", "%0", "', or export is not itself a module"],
- module_type_error: ["Module '", "%0", "' used improperly"],
module_export_undefined: ["Export '", "%0", "' is not defined in module"],
unexpected_super: ["'super' keyword unexpected here"],
extends_value_not_a_function: ["Class extends value ", "%0", " is not a function or null"],
void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = declaration->proxy()->var();
+ Interface* interface = declaration->module()->interface();
DCHECK(variable->location() == Variable::CONTEXT);
- DCHECK(variable->interface()->IsFrozen());
+ DCHECK(interface->IsFrozen());
Comment cmnt(masm_, "[ ModuleDeclaration");
EmitDebugCheckDeclarationContext(variable);
// Load instance object.
__ LoadContext(a1, scope_->ContextChainLength(scope_->ScriptScope()));
- __ lw(a1, ContextOperand(a1, variable->interface()->Index()));
+ __ lw(a1, ContextOperand(a1, interface->Index()));
__ lw(a1, ContextOperand(a1, Context::EXTENSION_INDEX));
// Assign it.
void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = declaration->proxy()->var();
+ Interface* interface = declaration->module()->interface();
DCHECK(variable->location() == Variable::CONTEXT);
- DCHECK(variable->interface()->IsFrozen());
+ DCHECK(interface->IsFrozen());
Comment cmnt(masm_, "[ ModuleDeclaration");
EmitDebugCheckDeclarationContext(variable);
// Load instance object.
__ LoadContext(a1, scope_->ContextChainLength(scope_->ScriptScope()));
- __ ld(a1, ContextOperand(a1, variable->interface()->Index()));
+ __ ld(a1, ContextOperand(a1, interface->Index()));
__ ld(a1, ContextOperand(a1, Context::EXTENSION_INDEX));
// Assign it.
int pos, Scope* scope,
AstNodeFactory* factory) {
if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
- // The name may refer to a module instance object, so its type is unknown.
-#ifdef DEBUG
- if (FLAG_print_interface_details)
- PrintF("# Variable %.*s ", name->length(), name->raw_data());
-#endif
- Interface* interface = Interface::NewUnknown(parser_->zone());
// Arrow function parameters are parsed as an expression. When
// parsing lazily, it is enough to create a VariableProxy in order
// for Traits::DeclareArrowParametersFromExpression() to be able to
// pick the names of the parameters.
return parser_->parsing_lazy_arrow_parameters_
- ? factory->NewVariableProxy(name, false, interface, pos)
- : scope->NewUnresolved(factory, name, interface, pos);
+ ? factory->NewVariableProxy(name, false, pos)
+ : scope->NewUnresolved(factory, name, pos);
}
}
}
- interface->MakeModule(ok);
- DCHECK(*ok);
- interface->Freeze(ok);
- DCHECK(*ok);
+ scope->interface()->Freeze();
return body;
}
if (FLAG_print_interface_details)
PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data());
#endif
- Interface* inner = Interface::NewUnknown(zone());
- interface->Add(names[i], inner, zone(), CHECK_OK);
- if (!*ok) return NULL;
- VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
- USE(proxy);
+ // TODO(adamk): Make early errors here provide the right error message
+ // (duplicate exported names).
+ interface->Add(names[i], zone(), CHECK_OK);
// TODO(rossberg): Rethink whether we actually need to store export
// declarations (for compilation?).
// ExportDeclaration* declaration =
VariableProxy* Parser::NewUnresolved(const AstRawString* name,
- VariableMode mode, Interface* interface) {
+ VariableMode mode) {
// If we are inside a function, a declaration of a var/const variable is a
// truly local variable, and the scope of the variable is always the function
// scope.
// Let/const variables in harmony mode are always added to the immediately
// enclosing scope.
- return DeclarationScope(mode)->NewUnresolved(
- factory(), name, interface, position());
+ return DeclarationScope(mode)->NewUnresolved(factory(), name, position());
}
var = declaration_scope->LookupLocal(name);
if (var == NULL) {
// Declare the name.
- var = declaration_scope->DeclareLocal(name, mode,
- declaration->initialization(),
- kNotAssigned, proxy->interface());
+ var = declaration_scope->DeclareLocal(
+ name, mode, declaration->initialization(), kNotAssigned);
} else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())
|| ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
!declaration_scope->is_script_scope())) {
// For global const variables we bind the proxy to a variable.
DCHECK(resolve); // should be set by all callers
Variable::Kind kind = Variable::NORMAL;
- var = new (zone())
- Variable(declaration_scope, name, mode, true, kind,
- kNeedsInitialization, kNotAssigned, proxy->interface());
+ var = new (zone()) Variable(declaration_scope, name, mode, true, kind,
+ kNeedsInitialization, kNotAssigned);
} else if (declaration_scope->is_eval_scope() &&
is_sloppy(declaration_scope->language_mode())) {
// For variable declarations in a sloppy eval scope the proxy is bound
Variable::Kind kind = Variable::NORMAL;
// TODO(sigurds) figure out if kNotAssigned is OK here
var = new (zone()) Variable(declaration_scope, name, mode, true, kind,
- declaration->initialization(), kNotAssigned,
- proxy->interface());
+ declaration->initialization(), kNotAssigned);
var->AllocateTo(Variable::LOOKUP, -1);
resolve = true;
}
// runtime needs to provide both.
if (resolve && var != NULL) {
proxy->BindTo(var);
-
- if (FLAG_harmony_modules) {
- bool ok;
-#ifdef DEBUG
- if (FLAG_print_interface_details) {
- PrintF("# Declare %.*s ", var->raw_name()->length(),
- var->raw_name()->raw_data());
- }
-#endif
- proxy->interface()->Unify(var->interface(), zone(), &ok);
- if (!ok) {
-#ifdef DEBUG
- if (FLAG_print_interfaces) {
- PrintF("DECLARE TYPE ERROR\n");
- PrintF("proxy: ");
- proxy->interface()->Print();
- PrintF("var: ");
- var->interface()->Print();
- }
-#endif
- ParserTraits::ReportMessage("module_type_error", name);
- }
- }
}
}
// TODO(1240846): It's weird that native function declarations are
// introduced dynamically when we meet their declarations, whereas
// other functions are set up when entering the surrounding scope.
- VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue());
+ VariableProxy* proxy = NewUnresolved(name, VAR);
Declaration* declaration =
factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
Declare(declaration, true, CHECK_OK);
scope_->is_function_scope())
? LET
: VAR;
- VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
+ VariableProxy* proxy = NewUnresolved(name, mode);
Declaration* declaration =
factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
Declare(declaration, true, CHECK_OK);
ClassLiteral* value = ParseClassLiteral(name, scanner()->location(),
is_strict_reserved, pos, CHECK_OK);
- VariableProxy* proxy = NewUnresolved(name, LET, Interface::NewValue());
+ VariableProxy* proxy = NewUnresolved(name, LET);
Declaration* declaration =
factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
Declare(declaration, true, CHECK_OK);
needs_init = false;
}
- Interface* interface =
- is_const ? Interface::NewConst() : Interface::NewValue();
- VariableProxy* proxy = NewUnresolved(name, mode, interface);
+ VariableProxy* proxy = NewUnresolved(name, mode);
Declaration* declaration =
factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
Declare(declaration, mode != VAR, CHECK_OK);
// if they are inside a 'with' statement - they may change a 'with' object
// property).
VariableProxy* proxy =
- initialization_scope->NewUnresolved(factory(), name, interface);
+ initialization_scope->NewUnresolved(factory(), name);
Assignment* assignment =
factory()->NewAssignment(init_op, proxy, value, pos);
block->AddStatement(
// For each let variable x:
// make statement: temp_x = x.
for (int i = 0; i < names->length(); i++) {
- VariableProxy* proxy =
- NewUnresolved(names->at(i), LET, Interface::NewValue());
+ VariableProxy* proxy = NewUnresolved(names->at(i), LET);
Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name);
VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
Assignment* assignment = factory()->NewAssignment(
// For each let variable x:
// make statement: let x = temp_x.
for (int i = 0; i < names->length(); i++) {
- VariableProxy* proxy =
- NewUnresolved(names->at(i), LET, Interface::NewValue());
+ VariableProxy* proxy = NewUnresolved(names->at(i), LET);
Declaration* declaration =
factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
Declare(declaration, true, CHECK_OK);
if (peek() != Token::SEMICOLON) {
if (peek() == Token::VAR ||
(peek() == Token::CONST && is_sloppy(language_mode()))) {
- bool is_const = peek() == Token::CONST;
const AstRawString* name = NULL;
VariableDeclarationProperties decl_props = kHasNoInitializers;
Block* variable_statement =
int each_pos = position();
if (name != NULL && CheckInOrOf(accept_OF, &mode)) {
- Interface* interface =
- is_const ? Interface::NewConst() : Interface::NewValue();
ForEachStatement* loop =
factory()->NewForEachStatement(mode, labels, stmt_pos);
Target target(&this->target_stack_, loop);
Expression* enumerable = ParseExpression(true, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
- VariableProxy* each =
- scope_->NewUnresolved(factory(), name, interface, each_pos);
+ VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos);
Statement* body = ParseSubStatement(NULL, CHECK_OK);
InitializeForEachStatement(loop, each, enumerable, body);
Block* result =
scope_ = for_scope;
Expect(Token::RPAREN, CHECK_OK);
- VariableProxy* each = scope_->NewUnresolved(
- factory(), name, Interface::NewValue(), each_pos);
+ VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos);
Statement* body = ParseSubStatement(NULL, CHECK_OK);
Block* body_block =
factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
DCHECK(function_name != NULL);
fvar = new (zone())
Variable(scope_, function_name, fvar_mode, true /* is valid LHS */,
- Variable::NORMAL, kCreatedInitialized, kNotAssigned,
- Interface::NewConst());
+ Variable::NORMAL, kCreatedInitialized, kNotAssigned);
VariableProxy* proxy = factory()->NewVariableProxy(fvar);
VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone());
if (fvar != NULL) {
- VariableProxy* fproxy = scope_->NewUnresolved(
- factory(), function_name, Interface::NewConst());
+ VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name);
fproxy->BindTo(fvar);
body->Add(factory()->NewExpressionStatement(
factory()->NewAssignment(fvar_init_op,
VariableProxy* proxy = NULL;
if (name != NULL) {
- proxy = NewUnresolved(name, CONST, Interface::NewConst());
+ proxy = NewUnresolved(name, CONST);
Declaration* declaration =
factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos);
Declare(declaration, true, CHECK_OK);
void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
// Parser support
- VariableProxy* NewUnresolved(const AstRawString* name,
- VariableMode mode,
- Interface* interface);
+ VariableProxy* NewUnresolved(const AstRawString* name, VariableMode mode);
void Declare(Declaration* declaration, bool resolve, bool* ok);
bool TargetStackContainsLabel(const AstRawString* label);
void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = declaration->proxy()->var();
+ Interface* interface = declaration->module()->interface();
DCHECK(variable->location() == Variable::CONTEXT);
- DCHECK(variable->interface()->IsFrozen());
+ DCHECK(interface->IsFrozen());
Comment cmnt(masm_, "[ ModuleDeclaration");
EmitDebugCheckDeclarationContext(variable);
// Load instance object.
__ LoadContext(r4, scope_->ContextChainLength(scope_->ScriptScope()));
- __ LoadP(r4, ContextOperand(r4, variable->interface()->Index()));
+ __ LoadP(r4, ContextOperand(r4, interface->Index()));
__ LoadP(r4, ContextOperand(r4, Context::EXTENSION_INDEX));
// Assign it.
}
-void CallPrinter::VisitModuleVariable(ModuleVariable* node) {
- Find(node->proxy());
-}
-
-
void CallPrinter::VisitModulePath(ModulePath* node) { Find(node->module()); }
}
-void PrettyPrinter::VisitModuleVariable(ModuleVariable* node) {
- Visit(node->proxy());
-}
-
-
void PrettyPrinter::VisitModulePath(ModulePath* node) {
Visit(node->module());
Print(".");
void PrettyPrinter::VisitModuleStatement(ModuleStatement* node) {
Print("module ");
- PrintLiteral(node->proxy()->name(), false);
- Print(" ");
Visit(node->body());
}
}
-void AstPrinter::VisitModuleVariable(ModuleVariable* node) {
- IndentedScope indent(this, "MODULE VARIABLE");
- Visit(node->proxy());
-}
-
-
void AstPrinter::VisitModulePath(ModulePath* node) {
IndentedScope indent(this, "MODULE PATH");
PrintIndentedVisit("MODULE PATH PARENT", node->module());
void AstPrinter::VisitModuleStatement(ModuleStatement* node) {
IndentedScope indent(this, "MODULE STATEMENT");
- PrintLiteralIndented("NAME", node->proxy()->name(), true);
PrintStatements(node->body()->statements());
}
void Processor::VisitImportDeclaration(ImportDeclaration* node) {}
void Processor::VisitExportDeclaration(ExportDeclaration* node) {}
void Processor::VisitModuleLiteral(ModuleLiteral* node) {}
-void Processor::VisitModuleVariable(ModuleVariable* node) {}
void Processor::VisitModulePath(ModulePath* node) {}
void Processor::VisitModuleUrl(ModuleUrl* node) {}
void Processor::VisitEmptyStatement(EmptyStatement* node) {}
USE(result);
break;
}
- case MODULE: {
- Object* referenced_context = Context::cast(host_context)->get(index);
- Handle<JSModule> value(Context::cast(referenced_context)->module());
- JSObject::SetOwnPropertyIgnoreAttributes(module, name, value, FROZEN)
- .Assert();
- break;
- }
case INTERNAL:
case TEMPORARY:
case DYNAMIC:
Variable* var = scope->LookupLocal(it.name());
info->set_name(i, *(it.name()->string()));
info->set_mode(i, var->mode());
- DCHECK((var->mode() == MODULE) == (it.interface()->IsModule()));
- if (var->mode() == MODULE) {
- DCHECK(it.interface()->IsFrozen());
- DCHECK(it.interface()->Index() >= 0);
- info->set_index(i, it.interface()->Index());
- } else {
- DCHECK(var->index() >= 0);
- info->set_index(i, var->index());
- }
+ DCHECK(var->index() >= 0);
+ info->set_index(i, var->index());
}
DCHECK(i == info->length());
return info;
#define V8_SCOPEINFO_H_
#include "src/allocation.h"
+#include "src/interface.h"
#include "src/variables.h"
namespace v8 {
VariableMode mode, bool is_valid_lhs,
Variable::Kind kind,
InitializationFlag initialization_flag,
- MaybeAssignedFlag maybe_assigned_flag,
- Interface* interface) {
+ MaybeAssignedFlag maybe_assigned_flag) {
// AstRawStrings are unambiguous, i.e., the same string is always represented
// by the same AstRawString*.
// FIXME(marja): fix the type of Lookup.
if (p->value == NULL) {
// The variable has not been declared yet -> insert it.
DCHECK(p->key == name);
- p->value = new (zone())
- Variable(scope, name, mode, is_valid_lhs, kind, initialization_flag,
- maybe_assigned_flag, interface);
+ p->value = new (zone()) Variable(scope, name, mode, is_valid_lhs, kind,
+ initialization_flag, maybe_assigned_flag);
}
return reinterpret_cast<Variable*>(p->value);
}
params_(4, zone),
unresolved_(16, zone),
decls_(4, zone),
- interface_(scope_type == MODULE_SCOPE ? Interface::NewModule(zone)
+ interface_(scope_type == MODULE_SCOPE ? Interface::New(zone)
: NULL),
already_resolved_(false),
ast_value_factory_(ast_value_factory),
Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
InitializationFlag init_flag,
- MaybeAssignedFlag maybe_assigned_flag,
- Interface* interface) {
+ MaybeAssignedFlag maybe_assigned_flag) {
DCHECK(!already_resolved());
// This function handles VAR, LET, and CONST modes. DYNAMIC variables are
// introduces during variable allocation, INTERNAL variables are allocated
DCHECK(IsDeclaredVariableMode(mode));
++num_var_or_const_;
return variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag,
- maybe_assigned_flag, interface);
+ maybe_assigned_flag);
}
DCHECK(var != NULL);
if (proxy->is_assigned()) var->set_maybe_assigned();
- if (FLAG_harmony_modules) {
- bool ok;
-#ifdef DEBUG
- if (FLAG_print_interface_details) {
- PrintF("# Resolve %.*s:\n", var->raw_name()->length(),
- var->raw_name()->raw_data());
- }
-#endif
- proxy->interface()->Unify(var->interface(), zone(), &ok);
- if (!ok) {
-#ifdef DEBUG
- if (FLAG_print_interfaces) {
- PrintF("SCOPES TYPE ERROR\n");
- PrintF("proxy: ");
- proxy->interface()->Print();
- PrintF("var: ");
- var->interface()->Print();
- }
-#endif
-
- // Inconsistent use of module. Throw a syntax error.
- // TODO(rossberg): generate more helpful error message.
- MessageLocation location(
- info->script(), proxy->position(), proxy->position());
- Isolate* isolate = info->isolate();
- Factory* factory = isolate->factory();
- Handle<JSArray> array = factory->NewJSArray(1);
- JSObject::SetElement(array, 0, var->name(), NONE, STRICT).Assert();
- Handle<Object> error;
- MaybeHandle<Object> maybe_error =
- factory->NewSyntaxError("module_type_error", array);
- if (maybe_error.ToHandle(&error)) isolate->Throw(*error, &location);
- return false;
- }
- }
-
proxy->BindTo(var);
return true;
Variable* Declare(Scope* scope, const AstRawString* name, VariableMode mode,
bool is_valid_lhs, Variable::Kind kind,
InitializationFlag initialization_flag,
- MaybeAssignedFlag maybe_assigned_flag = kNotAssigned,
- Interface* interface = Interface::NewValue());
+ MaybeAssignedFlag maybe_assigned_flag = kNotAssigned);
Variable* Lookup(const AstRawString* name);
// declared before, the previously declared variable is returned.
Variable* DeclareLocal(const AstRawString* name, VariableMode mode,
InitializationFlag init_flag,
- MaybeAssignedFlag maybe_assigned_flag = kNotAssigned,
- Interface* interface = Interface::NewValue());
+ MaybeAssignedFlag maybe_assigned_flag = kNotAssigned);
// Declare an implicit global variable in this scope which must be a
// script scope. The variable was introduced (possibly from an inner
// Create a new unresolved variable.
VariableProxy* NewUnresolved(AstNodeFactory* factory,
const AstRawString* name,
- Interface* interface = Interface::NewValue(),
int position = RelocInfo::kNoPosition) {
// Note that we must not share the unresolved variables with
// the same name because they may be removed selectively via
// RemoveUnresolved().
DCHECK(!already_resolved());
- VariableProxy* proxy =
- factory->NewVariableProxy(name, false, interface, position);
+ VariableProxy* proxy = factory->NewVariableProxy(name, false, position);
unresolved_.Add(proxy, zone_);
return proxy;
}
}
-void AstTyper::VisitModuleVariable(ModuleVariable* module) {
-}
-
-
void AstTyper::VisitModulePath(ModulePath* module) {
RECURSE(Visit(module->module()));
}
case CONST_LEGACY: return "CONST_LEGACY";
case LET: return "LET";
case CONST: return "CONST";
- case MODULE: return "MODULE";
case DYNAMIC: return "DYNAMIC";
case DYNAMIC_GLOBAL: return "DYNAMIC_GLOBAL";
case DYNAMIC_LOCAL: return "DYNAMIC_LOCAL";
Variable::Variable(Scope* scope, const AstRawString* name, VariableMode mode,
bool is_valid_ref, Kind kind,
InitializationFlag initialization_flag,
- MaybeAssignedFlag maybe_assigned_flag, Interface* interface)
+ MaybeAssignedFlag maybe_assigned_flag)
: scope_(scope),
name_(name),
mode_(mode),
force_context_allocation_(false),
is_used_(false),
initialization_flag_(initialization_flag),
- maybe_assigned_(maybe_assigned_flag),
- interface_(interface) {
+ maybe_assigned_(maybe_assigned_flag) {
// Var declared variables never need initialization.
DCHECK(!(mode == VAR && initialization_flag == kNeedsInitialization));
}
#define V8_VARIABLES_H_
#include "src/ast-value-factory.h"
-#include "src/interface.h"
#include "src/zone.h"
namespace v8 {
Variable(Scope* scope, const AstRawString* name, VariableMode mode,
bool is_valid_ref, Kind kind, InitializationFlag initialization_flag,
- MaybeAssignedFlag maybe_assigned_flag = kNotAssigned,
- Interface* interface = Interface::NewValue());
+ MaybeAssignedFlag maybe_assigned_flag = kNotAssigned);
// Printing support
static const char* Mode2String(VariableMode mode);
InitializationFlag initialization_flag() const {
return initialization_flag_;
}
- Interface* interface() const { return interface_; }
void AllocateTo(Location location, int index) {
location_ = location;
bool is_used_;
InitializationFlag initialization_flag_;
MaybeAssignedFlag maybe_assigned_;
-
- // Module type info.
- Interface* interface_;
};
void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = declaration->proxy()->var();
+ Interface* interface = declaration->module()->interface();
DCHECK(variable->location() == Variable::CONTEXT);
- DCHECK(variable->interface()->IsFrozen());
+ DCHECK(interface->IsFrozen());
Comment cmnt(masm_, "[ ModuleDeclaration");
EmitDebugCheckDeclarationContext(variable);
// Load instance object.
__ LoadContext(rax, scope_->ContextChainLength(scope_->ScriptScope()));
- __ movp(rax, ContextOperand(rax, variable->interface()->Index()));
+ __ movp(rax, ContextOperand(rax, interface->Index()));
__ movp(rax, ContextOperand(rax, Context::EXTENSION_INDEX));
// Assign it.
void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = declaration->proxy()->var();
+ Interface* interface = declaration->module()->interface();
DCHECK(variable->location() == Variable::CONTEXT);
- DCHECK(variable->interface()->IsFrozen());
+ DCHECK(interface->IsFrozen());
Comment cmnt(masm_, "[ ModuleDeclaration");
EmitDebugCheckDeclarationContext(variable);
// Load instance object.
__ LoadContext(eax, scope_->ContextChainLength(scope_->ScriptScope()));
- __ mov(eax, ContextOperand(eax, variable->interface()->Index()));
+ __ mov(eax, ContextOperand(eax, interface->Index()));
__ mov(eax, ContextOperand(eax, Context::EXTENSION_INDEX));
// Assign it.
"export { for as foo }",
"export { arguments }",
"export { arguments as foo }",
+ "var a; export { a, a };",
"import from;",
"import from 'm.js';",