Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 11 matching lines...) Expand all Loading... | |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "scopes.h" | 30 #include "scopes.h" |
| 31 | 31 |
| 32 #include "accessors.h" | |
| 32 #include "bootstrapper.h" | 33 #include "bootstrapper.h" |
| 33 #include "compiler.h" | 34 #include "compiler.h" |
| 34 #include "messages.h" | 35 #include "messages.h" |
| 35 #include "scopeinfo.h" | 36 #include "scopeinfo.h" |
| 36 | 37 |
| 37 #include "allocation-inl.h" | 38 #include "allocation-inl.h" |
| 38 | 39 |
| 39 namespace v8 { | 40 namespace v8 { |
| 40 namespace internal { | 41 namespace internal { |
| 41 | 42 |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 Scope* with_scope = new(zone) Scope(current_scope, | 220 Scope* with_scope = new(zone) Scope(current_scope, |
| 220 WITH_SCOPE, | 221 WITH_SCOPE, |
| 221 Handle<ScopeInfo>::null(), | 222 Handle<ScopeInfo>::null(), |
| 222 zone); | 223 zone); |
| 223 current_scope = with_scope; | 224 current_scope = with_scope; |
| 224 // All the inner scopes are inside a with. | 225 // All the inner scopes are inside a with. |
| 225 contains_with = true; | 226 contains_with = true; |
| 226 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { | 227 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { |
| 227 s->scope_inside_with_ = true; | 228 s->scope_inside_with_ = true; |
| 228 } | 229 } |
| 230 } else if (context->IsModuleContext()) { | |
| 231 ScopeInfo* scope_info = ScopeInfo::cast(context->module()->scope_info()); | |
| 232 current_scope = new(zone) Scope(current_scope, | |
| 233 MODULE_SCOPE, | |
| 234 Handle<ScopeInfo>(scope_info), | |
| 235 zone); | |
| 229 } else if (context->IsFunctionContext()) { | 236 } else if (context->IsFunctionContext()) { |
| 230 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); | 237 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
| 231 current_scope = new(zone) Scope(current_scope, | 238 current_scope = new(zone) Scope(current_scope, |
| 232 FUNCTION_SCOPE, | 239 FUNCTION_SCOPE, |
| 233 Handle<ScopeInfo>(scope_info), | 240 Handle<ScopeInfo>(scope_info), |
| 234 zone); | 241 zone); |
| 235 } else if (context->IsBlockContext()) { | 242 } else if (context->IsBlockContext()) { |
| 236 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); | 243 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); |
| 237 current_scope = new(zone) Scope(current_scope, | 244 current_scope = new(zone) Scope(current_scope, |
| 238 BLOCK_SCOPE, | 245 BLOCK_SCOPE, |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 627 outer_scope_->calls_non_strict_eval(); | 634 outer_scope_->calls_non_strict_eval(); |
| 628 } | 635 } |
| 629 PropagateScopeInfo(outer_scope_calls_non_strict_eval); | 636 PropagateScopeInfo(outer_scope_calls_non_strict_eval); |
| 630 | 637 |
| 631 // 2) Resolve variables. | 638 // 2) Resolve variables. |
| 632 if (!ResolveVariablesRecursively(info, factory)) return false; | 639 if (!ResolveVariablesRecursively(info, factory)) return false; |
| 633 | 640 |
| 634 // 3) Allocate variables. | 641 // 3) Allocate variables. |
| 635 AllocateVariablesRecursively(); | 642 AllocateVariablesRecursively(); |
| 636 | 643 |
| 644 // 4) Allocate and link module instance objects. | |
| 645 if (FLAG_harmony_modules) { | |
| 646 if (is_global_scope() || is_module_scope()) { | |
|
Michael Starzinger
2012/07/06 10:53:22
Can we merge that into one condition?
rossberg
2012/07/06 15:39:28
Done.
| |
| 647 AllocateModules(info); | |
| 648 LinkModules(info); | |
| 649 } | |
| 650 } | |
| 651 | |
| 637 return true; | 652 return true; |
| 638 } | 653 } |
| 639 | 654 |
| 640 | 655 |
| 641 bool Scope::HasTrivialContext() const { | 656 bool Scope::HasTrivialContext() const { |
| 642 // A function scope has a trivial context if it always is the global | 657 // A function scope has a trivial context if it always is the global |
| 643 // context. We iteratively scan out the context chain to see if | 658 // context. We iteratively scan out the context chain to see if |
| 644 // there is anything that makes this scope non-trivial; otherwise we | 659 // there is anything that makes this scope non-trivial; otherwise we |
| 645 // return true. | 660 // return true. |
| 646 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { | 661 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1104 bool Scope::MustAllocate(Variable* var) { | 1119 bool Scope::MustAllocate(Variable* var) { |
| 1105 // Give var a read/write use if there is a chance it might be accessed | 1120 // Give var a read/write use if there is a chance it might be accessed |
| 1106 // via an eval() call. This is only possible if the variable has a | 1121 // via an eval() call. This is only possible if the variable has a |
| 1107 // visible name. | 1122 // visible name. |
| 1108 if ((var->is_this() || var->name()->length() > 0) && | 1123 if ((var->is_this() || var->name()->length() > 0) && |
| 1109 (var->has_forced_context_allocation() || | 1124 (var->has_forced_context_allocation() || |
| 1110 scope_calls_eval_ || | 1125 scope_calls_eval_ || |
| 1111 inner_scope_calls_eval_ || | 1126 inner_scope_calls_eval_ || |
| 1112 scope_contains_with_ || | 1127 scope_contains_with_ || |
| 1113 is_catch_scope() || | 1128 is_catch_scope() || |
| 1114 is_block_scope())) { | 1129 is_block_scope() || |
| 1130 is_module_scope())) { | |
| 1115 var->set_is_used(true); | 1131 var->set_is_used(true); |
| 1116 } | 1132 } |
| 1117 // Global variables do not need to be allocated. | 1133 // Global variables do not need to be allocated. |
| 1118 return !var->is_global() && var->is_used(); | 1134 return !var->is_global() && var->is_used(); |
| 1119 } | 1135 } |
| 1120 | 1136 |
| 1121 | 1137 |
| 1122 bool Scope::MustAllocateInContext(Variable* var) { | 1138 bool Scope::MustAllocateInContext(Variable* var) { |
| 1123 // If var is accessed from an inner scope, or if there is a possibility | 1139 // If var is accessed from an inner scope, or if there is a possibility |
| 1124 // that it might be accessed from the current or an inner scope (through | 1140 // that it might be accessed from the current or an inner scope (through |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1292 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1308 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); |
| 1293 } | 1309 } |
| 1294 | 1310 |
| 1295 | 1311 |
| 1296 int Scope::ContextLocalCount() const { | 1312 int Scope::ContextLocalCount() const { |
| 1297 if (num_heap_slots() == 0) return 0; | 1313 if (num_heap_slots() == 0) return 0; |
| 1298 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1314 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 1299 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1315 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
| 1300 } | 1316 } |
| 1301 | 1317 |
| 1318 | |
| 1319 void Scope::AllocateModules(CompilationInfo* info) { | |
| 1320 ASSERT(is_global_scope() || is_module_scope()); | |
| 1321 | |
| 1322 if (is_module_scope()) { | |
| 1323 ASSERT(interface_->IsFrozen()); | |
| 1324 ASSERT(scope_info_.is_null()); | |
| 1325 | |
| 1326 // TODO(rossberg): This has to be the initial compilation of this code. | |
| 1327 // We currently do not allow recompiling any module definitions. | |
| 1328 Handle<ScopeInfo> scope_info = GetScopeInfo(); | |
| 1329 Factory* factory = info->isolate()->factory(); | |
| 1330 Handle<Context> context = factory->NewModuleContext(scope_info); | |
| 1331 Handle<JSModule> instance = factory->NewJSModule(context, scope_info); | |
| 1332 context->set_module(*instance); | |
| 1333 | |
| 1334 bool ok; | |
| 1335 interface_->MakeSingleton(instance, &ok); | |
| 1336 ASSERT(ok); | |
| 1337 } | |
| 1338 | |
| 1339 // Allocate nested modules. | |
| 1340 for (int i = 0; i < inner_scopes_.length(); i++) { | |
| 1341 Scope* inner_scope = inner_scopes_.at(i); | |
| 1342 if (inner_scope->is_module_scope()) { | |
| 1343 inner_scope->AllocateModules(info); | |
| 1344 } | |
| 1345 } | |
| 1346 } | |
| 1347 | |
| 1348 | |
| 1349 void Scope::LinkModules(CompilationInfo* info) { | |
| 1350 ASSERT(is_global_scope() || is_module_scope()); | |
| 1351 | |
| 1352 if (is_module_scope()) { | |
| 1353 Handle<JSModule> instance = interface_->Instance(); | |
| 1354 | |
| 1355 // Populate the module instance object. | |
| 1356 const PropertyAttributes ro_attr = | |
| 1357 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE | DONT_ENUM); | |
| 1358 const PropertyAttributes rw_attr = | |
| 1359 static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM); | |
| 1360 for (Interface::Iterator it = interface_->iterator(); | |
| 1361 !it.done(); it.Advance()) { | |
| 1362 if (it.interface()->IsModule()) { | |
| 1363 Handle<Object> value = it.interface()->Instance(); | |
| 1364 ASSERT(!value.is_null()); | |
| 1365 JSReceiver::SetProperty( | |
| 1366 instance, it.name(), value, ro_attr, kStrictMode); | |
| 1367 } else { | |
| 1368 Variable* var = LocalLookup(it.name()); | |
| 1369 ASSERT(var != NULL && var->IsContextSlot()); | |
| 1370 PropertyAttributes attr = var->is_const_mode() ? ro_attr : rw_attr; | |
| 1371 Handle<AccessorInfo> info = | |
| 1372 Accessors::MakeModuleExport(it.name(), var->index(), attr); | |
| 1373 Handle<Object> result = SetAccessor(instance, info); | |
| 1374 ASSERT(!(result.is_null() || result->IsUndefined())); | |
| 1375 } | |
| 1376 } | |
| 1377 USE(instance->PreventExtensions()); | |
|
Michael Starzinger
2012/07/06 10:53:22
This might request a GC, so you should use JSObjec
rossberg
2012/07/06 15:39:28
Done.
| |
| 1378 } | |
| 1379 | |
| 1380 // Link nested modules. | |
| 1381 for (int i = 0; i < inner_scopes_.length(); i++) { | |
| 1382 Scope* inner_scope = inner_scopes_.at(i); | |
| 1383 if (inner_scope->is_module_scope()) { | |
| 1384 inner_scope->LinkModules(info); | |
| 1385 } | |
| 1386 } | |
| 1387 } | |
| 1388 | |
| 1389 | |
| 1302 } } // namespace v8::internal | 1390 } } // namespace v8::internal |
| OLD | NEW |