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 |