| 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/linkage.h" | 10 #include "src/compiler/linkage.h" |
| (...skipping 2294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2305 } | 2305 } |
| 2306 | 2306 |
| 2307 | 2307 |
| 2308 void AstGraphBuilder::VisitCall(Call* expr) { | 2308 void AstGraphBuilder::VisitCall(Call* expr) { |
| 2309 Expression* callee = expr->expression(); | 2309 Expression* callee = expr->expression(); |
| 2310 Call::CallType call_type = expr->GetCallType(isolate()); | 2310 Call::CallType call_type = expr->GetCallType(isolate()); |
| 2311 | 2311 |
| 2312 // Prepare the callee and the receiver to the function call. This depends on | 2312 // Prepare the callee and the receiver to the function call. This depends on |
| 2313 // the semantics of the underlying call type. | 2313 // the semantics of the underlying call type. |
| 2314 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; | 2314 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; |
| 2315 Node* receiver_value = NULL; | 2315 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; |
| 2316 Node* callee_value = NULL; | 2316 Node* receiver_value = nullptr; |
| 2317 Node* callee_value = nullptr; |
| 2317 bool possibly_eval = false; | 2318 bool possibly_eval = false; |
| 2318 switch (call_type) { | 2319 switch (call_type) { |
| 2319 case Call::GLOBAL_CALL: { | 2320 case Call::GLOBAL_CALL: { |
| 2320 VariableProxy* proxy = callee->AsVariableProxy(); | 2321 VariableProxy* proxy = callee->AsVariableProxy(); |
| 2321 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2322 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
| 2322 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); | 2323 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); |
| 2323 callee_value = | 2324 callee_value = |
| 2324 BuildVariableLoad(proxy->var(), expr->expression()->id(), states, | 2325 BuildVariableLoad(proxy->var(), expr->expression()->id(), states, |
| 2325 pair, OutputFrameStateCombine::Push()); | 2326 pair, OutputFrameStateCombine::Push()); |
| 2327 receiver_hint = ConvertReceiverMode::kNullOrUndefined; |
| 2326 receiver_value = jsgraph()->UndefinedConstant(); | 2328 receiver_value = jsgraph()->UndefinedConstant(); |
| 2327 break; | 2329 break; |
| 2328 } | 2330 } |
| 2329 case Call::LOOKUP_SLOT_CALL: { | 2331 case Call::LOOKUP_SLOT_CALL: { |
| 2330 Variable* variable = callee->AsVariableProxy()->var(); | 2332 Variable* variable = callee->AsVariableProxy()->var(); |
| 2331 DCHECK(variable->location() == VariableLocation::LOOKUP); | 2333 DCHECK(variable->location() == VariableLocation::LOOKUP); |
| 2332 Node* name = jsgraph()->Constant(variable->name()); | 2334 Node* name = jsgraph()->Constant(variable->name()); |
| 2333 const Operator* op = | 2335 const Operator* op = |
| 2334 javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2); | 2336 javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2); |
| 2335 Node* pair = NewNode(op, current_context(), name); | 2337 Node* pair = NewNode(op, current_context(), name); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2355 states.AddToNode(callee_value, property->LoadId(), | 2357 states.AddToNode(callee_value, property->LoadId(), |
| 2356 OutputFrameStateCombine::Push()); | 2358 OutputFrameStateCombine::Push()); |
| 2357 } else { | 2359 } else { |
| 2358 VisitForValue(property->key()); | 2360 VisitForValue(property->key()); |
| 2359 FrameStateBeforeAndAfter states(this, property->key()->id()); | 2361 FrameStateBeforeAndAfter states(this, property->key()->id()); |
| 2360 Node* key = environment()->Pop(); | 2362 Node* key = environment()->Pop(); |
| 2361 callee_value = BuildKeyedLoad(object, key, pair); | 2363 callee_value = BuildKeyedLoad(object, key, pair); |
| 2362 states.AddToNode(callee_value, property->LoadId(), | 2364 states.AddToNode(callee_value, property->LoadId(), |
| 2363 OutputFrameStateCombine::Push()); | 2365 OutputFrameStateCombine::Push()); |
| 2364 } | 2366 } |
| 2367 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an |
| 2368 // object for sloppy callees. However the receiver is guaranteed not to |
| 2369 // be null or undefined at this point. |
| 2370 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; |
| 2365 receiver_value = environment()->Pop(); | 2371 receiver_value = environment()->Pop(); |
| 2366 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an | |
| 2367 // object for sloppy callees. This could also be modeled explicitly | |
| 2368 // here, | |
| 2369 // thereby obsoleting the need for a flag to the call operator. | |
| 2370 flags = CALL_AS_METHOD; | 2372 flags = CALL_AS_METHOD; |
| 2371 | 2373 |
| 2372 } else { | 2374 } else { |
| 2375 // TODO(mstarzinger): Cleanup this special handling for super access, |
| 2376 // the stack layout seems to be completely out of sync here, fix this! |
| 2373 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2377 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
| 2374 VisitForValue( | 2378 VisitForValue( |
| 2375 property->obj()->AsSuperPropertyReference()->home_object()); | 2379 property->obj()->AsSuperPropertyReference()->home_object()); |
| 2376 Node* home_object = environment()->Pop(); | 2380 Node* home_object = environment()->Pop(); |
| 2377 receiver_value = environment()->Pop(); | 2381 receiver_value = environment()->Pop(); |
| 2378 if (property->key()->IsPropertyName()) { | 2382 if (property->key()->IsPropertyName()) { |
| 2379 FrameStateBeforeAndAfter states(this, property->obj()->id()); | 2383 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
| 2380 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2384 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
| 2381 callee_value = | 2385 callee_value = |
| 2382 BuildNamedSuperLoad(receiver_value, home_object, name, pair); | 2386 BuildNamedSuperLoad(receiver_value, home_object, name, pair); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2409 callee_value = NewNode(common()->Projection(0), pair); | 2413 callee_value = NewNode(common()->Projection(0), pair); |
| 2410 receiver_value = NewNode(common()->Projection(1), pair); | 2414 receiver_value = NewNode(common()->Projection(1), pair); |
| 2411 PrepareFrameState(pair, expr->LookupId(), | 2415 PrepareFrameState(pair, expr->LookupId(), |
| 2412 OutputFrameStateCombine::Push(2)); | 2416 OutputFrameStateCombine::Push(2)); |
| 2413 break; | 2417 break; |
| 2414 } | 2418 } |
| 2415 // Fall through. | 2419 // Fall through. |
| 2416 case Call::OTHER_CALL: | 2420 case Call::OTHER_CALL: |
| 2417 VisitForValue(callee); | 2421 VisitForValue(callee); |
| 2418 callee_value = environment()->Pop(); | 2422 callee_value = environment()->Pop(); |
| 2423 receiver_hint = ConvertReceiverMode::kNullOrUndefined; |
| 2419 receiver_value = jsgraph()->UndefinedConstant(); | 2424 receiver_value = jsgraph()->UndefinedConstant(); |
| 2420 break; | 2425 break; |
| 2421 } | 2426 } |
| 2422 | 2427 |
| 2423 // The callee and the receiver both have to be pushed onto the operand stack | 2428 // The callee and the receiver both have to be pushed onto the operand stack |
| 2424 // before arguments are being evaluated. | 2429 // before arguments are being evaluated. |
| 2425 environment()->Push(callee_value); | 2430 environment()->Push(callee_value); |
| 2426 environment()->Push(receiver_value); | 2431 environment()->Push(receiver_value); |
| 2427 | 2432 |
| 2428 // Evaluate all arguments to the function call, | 2433 // Evaluate all arguments to the function call, |
| 2429 ZoneList<Expression*>* args = expr->arguments(); | 2434 ZoneList<Expression*>* args = expr->arguments(); |
| 2430 VisitForValues(args); | 2435 VisitForValues(args); |
| 2431 | 2436 |
| 2432 // Resolve callee and receiver for a potential direct eval call. This block | 2437 // Resolve callee and receiver for a potential direct eval call. This block |
| 2433 // will mutate the callee and receiver values pushed onto the environment. | 2438 // will mutate the callee and receiver values pushed onto the environment. |
| 2434 if (possibly_eval && args->length() > 0) { | 2439 if (possibly_eval && args->length() > 0) { |
| 2435 int arg_count = args->length(); | 2440 int arg_count = args->length(); |
| 2436 | 2441 |
| 2437 // Extract callee and source string from the environment. | 2442 // Extract callee and source string from the environment. |
| 2438 Node* callee = environment()->Peek(arg_count + 1); | 2443 Node* callee = environment()->Peek(arg_count + 1); |
| 2439 Node* source = environment()->Peek(arg_count - 1); | 2444 Node* source = environment()->Peek(arg_count - 1); |
| 2440 | 2445 |
| 2441 // Create node to ask for help resolving potential eval call. This will | 2446 // Create node to ask for help resolving potential eval call. This will |
| 2442 // provide a fully resolved callee and the corresponding receiver. | 2447 // provide a fully resolved callee to patch into the environment. |
| 2443 Node* function = GetFunctionClosure(); | 2448 Node* function = GetFunctionClosure(); |
| 2444 Node* language = jsgraph()->Constant(language_mode()); | 2449 Node* language = jsgraph()->Constant(language_mode()); |
| 2445 Node* position = jsgraph()->Constant(current_scope()->start_position()); | 2450 Node* position = jsgraph()->Constant(current_scope()->start_position()); |
| 2446 const Operator* op = | 2451 const Operator* op = |
| 2447 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 2452 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); |
| 2448 Node* new_callee = | 2453 Node* new_callee = |
| 2449 NewNode(op, callee, source, function, language, position); | 2454 NewNode(op, callee, source, function, language, position); |
| 2450 PrepareFrameState(new_callee, expr->EvalId(), | 2455 PrepareFrameState(new_callee, expr->EvalId(), |
| 2451 OutputFrameStateCombine::PokeAt(arg_count + 1)); | 2456 OutputFrameStateCombine::PokeAt(arg_count + 1)); |
| 2452 | 2457 |
| 2453 // Patch callee on the environment. | 2458 // Patch callee on the environment. |
| 2454 environment()->Poke(arg_count + 1, new_callee); | 2459 environment()->Poke(arg_count + 1, new_callee); |
| 2455 } | 2460 } |
| 2456 | 2461 |
| 2457 // Create node to perform the function call. | 2462 // Create node to perform the function call. |
| 2458 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); | 2463 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); |
| 2459 const Operator* call = javascript()->CallFunction(args->length() + 2, flags, | 2464 const Operator* call = javascript()->CallFunction( |
| 2460 language_mode(), feedback); | 2465 args->length() + 2, flags, language_mode(), feedback, receiver_hint); |
| 2461 Node* value = ProcessArguments(call, args->length() + 2); | 2466 Node* value = ProcessArguments(call, args->length() + 2); |
| 2462 environment()->Push(callee_value); | 2467 environment()->Push(callee_value); |
| 2463 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); | 2468 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); |
| 2464 environment()->Drop(1); | 2469 environment()->Drop(1); |
| 2465 ast_context()->ProduceValue(value); | 2470 ast_context()->ProduceValue(value); |
| 2466 } | 2471 } |
| 2467 | 2472 |
| 2468 | 2473 |
| 2469 void AstGraphBuilder::VisitCallSuper(Call* expr) { | 2474 void AstGraphBuilder::VisitCallSuper(Call* expr) { |
| 2470 SuperCallReference* super = expr->expression()->AsSuperCallReference(); | 2475 SuperCallReference* super = expr->expression()->AsSuperCallReference(); |
| (...skipping 1751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4222 // Phi does not exist yet, introduce one. | 4227 // Phi does not exist yet, introduce one. |
| 4223 value = NewPhi(inputs, value, control); | 4228 value = NewPhi(inputs, value, control); |
| 4224 value->ReplaceInput(inputs - 1, other); | 4229 value->ReplaceInput(inputs - 1, other); |
| 4225 } | 4230 } |
| 4226 return value; | 4231 return value; |
| 4227 } | 4232 } |
| 4228 | 4233 |
| 4229 } // namespace compiler | 4234 } // namespace compiler |
| 4230 } // namespace internal | 4235 } // namespace internal |
| 4231 } // namespace v8 | 4236 } // namespace v8 |
| OLD | NEW |