| Index: src/scopes.cc
|
| diff --git a/src/scopes.cc b/src/scopes.cc
|
| index 8d71f8ae858d8b44937bea0e25dc69b379a60f7f..766e1ae5cccc7c5e42512cdaccdf2f634b1ca0aa 100644
|
| --- a/src/scopes.cc
|
| +++ b/src/scopes.cc
|
| @@ -67,7 +67,8 @@ Variable* VariableMap::Declare(
|
| VariableMode mode,
|
| bool is_valid_lhs,
|
| Variable::Kind kind,
|
| - InitializationFlag initialization_flag) {
|
| + InitializationFlag initialization_flag,
|
| + Interface* interface) {
|
| Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), true);
|
| if (p->value == NULL) {
|
| // The variable has not been declared yet -> insert it.
|
| @@ -77,7 +78,8 @@ Variable* VariableMap::Declare(
|
| mode,
|
| is_valid_lhs,
|
| kind,
|
| - initialization_flag);
|
| + initialization_flag,
|
| + interface);
|
| }
|
| return reinterpret_cast<Variable*>(p->value);
|
| }
|
| @@ -105,6 +107,9 @@ Scope::Scope(Scope* outer_scope, ScopeType type)
|
| params_(4),
|
| unresolved_(16),
|
| decls_(4),
|
| + interface_(FLAG_harmony_modules &&
|
| + (type == MODULE_SCOPE || type == GLOBAL_SCOPE)
|
| + ? Interface::NewModule() : NULL),
|
| already_resolved_(false) {
|
| SetDefaults(type, outer_scope, Handle<ScopeInfo>::null());
|
| // At some point we might want to provide outer scopes to
|
| @@ -125,6 +130,7 @@ Scope::Scope(Scope* inner_scope,
|
| params_(4),
|
| unresolved_(16),
|
| decls_(4),
|
| + interface_(NULL),
|
| already_resolved_(true) {
|
| SetDefaults(type, NULL, scope_info);
|
| if (!scope_info.is_null()) {
|
| @@ -145,6 +151,7 @@ Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name)
|
| params_(0),
|
| unresolved_(0),
|
| decls_(0),
|
| + interface_(NULL),
|
| already_resolved_(true) {
|
| SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null());
|
| AddInnerScope(inner_scope);
|
| @@ -255,7 +262,7 @@ bool Scope::Analyze(CompilationInfo* info) {
|
| // Allocate the variables.
|
| {
|
| AstNodeFactory<AstNullVisitor> ast_node_factory(info->isolate());
|
| - top->AllocateVariables(info->global_scope(), &ast_node_factory);
|
| + if (!top->AllocateVariables(info, &ast_node_factory)) return false;
|
| }
|
|
|
| #ifdef DEBUG
|
| @@ -264,6 +271,11 @@ bool Scope::Analyze(CompilationInfo* info) {
|
| : FLAG_print_scopes) {
|
| scope->Print();
|
| }
|
| +
|
| + if (FLAG_harmony_modules && FLAG_print_interfaces && top->is_global_scope()) {
|
| + PrintF("global : ");
|
| + top->interface()->Print();
|
| + }
|
| #endif
|
|
|
| if (FLAG_harmony_scoping) {
|
| @@ -438,7 +450,8 @@ void Scope::DeclareParameter(Handle<String> name, VariableMode mode) {
|
|
|
| Variable* Scope::DeclareLocal(Handle<String> name,
|
| VariableMode mode,
|
| - InitializationFlag init_flag) {
|
| + InitializationFlag init_flag,
|
| + Interface* interface) {
|
| ASSERT(!already_resolved());
|
| // This function handles VAR and CONST modes. DYNAMIC variables are
|
| // introduces during variable allocation, INTERNAL variables are allocated
|
| @@ -448,8 +461,8 @@ Variable* Scope::DeclareLocal(Handle<String> name,
|
| mode == CONST_HARMONY ||
|
| mode == LET);
|
| ++num_var_or_const_;
|
| - return
|
| - variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag);
|
| + return variables_.Declare(
|
| + this, name, mode, true, Variable::NORMAL, init_flag, interface);
|
| }
|
|
|
|
|
| @@ -586,7 +599,7 @@ void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals,
|
| }
|
|
|
|
|
| -void Scope::AllocateVariables(Scope* global_scope,
|
| +bool Scope::AllocateVariables(CompilationInfo* info,
|
| AstNodeFactory<AstNullVisitor>* factory) {
|
| // 1) Propagate scope information.
|
| bool outer_scope_calls_non_strict_eval = false;
|
| @@ -598,10 +611,12 @@ void Scope::AllocateVariables(Scope* global_scope,
|
| PropagateScopeInfo(outer_scope_calls_non_strict_eval);
|
|
|
| // 2) Resolve variables.
|
| - ResolveVariablesRecursively(global_scope, factory);
|
| + if (!ResolveVariablesRecursively(info, factory)) return false;
|
|
|
| // 3) Allocate variables.
|
| AllocateVariablesRecursively();
|
| +
|
| + return true;
|
| }
|
|
|
|
|
| @@ -916,14 +931,14 @@ Variable* Scope::LookupRecursive(Handle<String> name,
|
| }
|
|
|
|
|
| -void Scope::ResolveVariable(Scope* global_scope,
|
| +bool Scope::ResolveVariable(CompilationInfo* info,
|
| VariableProxy* proxy,
|
| AstNodeFactory<AstNullVisitor>* factory) {
|
| - ASSERT(global_scope == NULL || global_scope->is_global_scope());
|
| + ASSERT(info->global_scope()->is_global_scope());
|
|
|
| // If the proxy is already resolved there's nothing to do
|
| // (functions and consts may be resolved by the parser).
|
| - if (proxy->var() != NULL) return;
|
| + if (proxy->var() != NULL) return true;
|
|
|
| // Otherwise, try to resolve the variable.
|
| BindingKind binding_kind;
|
| @@ -947,8 +962,7 @@ void Scope::ResolveVariable(Scope* global_scope,
|
|
|
| case UNBOUND:
|
| // No binding has been found. Declare a variable in global scope.
|
| - ASSERT(global_scope != NULL);
|
| - var = global_scope->DeclareGlobal(proxy->name());
|
| + var = info->global_scope()->DeclareGlobal(proxy->name());
|
| break;
|
|
|
| case UNBOUND_EVAL_SHADOWED:
|
| @@ -965,23 +979,62 @@ void Scope::ResolveVariable(Scope* global_scope,
|
|
|
| ASSERT(var != NULL);
|
| proxy->BindTo(var);
|
| +
|
| + if (FLAG_harmony_modules) {
|
| + bool ok;
|
| +#ifdef DEBUG
|
| + if (FLAG_print_interface_details)
|
| + PrintF("# Resolve %s:\n", var->name()->ToAsciiArray());
|
| +#endif
|
| + proxy->interface()->Unify(var->interface(), &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 = Isolate::Current();
|
| + Factory* factory = isolate->factory();
|
| + Handle<JSArray> array = factory->NewJSArray(1);
|
| + array->SetElement(array, 0, var->name(), NONE, kStrictMode);
|
| + Handle<Object> result =
|
| + factory->NewSyntaxError("module_type_error", array);
|
| + isolate->Throw(*result, &location);
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + return true;
|
| }
|
|
|
|
|
| -void Scope::ResolveVariablesRecursively(
|
| - Scope* global_scope,
|
| +bool Scope::ResolveVariablesRecursively(
|
| + CompilationInfo* info,
|
| AstNodeFactory<AstNullVisitor>* factory) {
|
| - ASSERT(global_scope == NULL || global_scope->is_global_scope());
|
| + ASSERT(info->global_scope()->is_global_scope());
|
|
|
| // Resolve unresolved variables for this scope.
|
| for (int i = 0; i < unresolved_.length(); i++) {
|
| - ResolveVariable(global_scope, unresolved_[i], factory);
|
| + if (!ResolveVariable(info, unresolved_[i], factory)) return false;
|
| }
|
|
|
| // Resolve unresolved variables for inner scopes.
|
| for (int i = 0; i < inner_scopes_.length(); i++) {
|
| - inner_scopes_[i]->ResolveVariablesRecursively(global_scope, factory);
|
| + if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory))
|
| + return false;
|
| }
|
| +
|
| + return true;
|
| }
|
|
|
|
|
|
|