OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/messages.h" | 9 #include "src/messages.h" |
10 #include "src/parser.h" | 10 #include "src/parser.h" |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 | 147 |
148 | 148 |
149 void Scope::SetDefaults(ScopeType scope_type, Scope* outer_scope, | 149 void Scope::SetDefaults(ScopeType scope_type, Scope* outer_scope, |
150 Handle<ScopeInfo> scope_info, | 150 Handle<ScopeInfo> scope_info, |
151 FunctionKind function_kind) { | 151 FunctionKind function_kind) { |
152 outer_scope_ = outer_scope; | 152 outer_scope_ = outer_scope; |
153 scope_type_ = scope_type; | 153 scope_type_ = scope_type; |
154 function_kind_ = function_kind; | 154 function_kind_ = function_kind; |
155 block_scope_is_class_scope_ = false; | 155 block_scope_is_class_scope_ = false; |
156 scope_name_ = ast_value_factory_->empty_string(); | 156 scope_name_ = ast_value_factory_->empty_string(); |
157 dynamics_ = NULL; | 157 dynamics_ = nullptr; |
158 receiver_ = NULL; | 158 receiver_ = nullptr; |
159 new_target_ = nullptr; | 159 new_target_ = nullptr; |
160 function_ = NULL; | 160 function_ = nullptr; |
161 arguments_ = NULL; | 161 arguments_ = nullptr; |
162 illegal_redecl_ = NULL; | 162 home_object_ = nullptr; |
| 163 illegal_redecl_ = nullptr; |
163 scope_inside_with_ = false; | 164 scope_inside_with_ = false; |
164 scope_contains_with_ = false; | 165 scope_contains_with_ = false; |
165 scope_calls_eval_ = false; | 166 scope_calls_eval_ = false; |
166 scope_uses_arguments_ = false; | 167 scope_uses_arguments_ = false; |
167 scope_uses_super_property_ = false; | 168 scope_uses_super_property_ = false; |
168 asm_module_ = false; | 169 asm_module_ = false; |
169 asm_function_ = outer_scope != NULL && outer_scope->asm_module_; | 170 asm_function_ = outer_scope != NULL && outer_scope->asm_module_; |
170 // Inherit the language mode from the parent scope. | 171 // Inherit the language mode from the parent scope. |
171 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY; | 172 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY; |
172 outer_scope_calls_sloppy_eval_ = false; | 173 outer_scope_calls_sloppy_eval_ = false; |
173 inner_scope_calls_eval_ = false; | 174 inner_scope_calls_eval_ = false; |
174 inner_scope_uses_arguments_ = false; | 175 inner_scope_uses_arguments_ = false; |
175 inner_scope_uses_super_property_ = false; | |
176 force_eager_compilation_ = false; | 176 force_eager_compilation_ = false; |
177 force_context_allocation_ = (outer_scope != NULL && !is_function_scope()) | 177 force_context_allocation_ = (outer_scope != NULL && !is_function_scope()) |
178 ? outer_scope->has_forced_context_allocation() : false; | 178 ? outer_scope->has_forced_context_allocation() : false; |
179 num_var_or_const_ = 0; | 179 num_var_or_const_ = 0; |
180 num_stack_slots_ = 0; | 180 num_stack_slots_ = 0; |
181 num_heap_slots_ = 0; | 181 num_heap_slots_ = 0; |
182 num_modules_ = 0; | 182 num_modules_ = 0; |
183 module_var_ = NULL, | 183 module_var_ = NULL, |
184 rest_parameter_ = NULL; | 184 rest_parameter_ = NULL; |
185 rest_index_ = -1; | 185 rest_index_ = -1; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 if (is_function_scope() && !is_arrow_scope()) { | 330 if (is_function_scope() && !is_arrow_scope()) { |
331 // Declare 'arguments' variable which exists in all non arrow functions. | 331 // Declare 'arguments' variable which exists in all non arrow functions. |
332 // Note that it might never be accessed, in which case it won't be | 332 // Note that it might never be accessed, in which case it won't be |
333 // allocated during variable allocation. | 333 // allocated during variable allocation. |
334 variables_.Declare(this, | 334 variables_.Declare(this, |
335 ast_value_factory_->arguments_string(), | 335 ast_value_factory_->arguments_string(), |
336 VAR, | 336 VAR, |
337 Variable::ARGUMENTS, | 337 Variable::ARGUMENTS, |
338 kCreatedInitialized); | 338 kCreatedInitialized); |
339 } | 339 } |
| 340 |
| 341 if (is_function_scope() && |
| 342 (IsConciseMethod(function_kind_) || IsConstructor(function_kind_) || |
| 343 IsAccessorFunction(function_kind_))) { |
| 344 DCHECK(!is_arrow_scope()); |
| 345 // Declare '.home_object' variable which exists in all methods. |
| 346 // Note that it might never be accessed, in which case it won't be |
| 347 // allocated during variable allocation. |
| 348 variables_.Declare(this, ast_value_factory_->home_object_string(), VAR, |
| 349 Variable::NORMAL, kCreatedInitialized); |
| 350 } |
340 } | 351 } |
341 | 352 |
342 | 353 |
343 Scope* Scope::FinalizeBlockScope() { | 354 Scope* Scope::FinalizeBlockScope() { |
344 DCHECK(is_block_scope()); | 355 DCHECK(is_block_scope()); |
345 DCHECK(internals_.is_empty()); | 356 DCHECK(internals_.is_empty()); |
346 DCHECK(temps_.is_empty()); | 357 DCHECK(temps_.is_empty()); |
347 DCHECK(params_.is_empty()); | 358 DCHECK(params_.is_empty()); |
348 | 359 |
349 if (num_var_or_const() > 0) return this; | 360 if (num_var_or_const() > 0) return this; |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 } | 933 } |
923 if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n"); | 934 if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n"); |
924 if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n"); | 935 if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n"); |
925 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); | 936 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); |
926 if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n"); | 937 if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n"); |
927 if (scope_uses_super_property_) | 938 if (scope_uses_super_property_) |
928 Indent(n1, "// scope uses 'super' property\n"); | 939 Indent(n1, "// scope uses 'super' property\n"); |
929 if (inner_scope_uses_arguments_) { | 940 if (inner_scope_uses_arguments_) { |
930 Indent(n1, "// inner scope uses 'arguments'\n"); | 941 Indent(n1, "// inner scope uses 'arguments'\n"); |
931 } | 942 } |
932 if (inner_scope_uses_super_property_) | |
933 Indent(n1, "// inner scope uses 'super' property\n"); | |
934 if (outer_scope_calls_sloppy_eval_) { | 943 if (outer_scope_calls_sloppy_eval_) { |
935 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); | 944 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); |
936 } | 945 } |
937 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); | 946 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); |
938 if (num_stack_slots_ > 0) { Indent(n1, "// "); | 947 if (num_stack_slots_ > 0) { Indent(n1, "// "); |
939 PrintF("%d stack slots\n", num_stack_slots_); } | 948 PrintF("%d stack slots\n", num_stack_slots_); } |
940 if (num_heap_slots_ > 0) { Indent(n1, "// "); | 949 if (num_heap_slots_ > 0) { Indent(n1, "// "); |
941 PrintF("%d heap slots\n", num_heap_slots_); } | 950 PrintF("%d heap slots\n", num_heap_slots_); } |
942 | 951 |
943 // Print locals. | 952 // Print locals. |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1280 if (inner->scope_calls_eval_ || inner->inner_scope_calls_eval_) { | 1289 if (inner->scope_calls_eval_ || inner->inner_scope_calls_eval_) { |
1281 inner_scope_calls_eval_ = true; | 1290 inner_scope_calls_eval_ = true; |
1282 } | 1291 } |
1283 // If the inner scope is an arrow function, propagate the flags tracking | 1292 // If the inner scope is an arrow function, propagate the flags tracking |
1284 // usage of arguments/super/this, but do not propagate them out from normal | 1293 // usage of arguments/super/this, but do not propagate them out from normal |
1285 // functions. | 1294 // functions. |
1286 if (!inner->is_function_scope() || inner->is_arrow_scope()) { | 1295 if (!inner->is_function_scope() || inner->is_arrow_scope()) { |
1287 if (inner->scope_uses_arguments_ || inner->inner_scope_uses_arguments_) { | 1296 if (inner->scope_uses_arguments_ || inner->inner_scope_uses_arguments_) { |
1288 inner_scope_uses_arguments_ = true; | 1297 inner_scope_uses_arguments_ = true; |
1289 } | 1298 } |
1290 if (inner->scope_uses_super_property_ || | |
1291 inner->inner_scope_uses_super_property_) { | |
1292 inner_scope_uses_super_property_ = true; | |
1293 } | |
1294 } | 1299 } |
1295 if (inner->force_eager_compilation_) { | 1300 if (inner->force_eager_compilation_) { |
1296 force_eager_compilation_ = true; | 1301 force_eager_compilation_ = true; |
1297 } | 1302 } |
1298 if (asm_module_ && inner->scope_type() == FUNCTION_SCOPE) { | 1303 if (asm_module_ && inner->scope_type() == FUNCTION_SCOPE) { |
1299 inner->asm_function_ = true; | 1304 inner->asm_function_ = true; |
1300 } | 1305 } |
1301 } | 1306 } |
1302 } | 1307 } |
1303 | 1308 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1391 // In strict mode 'arguments' does not alias formal parameters. | 1396 // In strict mode 'arguments' does not alias formal parameters. |
1392 // Therefore in strict mode we allocate parameters as if 'arguments' | 1397 // Therefore in strict mode we allocate parameters as if 'arguments' |
1393 // were not used. | 1398 // were not used. |
1394 uses_sloppy_arguments = is_sloppy(language_mode()); | 1399 uses_sloppy_arguments = is_sloppy(language_mode()); |
1395 } | 1400 } |
1396 | 1401 |
1397 if (rest_parameter_ && !MustAllocate(rest_parameter_)) { | 1402 if (rest_parameter_ && !MustAllocate(rest_parameter_)) { |
1398 rest_parameter_ = NULL; | 1403 rest_parameter_ = NULL; |
1399 } | 1404 } |
1400 | 1405 |
| 1406 Variable* home_object_var = |
| 1407 LookupLocal(ast_value_factory_->home_object_string()); |
| 1408 if (home_object_var != nullptr && uses_super_property() && |
| 1409 MustAllocate(home_object_var)) { |
| 1410 // TODO(arv): super() uses a SuperReference so it generates a VariableProxy |
| 1411 // for the .home_object which makes it look like we need to allocate the |
| 1412 // home_object_var. |
| 1413 // Consider splitting the AST node into 2 different nodes since the |
| 1414 // semantics is just so different. |
| 1415 home_object_ = home_object_var; |
| 1416 } |
| 1417 |
1401 // The same parameter may occur multiple times in the parameters_ list. | 1418 // The same parameter may occur multiple times in the parameters_ list. |
1402 // If it does, and if it is not copied into the context object, it must | 1419 // If it does, and if it is not copied into the context object, it must |
1403 // receive the highest parameter index for that parameter; thus iteration | 1420 // receive the highest parameter index for that parameter; thus iteration |
1404 // order is relevant! | 1421 // order is relevant! |
1405 for (int i = params_.length() - 1; i >= 0; --i) { | 1422 for (int i = params_.length() - 1; i >= 0; --i) { |
1406 Variable* var = params_[i]; | 1423 Variable* var = params_[i]; |
1407 if (var == rest_parameter_) continue; | 1424 if (var == rest_parameter_) continue; |
1408 | 1425 |
1409 DCHECK(var->scope() == this); | 1426 DCHECK(var->scope() == this); |
1410 if (uses_sloppy_arguments || has_forced_context_allocation()) { | 1427 if (uses_sloppy_arguments || has_forced_context_allocation()) { |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1556 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1573 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); |
1557 } | 1574 } |
1558 | 1575 |
1559 | 1576 |
1560 int Scope::ContextLocalCount() const { | 1577 int Scope::ContextLocalCount() const { |
1561 if (num_heap_slots() == 0) return 0; | 1578 if (num_heap_slots() == 0) return 0; |
1562 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1579 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1563 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1580 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
1564 } | 1581 } |
1565 } } // namespace v8::internal | 1582 } } // namespace v8::internal |
OLD | NEW |