OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 exit_controls_(local_zone), | 446 exit_controls_(local_zone), |
447 loop_assignment_analysis_(loop), | 447 loop_assignment_analysis_(loop), |
448 state_values_cache_(jsgraph), | 448 state_values_cache_(jsgraph), |
449 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()), | 449 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()), |
450 local_zone), | 450 local_zone), |
451 js_type_feedback_(js_type_feedback) { | 451 js_type_feedback_(js_type_feedback) { |
452 InitializeAstVisitor(info->isolate(), local_zone); | 452 InitializeAstVisitor(info->isolate(), local_zone); |
453 } | 453 } |
454 | 454 |
455 | 455 |
| 456 Node* AstGraphBuilder::GetFunctionClosureForContext() { |
| 457 Scope* declaration_scope = current_scope()->DeclarationScope(); |
| 458 if (declaration_scope->is_script_scope() || |
| 459 declaration_scope->is_module_scope()) { |
| 460 // Contexts nested in the native context have a canonical empty function as |
| 461 // their closure, not the anonymous closure containing the global code. |
| 462 // Pass a SMI sentinel and let the runtime look up the empty function. |
| 463 return jsgraph()->SmiConstant(0); |
| 464 } else { |
| 465 DCHECK(declaration_scope->is_function_scope()); |
| 466 return GetFunctionClosure(); |
| 467 } |
| 468 } |
| 469 |
| 470 |
456 Node* AstGraphBuilder::GetFunctionClosure() { | 471 Node* AstGraphBuilder::GetFunctionClosure() { |
457 if (!function_closure_.is_set()) { | 472 if (!function_closure_.is_set()) { |
458 const Operator* op = common()->Parameter( | 473 const Operator* op = common()->Parameter( |
459 Linkage::kJSFunctionCallClosureParamIndex, "%closure"); | 474 Linkage::kJSFunctionCallClosureParamIndex, "%closure"); |
460 Node* node = NewNode(op, graph()->start()); | 475 Node* node = NewNode(op, graph()->start()); |
461 function_closure_.set(node); | 476 function_closure_.set(node); |
462 } | 477 } |
463 return function_closure_.get(); | 478 return function_closure_.get(); |
464 } | 479 } |
465 | 480 |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1174 VisitForValue(stmt->expression()); | 1189 VisitForValue(stmt->expression()); |
1175 Node* result = environment()->Pop(); | 1190 Node* result = environment()->Pop(); |
1176 execution_control()->ReturnValue(result); | 1191 execution_control()->ReturnValue(result); |
1177 } | 1192 } |
1178 | 1193 |
1179 | 1194 |
1180 void AstGraphBuilder::VisitWithStatement(WithStatement* stmt) { | 1195 void AstGraphBuilder::VisitWithStatement(WithStatement* stmt) { |
1181 VisitForValue(stmt->expression()); | 1196 VisitForValue(stmt->expression()); |
1182 Node* value = environment()->Pop(); | 1197 Node* value = environment()->Pop(); |
1183 const Operator* op = javascript()->CreateWithContext(); | 1198 const Operator* op = javascript()->CreateWithContext(); |
1184 Node* context = NewNode(op, value, GetFunctionClosure()); | 1199 Node* context = NewNode(op, value, GetFunctionClosureForContext()); |
1185 PrepareFrameState(context, stmt->EntryId()); | 1200 PrepareFrameState(context, stmt->EntryId()); |
1186 ContextScope scope(this, stmt->scope(), context); | 1201 ContextScope scope(this, stmt->scope(), context); |
1187 Visit(stmt->statement()); | 1202 Visit(stmt->statement()); |
1188 } | 1203 } |
1189 | 1204 |
1190 | 1205 |
1191 void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { | 1206 void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { |
1192 ZoneList<CaseClause*>* clauses = stmt->cases(); | 1207 ZoneList<CaseClause*>* clauses = stmt->cases(); |
1193 SwitchBuilder compare_switch(this, clauses->length()); | 1208 SwitchBuilder compare_switch(this, clauses->length()); |
1194 ControlScopeForBreakable scope(this, stmt, &compare_switch); | 1209 ControlScopeForBreakable scope(this, stmt, &compare_switch); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1392 // Clear message object as we enter the catch block. | 1407 // Clear message object as we enter the catch block. |
1393 ExternalReference message_object = | 1408 ExternalReference message_object = |
1394 ExternalReference::address_of_pending_message_obj(isolate()); | 1409 ExternalReference::address_of_pending_message_obj(isolate()); |
1395 Node* the_hole = jsgraph()->TheHoleConstant(); | 1410 Node* the_hole = jsgraph()->TheHoleConstant(); |
1396 BuildStoreExternal(message_object, kMachAnyTagged, the_hole); | 1411 BuildStoreExternal(message_object, kMachAnyTagged, the_hole); |
1397 | 1412 |
1398 // Create a catch scope that binds the exception. | 1413 // Create a catch scope that binds the exception. |
1399 Node* exception = try_control.GetExceptionNode(); | 1414 Node* exception = try_control.GetExceptionNode(); |
1400 Unique<String> name = MakeUnique(stmt->variable()->name()); | 1415 Unique<String> name = MakeUnique(stmt->variable()->name()); |
1401 const Operator* op = javascript()->CreateCatchContext(name); | 1416 const Operator* op = javascript()->CreateCatchContext(name); |
1402 Node* context = NewNode(op, exception, GetFunctionClosure()); | 1417 Node* context = NewNode(op, exception, GetFunctionClosureForContext()); |
1403 PrepareFrameState(context, BailoutId::None()); | 1418 PrepareFrameState(context, BailoutId::None()); |
1404 { | 1419 { |
1405 ContextScope scope(this, stmt->scope(), context); | 1420 ContextScope scope(this, stmt->scope(), context); |
1406 DCHECK(stmt->scope()->declarations()->is_empty()); | 1421 DCHECK(stmt->scope()->declarations()->is_empty()); |
1407 // Evaluate the catch-block. | 1422 // Evaluate the catch-block. |
1408 Visit(stmt->catch_block()); | 1423 Visit(stmt->catch_block()); |
1409 } | 1424 } |
1410 try_control.EndCatch(); | 1425 try_control.EndCatch(); |
1411 | 1426 |
1412 // TODO(mstarzinger): Remove bailout once everything works. | 1427 // TODO(mstarzinger): Remove bailout once everything works. |
(...skipping 1634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3047 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); | 3062 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); |
3048 const Operator* op = javascript()->StoreContext(0, variable->index()); | 3063 const Operator* op = javascript()->StoreContext(0, variable->index()); |
3049 NewNode(op, local_context, parameter); | 3064 NewNode(op, local_context, parameter); |
3050 } | 3065 } |
3051 | 3066 |
3052 return local_context; | 3067 return local_context; |
3053 } | 3068 } |
3054 | 3069 |
3055 | 3070 |
3056 Node* AstGraphBuilder::BuildLocalScriptContext(Scope* scope) { | 3071 Node* AstGraphBuilder::BuildLocalScriptContext(Scope* scope) { |
3057 Node* closure = GetFunctionClosure(); | 3072 DCHECK(scope->is_script_scope()); |
3058 | 3073 |
3059 // Allocate a new local context. | 3074 // Allocate a new local context. |
3060 const Operator* op = javascript()->CreateScriptContext(); | 3075 const Operator* op = javascript()->CreateScriptContext(); |
3061 Node* scope_info = jsgraph()->Constant(scope->GetScopeInfo(isolate())); | 3076 Node* scope_info = jsgraph()->Constant(scope->GetScopeInfo(isolate())); |
3062 Node* local_context = NewNode(op, closure, scope_info); | 3077 Node* local_context = NewNode(op, GetFunctionClosure(), scope_info); |
3063 PrepareFrameState(local_context, BailoutId::FunctionEntry()); | 3078 PrepareFrameState(local_context, BailoutId::FunctionEntry()); |
3064 | 3079 |
3065 return local_context; | 3080 return local_context; |
3066 } | 3081 } |
3067 | 3082 |
3068 | 3083 |
3069 Node* AstGraphBuilder::BuildLocalBlockContext(Scope* scope) { | 3084 Node* AstGraphBuilder::BuildLocalBlockContext(Scope* scope) { |
3070 Node* closure = GetFunctionClosure(); | 3085 DCHECK(scope->is_block_scope()); |
3071 | 3086 |
3072 // Allocate a new local context. | 3087 // Allocate a new local context. |
3073 const Operator* op = javascript()->CreateBlockContext(); | 3088 const Operator* op = javascript()->CreateBlockContext(); |
3074 Node* scope_info = jsgraph()->Constant(scope->GetScopeInfo(isolate())); | 3089 Node* scope_info = jsgraph()->Constant(scope->GetScopeInfo(isolate())); |
3075 Node* local_context = NewNode(op, scope_info, closure); | 3090 Node* local_context = NewNode(op, scope_info, GetFunctionClosureForContext()); |
3076 | 3091 |
3077 return local_context; | 3092 return local_context; |
3078 } | 3093 } |
3079 | 3094 |
3080 | 3095 |
3081 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) { | 3096 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) { |
3082 if (arguments == NULL) return NULL; | 3097 if (arguments == NULL) return NULL; |
3083 | 3098 |
3084 // Allocate and initialize a new arguments object. | 3099 // Allocate and initialize a new arguments object. |
3085 Node* callee = GetFunctionClosure(); | 3100 Node* callee = GetFunctionClosure(); |
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4040 // Phi does not exist yet, introduce one. | 4055 // Phi does not exist yet, introduce one. |
4041 value = NewPhi(inputs, value, control); | 4056 value = NewPhi(inputs, value, control); |
4042 value->ReplaceInput(inputs - 1, other); | 4057 value->ReplaceInput(inputs - 1, other); |
4043 } | 4058 } |
4044 return value; | 4059 return value; |
4045 } | 4060 } |
4046 | 4061 |
4047 } // namespace compiler | 4062 } // namespace compiler |
4048 } // namespace internal | 4063 } // namespace internal |
4049 } // namespace v8 | 4064 } // namespace v8 |
OLD | NEW |