Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: src/scopes.cc

Issue 9615009: Basic interface inference for modules. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Eps. Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/scopes.h ('k') | src/variables.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 VariableMap::VariableMap() : ZoneHashMap(Match, 8) {} 60 VariableMap::VariableMap() : ZoneHashMap(Match, 8) {}
61 VariableMap::~VariableMap() {} 61 VariableMap::~VariableMap() {}
62 62
63 63
64 Variable* VariableMap::Declare( 64 Variable* VariableMap::Declare(
65 Scope* scope, 65 Scope* scope,
66 Handle<String> name, 66 Handle<String> name,
67 VariableMode mode, 67 VariableMode mode,
68 bool is_valid_lhs, 68 bool is_valid_lhs,
69 Variable::Kind kind, 69 Variable::Kind kind,
70 InitializationFlag initialization_flag) { 70 InitializationFlag initialization_flag,
71 Interface* interface) {
71 Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), true); 72 Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), true);
72 if (p->value == NULL) { 73 if (p->value == NULL) {
73 // The variable has not been declared yet -> insert it. 74 // The variable has not been declared yet -> insert it.
74 ASSERT(p->key == name.location()); 75 ASSERT(p->key == name.location());
75 p->value = new Variable(scope, 76 p->value = new Variable(scope,
76 name, 77 name,
77 mode, 78 mode,
78 is_valid_lhs, 79 is_valid_lhs,
79 kind, 80 kind,
80 initialization_flag); 81 initialization_flag,
82 interface);
81 } 83 }
82 return reinterpret_cast<Variable*>(p->value); 84 return reinterpret_cast<Variable*>(p->value);
83 } 85 }
84 86
85 87
86 Variable* VariableMap::Lookup(Handle<String> name) { 88 Variable* VariableMap::Lookup(Handle<String> name) {
87 Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), false); 89 Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), false);
88 if (p != NULL) { 90 if (p != NULL) {
89 ASSERT(*reinterpret_cast<String**>(p->key) == *name); 91 ASSERT(*reinterpret_cast<String**>(p->key) == *name);
90 ASSERT(p->value != NULL); 92 ASSERT(p->value != NULL);
91 return reinterpret_cast<Variable*>(p->value); 93 return reinterpret_cast<Variable*>(p->value);
92 } 94 }
93 return NULL; 95 return NULL;
94 } 96 }
95 97
96 98
97 // ---------------------------------------------------------------------------- 99 // ----------------------------------------------------------------------------
98 // Implementation of Scope 100 // Implementation of Scope
99 101
100 Scope::Scope(Scope* outer_scope, ScopeType type) 102 Scope::Scope(Scope* outer_scope, ScopeType type)
101 : isolate_(Isolate::Current()), 103 : isolate_(Isolate::Current()),
102 inner_scopes_(4), 104 inner_scopes_(4),
103 variables_(), 105 variables_(),
104 temps_(4), 106 temps_(4),
105 params_(4), 107 params_(4),
106 unresolved_(16), 108 unresolved_(16),
107 decls_(4), 109 decls_(4),
110 interface_(FLAG_harmony_modules &&
111 (type == MODULE_SCOPE || type == GLOBAL_SCOPE)
112 ? Interface::NewModule() : NULL),
108 already_resolved_(false) { 113 already_resolved_(false) {
109 SetDefaults(type, outer_scope, Handle<ScopeInfo>::null()); 114 SetDefaults(type, outer_scope, Handle<ScopeInfo>::null());
110 // At some point we might want to provide outer scopes to 115 // At some point we might want to provide outer scopes to
111 // eval scopes (by walking the stack and reading the scope info). 116 // eval scopes (by walking the stack and reading the scope info).
112 // In that case, the ASSERT below needs to be adjusted. 117 // In that case, the ASSERT below needs to be adjusted.
113 ASSERT_EQ(type == GLOBAL_SCOPE, outer_scope == NULL); 118 ASSERT_EQ(type == GLOBAL_SCOPE, outer_scope == NULL);
114 ASSERT(!HasIllegalRedeclaration()); 119 ASSERT(!HasIllegalRedeclaration());
115 } 120 }
116 121
117 122
118 Scope::Scope(Scope* inner_scope, 123 Scope::Scope(Scope* inner_scope,
119 ScopeType type, 124 ScopeType type,
120 Handle<ScopeInfo> scope_info) 125 Handle<ScopeInfo> scope_info)
121 : isolate_(Isolate::Current()), 126 : isolate_(Isolate::Current()),
122 inner_scopes_(4), 127 inner_scopes_(4),
123 variables_(), 128 variables_(),
124 temps_(4), 129 temps_(4),
125 params_(4), 130 params_(4),
126 unresolved_(16), 131 unresolved_(16),
127 decls_(4), 132 decls_(4),
133 interface_(NULL),
128 already_resolved_(true) { 134 already_resolved_(true) {
129 SetDefaults(type, NULL, scope_info); 135 SetDefaults(type, NULL, scope_info);
130 if (!scope_info.is_null()) { 136 if (!scope_info.is_null()) {
131 num_heap_slots_ = scope_info_->ContextLength(); 137 num_heap_slots_ = scope_info_->ContextLength();
132 } 138 }
133 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. 139 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context.
134 num_heap_slots_ = Max(num_heap_slots_, 140 num_heap_slots_ = Max(num_heap_slots_,
135 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); 141 static_cast<int>(Context::MIN_CONTEXT_SLOTS));
136 AddInnerScope(inner_scope); 142 AddInnerScope(inner_scope);
137 } 143 }
138 144
139 145
140 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name) 146 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name)
141 : isolate_(Isolate::Current()), 147 : isolate_(Isolate::Current()),
142 inner_scopes_(1), 148 inner_scopes_(1),
143 variables_(), 149 variables_(),
144 temps_(0), 150 temps_(0),
145 params_(0), 151 params_(0),
146 unresolved_(0), 152 unresolved_(0),
147 decls_(0), 153 decls_(0),
154 interface_(NULL),
148 already_resolved_(true) { 155 already_resolved_(true) {
149 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); 156 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null());
150 AddInnerScope(inner_scope); 157 AddInnerScope(inner_scope);
151 ++num_var_or_const_; 158 ++num_var_or_const_;
152 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; 159 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
153 Variable* variable = variables_.Declare(this, 160 Variable* variable = variables_.Declare(this,
154 catch_variable_name, 161 catch_variable_name,
155 VAR, 162 VAR,
156 true, // Valid left-hand side. 163 true, // Valid left-hand side.
157 Variable::NORMAL, 164 Variable::NORMAL,
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 // Traverse the scope tree up to the first unresolved scope or the global 255 // Traverse the scope tree up to the first unresolved scope or the global
249 // scope and start scope resolution and variable allocation from that scope. 256 // scope and start scope resolution and variable allocation from that scope.
250 while (!top->is_global_scope() && 257 while (!top->is_global_scope() &&
251 !top->outer_scope()->already_resolved()) { 258 !top->outer_scope()->already_resolved()) {
252 top = top->outer_scope(); 259 top = top->outer_scope();
253 } 260 }
254 261
255 // Allocate the variables. 262 // Allocate the variables.
256 { 263 {
257 AstNodeFactory<AstNullVisitor> ast_node_factory(info->isolate()); 264 AstNodeFactory<AstNullVisitor> ast_node_factory(info->isolate());
258 top->AllocateVariables(info->global_scope(), &ast_node_factory); 265 if (!top->AllocateVariables(info, &ast_node_factory)) return false;
259 } 266 }
260 267
261 #ifdef DEBUG 268 #ifdef DEBUG
262 if (info->isolate()->bootstrapper()->IsActive() 269 if (info->isolate()->bootstrapper()->IsActive()
263 ? FLAG_print_builtin_scopes 270 ? FLAG_print_builtin_scopes
264 : FLAG_print_scopes) { 271 : FLAG_print_scopes) {
265 scope->Print(); 272 scope->Print();
266 } 273 }
274
275 if (FLAG_harmony_modules && FLAG_print_interfaces && top->is_global_scope()) {
276 PrintF("global : ");
277 top->interface()->Print();
278 }
267 #endif 279 #endif
268 280
269 if (FLAG_harmony_scoping) { 281 if (FLAG_harmony_scoping) {
270 VariableProxy* proxy = scope->CheckAssignmentToConst(); 282 VariableProxy* proxy = scope->CheckAssignmentToConst();
271 if (proxy != NULL) { 283 if (proxy != NULL) {
272 // Found an assignment to const. Throw a syntax error. 284 // Found an assignment to const. Throw a syntax error.
273 MessageLocation location(info->script(), 285 MessageLocation location(info->script(),
274 proxy->position(), 286 proxy->position(),
275 proxy->position()); 287 proxy->position());
276 Isolate* isolate = info->isolate(); 288 Isolate* isolate = info->isolate();
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 ASSERT(!already_resolved()); 443 ASSERT(!already_resolved());
432 ASSERT(is_function_scope()); 444 ASSERT(is_function_scope());
433 Variable* var = variables_.Declare( 445 Variable* var = variables_.Declare(
434 this, name, mode, true, Variable::NORMAL, kCreatedInitialized); 446 this, name, mode, true, Variable::NORMAL, kCreatedInitialized);
435 params_.Add(var); 447 params_.Add(var);
436 } 448 }
437 449
438 450
439 Variable* Scope::DeclareLocal(Handle<String> name, 451 Variable* Scope::DeclareLocal(Handle<String> name,
440 VariableMode mode, 452 VariableMode mode,
441 InitializationFlag init_flag) { 453 InitializationFlag init_flag,
454 Interface* interface) {
442 ASSERT(!already_resolved()); 455 ASSERT(!already_resolved());
443 // This function handles VAR and CONST modes. DYNAMIC variables are 456 // This function handles VAR and CONST modes. DYNAMIC variables are
444 // introduces during variable allocation, INTERNAL variables are allocated 457 // introduces during variable allocation, INTERNAL variables are allocated
445 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). 458 // explicitly, and TEMPORARY variables are allocated via NewTemporary().
446 ASSERT(mode == VAR || 459 ASSERT(mode == VAR ||
447 mode == CONST || 460 mode == CONST ||
448 mode == CONST_HARMONY || 461 mode == CONST_HARMONY ||
449 mode == LET); 462 mode == LET);
450 ++num_var_or_const_; 463 ++num_var_or_const_;
451 return 464 return variables_.Declare(
452 variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag); 465 this, name, mode, true, Variable::NORMAL, init_flag, interface);
453 } 466 }
454 467
455 468
456 Variable* Scope::DeclareGlobal(Handle<String> name) { 469 Variable* Scope::DeclareGlobal(Handle<String> name) {
457 ASSERT(is_global_scope()); 470 ASSERT(is_global_scope());
458 return variables_.Declare(this, 471 return variables_.Declare(this,
459 name, 472 name,
460 DYNAMIC_GLOBAL, 473 DYNAMIC_GLOBAL,
461 true, 474 true,
462 Variable::NORMAL, 475 Variable::NORMAL,
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 if (var->IsStackLocal()) { 592 if (var->IsStackLocal()) {
580 stack_locals->Add(var); 593 stack_locals->Add(var);
581 } else if (var->IsContextSlot()) { 594 } else if (var->IsContextSlot()) {
582 context_locals->Add(var); 595 context_locals->Add(var);
583 } 596 }
584 } 597 }
585 } 598 }
586 } 599 }
587 600
588 601
589 void Scope::AllocateVariables(Scope* global_scope, 602 bool Scope::AllocateVariables(CompilationInfo* info,
590 AstNodeFactory<AstNullVisitor>* factory) { 603 AstNodeFactory<AstNullVisitor>* factory) {
591 // 1) Propagate scope information. 604 // 1) Propagate scope information.
592 bool outer_scope_calls_non_strict_eval = false; 605 bool outer_scope_calls_non_strict_eval = false;
593 if (outer_scope_ != NULL) { 606 if (outer_scope_ != NULL) {
594 outer_scope_calls_non_strict_eval = 607 outer_scope_calls_non_strict_eval =
595 outer_scope_->outer_scope_calls_non_strict_eval() | 608 outer_scope_->outer_scope_calls_non_strict_eval() |
596 outer_scope_->calls_non_strict_eval(); 609 outer_scope_->calls_non_strict_eval();
597 } 610 }
598 PropagateScopeInfo(outer_scope_calls_non_strict_eval); 611 PropagateScopeInfo(outer_scope_calls_non_strict_eval);
599 612
600 // 2) Resolve variables. 613 // 2) Resolve variables.
601 ResolveVariablesRecursively(global_scope, factory); 614 if (!ResolveVariablesRecursively(info, factory)) return false;
602 615
603 // 3) Allocate variables. 616 // 3) Allocate variables.
604 AllocateVariablesRecursively(); 617 AllocateVariablesRecursively();
618
619 return true;
605 } 620 }
606 621
607 622
608 bool Scope::AllowsLazyCompilation() const { 623 bool Scope::AllowsLazyCompilation() const {
609 return !force_eager_compilation_ && HasTrivialOuterContext(); 624 return !force_eager_compilation_ && HasTrivialOuterContext();
610 } 625 }
611 626
612 627
613 bool Scope::HasTrivialContext() const { 628 bool Scope::HasTrivialContext() const {
614 // A function scope has a trivial context if it always is the global 629 // A function scope has a trivial context if it always is the global
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 if (*binding_kind == BOUND) { 924 if (*binding_kind == BOUND) {
910 *binding_kind = BOUND_EVAL_SHADOWED; 925 *binding_kind = BOUND_EVAL_SHADOWED;
911 } else if (*binding_kind == UNBOUND) { 926 } else if (*binding_kind == UNBOUND) {
912 *binding_kind = UNBOUND_EVAL_SHADOWED; 927 *binding_kind = UNBOUND_EVAL_SHADOWED;
913 } 928 }
914 } 929 }
915 return var; 930 return var;
916 } 931 }
917 932
918 933
919 void Scope::ResolveVariable(Scope* global_scope, 934 bool Scope::ResolveVariable(CompilationInfo* info,
920 VariableProxy* proxy, 935 VariableProxy* proxy,
921 AstNodeFactory<AstNullVisitor>* factory) { 936 AstNodeFactory<AstNullVisitor>* factory) {
922 ASSERT(global_scope == NULL || global_scope->is_global_scope()); 937 ASSERT(info->global_scope()->is_global_scope());
923 938
924 // If the proxy is already resolved there's nothing to do 939 // If the proxy is already resolved there's nothing to do
925 // (functions and consts may be resolved by the parser). 940 // (functions and consts may be resolved by the parser).
926 if (proxy->var() != NULL) return; 941 if (proxy->var() != NULL) return true;
927 942
928 // Otherwise, try to resolve the variable. 943 // Otherwise, try to resolve the variable.
929 BindingKind binding_kind; 944 BindingKind binding_kind;
930 Variable* var = LookupRecursive(proxy->name(), &binding_kind, factory); 945 Variable* var = LookupRecursive(proxy->name(), &binding_kind, factory);
931 switch (binding_kind) { 946 switch (binding_kind) {
932 case BOUND: 947 case BOUND:
933 // We found a variable binding. 948 // We found a variable binding.
934 break; 949 break;
935 950
936 case BOUND_EVAL_SHADOWED: 951 case BOUND_EVAL_SHADOWED:
937 // We found a variable variable binding that might be shadowed 952 // We found a variable variable binding that might be shadowed
938 // by 'eval' introduced variable bindings. 953 // by 'eval' introduced variable bindings.
939 if (var->is_global()) { 954 if (var->is_global()) {
940 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); 955 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
941 } else { 956 } else {
942 Variable* invalidated = var; 957 Variable* invalidated = var;
943 var = NonLocal(proxy->name(), DYNAMIC_LOCAL); 958 var = NonLocal(proxy->name(), DYNAMIC_LOCAL);
944 var->set_local_if_not_shadowed(invalidated); 959 var->set_local_if_not_shadowed(invalidated);
945 } 960 }
946 break; 961 break;
947 962
948 case UNBOUND: 963 case UNBOUND:
949 // No binding has been found. Declare a variable in global scope. 964 // No binding has been found. Declare a variable in global scope.
950 ASSERT(global_scope != NULL); 965 var = info->global_scope()->DeclareGlobal(proxy->name());
951 var = global_scope->DeclareGlobal(proxy->name());
952 break; 966 break;
953 967
954 case UNBOUND_EVAL_SHADOWED: 968 case UNBOUND_EVAL_SHADOWED:
955 // No binding has been found. But some scope makes a 969 // No binding has been found. But some scope makes a
956 // non-strict 'eval' call. 970 // non-strict 'eval' call.
957 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); 971 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
958 break; 972 break;
959 973
960 case DYNAMIC_LOOKUP: 974 case DYNAMIC_LOOKUP:
961 // The variable could not be resolved statically. 975 // The variable could not be resolved statically.
962 var = NonLocal(proxy->name(), DYNAMIC); 976 var = NonLocal(proxy->name(), DYNAMIC);
963 break; 977 break;
964 } 978 }
965 979
966 ASSERT(var != NULL); 980 ASSERT(var != NULL);
967 proxy->BindTo(var); 981 proxy->BindTo(var);
982
983 if (FLAG_harmony_modules) {
984 bool ok;
985 #ifdef DEBUG
986 if (FLAG_print_interface_details)
987 PrintF("# Resolve %s:\n", var->name()->ToAsciiArray());
988 #endif
989 proxy->interface()->Unify(var->interface(), &ok);
990 if (!ok) {
991 #ifdef DEBUG
992 if (FLAG_print_interfaces) {
993 PrintF("SCOPES TYPE ERROR\n");
994 PrintF("proxy: ");
995 proxy->interface()->Print();
996 PrintF("var: ");
997 var->interface()->Print();
998 }
999 #endif
1000
1001 // Inconsistent use of module. Throw a syntax error.
1002 // TODO(rossberg): generate more helpful error message.
1003 MessageLocation location(info->script(),
1004 proxy->position(),
1005 proxy->position());
1006 Isolate* isolate = Isolate::Current();
1007 Factory* factory = isolate->factory();
1008 Handle<JSArray> array = factory->NewJSArray(1);
1009 array->SetElement(array, 0, var->name(), NONE, kStrictMode);
1010 Handle<Object> result =
1011 factory->NewSyntaxError("module_type_error", array);
1012 isolate->Throw(*result, &location);
1013 return false;
1014 }
1015 }
1016
1017 return true;
968 } 1018 }
969 1019
970 1020
971 void Scope::ResolveVariablesRecursively( 1021 bool Scope::ResolveVariablesRecursively(
972 Scope* global_scope, 1022 CompilationInfo* info,
973 AstNodeFactory<AstNullVisitor>* factory) { 1023 AstNodeFactory<AstNullVisitor>* factory) {
974 ASSERT(global_scope == NULL || global_scope->is_global_scope()); 1024 ASSERT(info->global_scope()->is_global_scope());
975 1025
976 // Resolve unresolved variables for this scope. 1026 // Resolve unresolved variables for this scope.
977 for (int i = 0; i < unresolved_.length(); i++) { 1027 for (int i = 0; i < unresolved_.length(); i++) {
978 ResolveVariable(global_scope, unresolved_[i], factory); 1028 if (!ResolveVariable(info, unresolved_[i], factory)) return false;
979 } 1029 }
980 1030
981 // Resolve unresolved variables for inner scopes. 1031 // Resolve unresolved variables for inner scopes.
982 for (int i = 0; i < inner_scopes_.length(); i++) { 1032 for (int i = 0; i < inner_scopes_.length(); i++) {
983 inner_scopes_[i]->ResolveVariablesRecursively(global_scope, factory); 1033 if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory))
1034 return false;
984 } 1035 }
1036
1037 return true;
985 } 1038 }
986 1039
987 1040
988 bool Scope::PropagateScopeInfo(bool outer_scope_calls_non_strict_eval ) { 1041 bool Scope::PropagateScopeInfo(bool outer_scope_calls_non_strict_eval ) {
989 if (outer_scope_calls_non_strict_eval) { 1042 if (outer_scope_calls_non_strict_eval) {
990 outer_scope_calls_non_strict_eval_ = true; 1043 outer_scope_calls_non_strict_eval_ = true;
991 } 1044 }
992 1045
993 bool calls_non_strict_eval = 1046 bool calls_non_strict_eval =
994 this->calls_non_strict_eval() || outer_scope_calls_non_strict_eval_; 1047 this->calls_non_strict_eval() || outer_scope_calls_non_strict_eval_;
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 } 1250 }
1198 1251
1199 1252
1200 int Scope::ContextLocalCount() const { 1253 int Scope::ContextLocalCount() const {
1201 if (num_heap_slots() == 0) return 0; 1254 if (num_heap_slots() == 0) return 0;
1202 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - 1255 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
1203 (function_ != NULL && function_->var()->IsContextSlot() ? 1 : 0); 1256 (function_ != NULL && function_->var()->IsContextSlot() ? 1 : 0);
1204 } 1257 }
1205 1258
1206 } } // namespace v8::internal 1259 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scopes.h ('k') | src/variables.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698