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 && (is_global_scope() || is_module_scope())) { | |
646 AllocateModules(info); | |
647 LinkModules(info); | |
648 } | |
649 | |
637 return true; | 650 return true; |
638 } | 651 } |
639 | 652 |
640 | 653 |
641 bool Scope::HasTrivialContext() const { | 654 bool Scope::HasTrivialContext() const { |
642 // A function scope has a trivial context if it always is the global | 655 // 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 | 656 // context. We iteratively scan out the context chain to see if |
644 // there is anything that makes this scope non-trivial; otherwise we | 657 // there is anything that makes this scope non-trivial; otherwise we |
645 // return true. | 658 // return true. |
646 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { | 659 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) { | 1117 bool Scope::MustAllocate(Variable* var) { |
1105 // Give var a read/write use if there is a chance it might be accessed | 1118 // 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 | 1119 // via an eval() call. This is only possible if the variable has a |
1107 // visible name. | 1120 // visible name. |
1108 if ((var->is_this() || var->name()->length() > 0) && | 1121 if ((var->is_this() || var->name()->length() > 0) && |
1109 (var->has_forced_context_allocation() || | 1122 (var->has_forced_context_allocation() || |
1110 scope_calls_eval_ || | 1123 scope_calls_eval_ || |
1111 inner_scope_calls_eval_ || | 1124 inner_scope_calls_eval_ || |
1112 scope_contains_with_ || | 1125 scope_contains_with_ || |
1113 is_catch_scope() || | 1126 is_catch_scope() || |
1114 is_block_scope())) { | 1127 is_block_scope() || |
1128 is_module_scope())) { | |
1115 var->set_is_used(true); | 1129 var->set_is_used(true); |
1116 } | 1130 } |
1117 // Global variables do not need to be allocated. | 1131 // Global variables do not need to be allocated. |
1118 return !var->is_global() && var->is_used(); | 1132 return !var->is_global() && var->is_used(); |
1119 } | 1133 } |
1120 | 1134 |
1121 | 1135 |
1122 bool Scope::MustAllocateInContext(Variable* var) { | 1136 bool Scope::MustAllocateInContext(Variable* var) { |
1123 // If var is accessed from an inner scope, or if there is a possibility | 1137 // 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 | 1138 // 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); | 1306 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); |
1293 } | 1307 } |
1294 | 1308 |
1295 | 1309 |
1296 int Scope::ContextLocalCount() const { | 1310 int Scope::ContextLocalCount() const { |
1297 if (num_heap_slots() == 0) return 0; | 1311 if (num_heap_slots() == 0) return 0; |
1298 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1312 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1299 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1313 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
1300 } | 1314 } |
1301 | 1315 |
1316 | |
1317 void Scope::AllocateModules(CompilationInfo* info) { | |
1318 ASSERT(is_global_scope() || is_module_scope()); | |
1319 | |
1320 if (is_module_scope()) { | |
1321 ASSERT(interface_->IsFrozen()); | |
1322 ASSERT(scope_info_.is_null()); | |
1323 | |
1324 // TODO(rossberg): This has to be the initial compilation of this code. | |
1325 // We currently do not allow recompiling any module definitions. | |
1326 Handle<ScopeInfo> scope_info = GetScopeInfo(); | |
1327 Factory* factory = info->isolate()->factory(); | |
1328 Handle<Context> context = factory->NewModuleContext(scope_info); | |
1329 Handle<JSModule> instance = factory->NewJSModule(context, scope_info); | |
1330 context->set_module(*instance); | |
1331 | |
1332 bool ok; | |
1333 interface_->MakeSingleton(instance, &ok); | |
1334 ASSERT(ok); | |
1335 } | |
1336 | |
1337 // Allocate nested modules. | |
1338 for (int i = 0; i < inner_scopes_.length(); i++) { | |
1339 Scope* inner_scope = inner_scopes_.at(i); | |
1340 if (inner_scope->is_module_scope()) { | |
1341 inner_scope->AllocateModules(info); | |
1342 } | |
1343 } | |
1344 } | |
1345 | |
1346 | |
1347 void Scope::LinkModules(CompilationInfo* info) { | |
1348 ASSERT(is_global_scope() || is_module_scope()); | |
1349 | |
1350 if (is_module_scope()) { | |
1351 Handle<JSModule> instance = interface_->Instance(); | |
1352 | |
1353 // Populate the module instance object. | |
1354 const PropertyAttributes ro_attr = | |
1355 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE | DONT_ENUM); | |
1356 const PropertyAttributes rw_attr = | |
1357 static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM); | |
1358 for (Interface::Iterator it = interface_->iterator(); | |
1359 !it.done(); it.Advance()) { | |
1360 if (it.interface()->IsModule()) { | |
1361 Handle<Object> value = it.interface()->Instance(); | |
1362 ASSERT(!value.is_null()); | |
1363 JSReceiver::SetProperty( | |
1364 instance, it.name(), value, ro_attr, kStrictMode); | |
1365 } else { | |
1366 Variable* var = LocalLookup(it.name()); | |
1367 ASSERT(var != NULL && var->IsContextSlot()); | |
1368 PropertyAttributes attr = var->is_const_mode() ? ro_attr : rw_attr; | |
1369 Handle<AccessorInfo> info = | |
1370 Accessors::MakeModuleExport(it.name(), var->index(), attr); | |
1371 Handle<Object> result = SetAccessor(instance, info); | |
Jakob Kummerow
2012/07/09 11:03:12
unused variable (in release mode).
| |
1372 ASSERT(!(result.is_null() || result->IsUndefined())); | |
1373 } | |
1374 } | |
1375 USE(JSObject::PreventExtensions(instance)); | |
1376 } | |
1377 | |
1378 // Link nested modules. | |
1379 for (int i = 0; i < inner_scopes_.length(); i++) { | |
1380 Scope* inner_scope = inner_scopes_.at(i); | |
1381 if (inner_scope->is_module_scope()) { | |
1382 inner_scope->LinkModules(info); | |
1383 } | |
1384 } | |
1385 } | |
1386 | |
1387 | |
1302 } } // namespace v8::internal | 1388 } } // namespace v8::internal |
OLD | NEW |