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 |