| 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 |