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 1951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1962 Node* array = environment()->Pop(); | 1962 Node* array = environment()->Pop(); |
1963 Node* result; | 1963 Node* result; |
1964 | 1964 |
1965 if (subexpr->IsSpread()) { | 1965 if (subexpr->IsSpread()) { |
1966 VisitForValue(subexpr->AsSpread()->expression()); | 1966 VisitForValue(subexpr->AsSpread()->expression()); |
1967 FrameStateBeforeAndAfter states(this, | 1967 FrameStateBeforeAndAfter states(this, |
1968 subexpr->AsSpread()->expression()->id()); | 1968 subexpr->AsSpread()->expression()->id()); |
1969 Node* iterable = environment()->Pop(); | 1969 Node* iterable = environment()->Pop(); |
1970 Node* function = BuildLoadNativeContextField( | 1970 Node* function = BuildLoadNativeContextField( |
1971 Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX); | 1971 Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX); |
1972 result = NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS, | 1972 result = NewNode(javascript()->CallFunction(3, language_mode()), function, |
1973 language_mode()), | 1973 array, iterable); |
1974 function, array, iterable); | |
1975 states.AddToNode(result, expr->GetIdForElement(array_index)); | 1974 states.AddToNode(result, expr->GetIdForElement(array_index)); |
1976 } else { | 1975 } else { |
1977 VisitForValue(subexpr); | 1976 VisitForValue(subexpr); |
1978 Node* value = environment()->Pop(); | 1977 Node* value = environment()->Pop(); |
1979 const Operator* op = | 1978 const Operator* op = |
1980 javascript()->CallRuntime(Runtime::kAppendElement, 2); | 1979 javascript()->CallRuntime(Runtime::kAppendElement, 2); |
1981 result = NewNode(op, array, value); | 1980 result = NewNode(op, array, value); |
1982 PrepareFrameState(result, expr->GetIdForElement(array_index)); | 1981 PrepareFrameState(result, expr->GetIdForElement(array_index)); |
1983 } | 1982 } |
1984 | 1983 |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2310 ast_context()->ProduceValue(value); | 2309 ast_context()->ProduceValue(value); |
2311 } | 2310 } |
2312 | 2311 |
2313 | 2312 |
2314 void AstGraphBuilder::VisitCall(Call* expr) { | 2313 void AstGraphBuilder::VisitCall(Call* expr) { |
2315 Expression* callee = expr->expression(); | 2314 Expression* callee = expr->expression(); |
2316 Call::CallType call_type = expr->GetCallType(isolate()); | 2315 Call::CallType call_type = expr->GetCallType(isolate()); |
2317 | 2316 |
2318 // Prepare the callee and the receiver to the function call. This depends on | 2317 // Prepare the callee and the receiver to the function call. This depends on |
2319 // the semantics of the underlying call type. | 2318 // the semantics of the underlying call type. |
2320 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; | |
2321 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; | 2319 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; |
2322 Node* receiver_value = nullptr; | 2320 Node* receiver_value = nullptr; |
2323 Node* callee_value = nullptr; | 2321 Node* callee_value = nullptr; |
2324 bool possibly_eval = false; | 2322 bool possibly_eval = false; |
2325 switch (call_type) { | 2323 switch (call_type) { |
2326 case Call::GLOBAL_CALL: { | 2324 case Call::GLOBAL_CALL: { |
2327 VariableProxy* proxy = callee->AsVariableProxy(); | 2325 VariableProxy* proxy = callee->AsVariableProxy(); |
2328 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 2326 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
2329 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); | 2327 FrameStateBeforeAndAfter states(this, BeforeId(proxy)); |
2330 callee_value = | 2328 callee_value = |
(...skipping 25 matching lines...) Expand all Loading... |
2356 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2354 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2357 Node* object = environment()->Top(); | 2355 Node* object = environment()->Top(); |
2358 callee_value = BuildNamedLoad(object, name, feedback); | 2356 callee_value = BuildNamedLoad(object, name, feedback); |
2359 states.AddToNode(callee_value, property->LoadId(), | 2357 states.AddToNode(callee_value, property->LoadId(), |
2360 OutputFrameStateCombine::Push()); | 2358 OutputFrameStateCombine::Push()); |
2361 // Note that a property call requires the receiver to be wrapped into | 2359 // Note that a property call requires the receiver to be wrapped into |
2362 // an object for sloppy callees. However the receiver is guaranteed | 2360 // an object for sloppy callees. However the receiver is guaranteed |
2363 // not to be null or undefined at this point. | 2361 // not to be null or undefined at this point. |
2364 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; | 2362 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; |
2365 receiver_value = environment()->Pop(); | 2363 receiver_value = environment()->Pop(); |
2366 flags = CALL_AS_METHOD; | |
2367 break; | 2364 break; |
2368 } | 2365 } |
2369 case Call::KEYED_PROPERTY_CALL: { | 2366 case Call::KEYED_PROPERTY_CALL: { |
2370 Property* property = callee->AsProperty(); | 2367 Property* property = callee->AsProperty(); |
2371 VectorSlotPair feedback = | 2368 VectorSlotPair feedback = |
2372 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2369 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2373 VisitForValue(property->obj()); | 2370 VisitForValue(property->obj()); |
2374 VisitForValue(property->key()); | 2371 VisitForValue(property->key()); |
2375 FrameStateBeforeAndAfter states(this, property->key()->id()); | 2372 FrameStateBeforeAndAfter states(this, property->key()->id()); |
2376 Node* key = environment()->Pop(); | 2373 Node* key = environment()->Pop(); |
2377 Node* object = environment()->Top(); | 2374 Node* object = environment()->Top(); |
2378 callee_value = BuildKeyedLoad(object, key, feedback); | 2375 callee_value = BuildKeyedLoad(object, key, feedback); |
2379 states.AddToNode(callee_value, property->LoadId(), | 2376 states.AddToNode(callee_value, property->LoadId(), |
2380 OutputFrameStateCombine::Push()); | 2377 OutputFrameStateCombine::Push()); |
2381 // Note that a property call requires the receiver to be wrapped into | 2378 // Note that a property call requires the receiver to be wrapped into |
2382 // an object for sloppy callees. However the receiver is guaranteed | 2379 // an object for sloppy callees. However the receiver is guaranteed |
2383 // not to be null or undefined at this point. | 2380 // not to be null or undefined at this point. |
2384 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; | 2381 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; |
2385 receiver_value = environment()->Pop(); | 2382 receiver_value = environment()->Pop(); |
2386 flags = CALL_AS_METHOD; | |
2387 break; | 2383 break; |
2388 } | 2384 } |
2389 case Call::NAMED_SUPER_PROPERTY_CALL: { | 2385 case Call::NAMED_SUPER_PROPERTY_CALL: { |
2390 Property* property = callee->AsProperty(); | 2386 Property* property = callee->AsProperty(); |
2391 SuperPropertyReference* super_ref = | 2387 SuperPropertyReference* super_ref = |
2392 property->obj()->AsSuperPropertyReference(); | 2388 property->obj()->AsSuperPropertyReference(); |
2393 VisitForValue(super_ref->home_object()); | 2389 VisitForValue(super_ref->home_object()); |
2394 VisitForValue(super_ref->this_var()); | 2390 VisitForValue(super_ref->this_var()); |
2395 Node* home = environment()->Peek(1); | 2391 Node* home = environment()->Peek(1); |
2396 Node* object = environment()->Top(); | 2392 Node* object = environment()->Top(); |
2397 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2393 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2398 FrameStateBeforeAndAfter states(this, property->obj()->id()); | 2394 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
2399 callee_value = BuildNamedSuperLoad(object, home, name, VectorSlotPair()); | 2395 callee_value = BuildNamedSuperLoad(object, home, name, VectorSlotPair()); |
2400 states.AddToNode(callee_value, property->LoadId(), | 2396 states.AddToNode(callee_value, property->LoadId(), |
2401 OutputFrameStateCombine::Push()); | 2397 OutputFrameStateCombine::Push()); |
2402 // Note that a property call requires the receiver to be wrapped into | 2398 // Note that a property call requires the receiver to be wrapped into |
2403 // an object for sloppy callees. Since the receiver is not the target of | 2399 // an object for sloppy callees. Since the receiver is not the target of |
2404 // the load, it could very well be null or undefined at this point. | 2400 // the load, it could very well be null or undefined at this point. |
2405 receiver_value = environment()->Pop(); | 2401 receiver_value = environment()->Pop(); |
2406 flags = CALL_AS_METHOD; | |
2407 environment()->Drop(1); | 2402 environment()->Drop(1); |
2408 break; | 2403 break; |
2409 } | 2404 } |
2410 case Call::KEYED_SUPER_PROPERTY_CALL: { | 2405 case Call::KEYED_SUPER_PROPERTY_CALL: { |
2411 Property* property = callee->AsProperty(); | 2406 Property* property = callee->AsProperty(); |
2412 SuperPropertyReference* super_ref = | 2407 SuperPropertyReference* super_ref = |
2413 property->obj()->AsSuperPropertyReference(); | 2408 property->obj()->AsSuperPropertyReference(); |
2414 VisitForValue(super_ref->home_object()); | 2409 VisitForValue(super_ref->home_object()); |
2415 VisitForValue(super_ref->this_var()); | 2410 VisitForValue(super_ref->this_var()); |
2416 environment()->Push(environment()->Top()); // Duplicate this_var. | 2411 environment()->Push(environment()->Top()); // Duplicate this_var. |
2417 environment()->Push(environment()->Peek(2)); // Duplicate home_obj. | 2412 environment()->Push(environment()->Peek(2)); // Duplicate home_obj. |
2418 VisitForValue(property->key()); | 2413 VisitForValue(property->key()); |
2419 Node* key = environment()->Pop(); | 2414 Node* key = environment()->Pop(); |
2420 Node* home = environment()->Pop(); | 2415 Node* home = environment()->Pop(); |
2421 Node* object = environment()->Pop(); | 2416 Node* object = environment()->Pop(); |
2422 FrameStateBeforeAndAfter states(this, property->key()->id()); | 2417 FrameStateBeforeAndAfter states(this, property->key()->id()); |
2423 callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair()); | 2418 callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair()); |
2424 states.AddToNode(callee_value, property->LoadId(), | 2419 states.AddToNode(callee_value, property->LoadId(), |
2425 OutputFrameStateCombine::Push()); | 2420 OutputFrameStateCombine::Push()); |
2426 // Note that a property call requires the receiver to be wrapped into | 2421 // Note that a property call requires the receiver to be wrapped into |
2427 // an object for sloppy callees. Since the receiver is not the target of | 2422 // an object for sloppy callees. Since the receiver is not the target of |
2428 // the load, it could very well be null or undefined at this point. | 2423 // the load, it could very well be null or undefined at this point. |
2429 receiver_value = environment()->Pop(); | 2424 receiver_value = environment()->Pop(); |
2430 flags = CALL_AS_METHOD; | |
2431 environment()->Drop(1); | 2425 environment()->Drop(1); |
2432 break; | 2426 break; |
2433 } | 2427 } |
2434 case Call::SUPER_CALL: | 2428 case Call::SUPER_CALL: |
2435 return VisitCallSuper(expr); | 2429 return VisitCallSuper(expr); |
2436 case Call::POSSIBLY_EVAL_CALL: | 2430 case Call::POSSIBLY_EVAL_CALL: |
2437 possibly_eval = true; | 2431 possibly_eval = true; |
2438 if (callee->AsVariableProxy()->var()->IsLookupSlot()) { | 2432 if (callee->AsVariableProxy()->var()->IsLookupSlot()) { |
2439 Variable* variable = callee->AsVariableProxy()->var(); | 2433 Variable* variable = callee->AsVariableProxy()->var(); |
2440 Node* name = jsgraph()->Constant(variable->name()); | 2434 Node* name = jsgraph()->Constant(variable->name()); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2486 PrepareFrameState(new_callee, expr->EvalId(), | 2480 PrepareFrameState(new_callee, expr->EvalId(), |
2487 OutputFrameStateCombine::PokeAt(arg_count + 1)); | 2481 OutputFrameStateCombine::PokeAt(arg_count + 1)); |
2488 | 2482 |
2489 // Patch callee on the environment. | 2483 // Patch callee on the environment. |
2490 environment()->Poke(arg_count + 1, new_callee); | 2484 environment()->Poke(arg_count + 1, new_callee); |
2491 } | 2485 } |
2492 | 2486 |
2493 // Create node to perform the function call. | 2487 // Create node to perform the function call. |
2494 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); | 2488 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); |
2495 const Operator* call = javascript()->CallFunction( | 2489 const Operator* call = javascript()->CallFunction( |
2496 args->length() + 2, flags, language_mode(), feedback, receiver_hint); | 2490 args->length() + 2, language_mode(), feedback, receiver_hint); |
2497 FrameStateBeforeAndAfter states(this, expr->CallId()); | 2491 FrameStateBeforeAndAfter states(this, expr->CallId()); |
2498 Node* value = ProcessArguments(call, args->length() + 2); | 2492 Node* value = ProcessArguments(call, args->length() + 2); |
2499 environment()->Push(value->InputAt(0)); // The callee passed to the call. | 2493 environment()->Push(value->InputAt(0)); // The callee passed to the call. |
2500 states.AddToNode(value, expr->ReturnId(), OutputFrameStateCombine::Push()); | 2494 states.AddToNode(value, expr->ReturnId(), OutputFrameStateCombine::Push()); |
2501 environment()->Drop(1); | 2495 environment()->Drop(1); |
2502 ast_context()->ProduceValue(value); | 2496 ast_context()->ProduceValue(value); |
2503 } | 2497 } |
2504 | 2498 |
2505 | 2499 |
2506 void AstGraphBuilder::VisitCallSuper(Call* expr) { | 2500 void AstGraphBuilder::VisitCallSuper(Call* expr) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2546 const Operator* call = javascript()->CallConstruct(args->length() + 2); | 2540 const Operator* call = javascript()->CallConstruct(args->length() + 2); |
2547 Node* value = ProcessArguments(call, args->length() + 2); | 2541 Node* value = ProcessArguments(call, args->length() + 2); |
2548 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2542 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
2549 ast_context()->ProduceValue(value); | 2543 ast_context()->ProduceValue(value); |
2550 } | 2544 } |
2551 | 2545 |
2552 | 2546 |
2553 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { | 2547 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { |
2554 // The callee and the receiver both have to be pushed onto the operand stack | 2548 // The callee and the receiver both have to be pushed onto the operand stack |
2555 // before arguments are being evaluated. | 2549 // before arguments are being evaluated. |
2556 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; | |
2557 Node* callee_value = BuildLoadNativeContextField(expr->context_index()); | 2550 Node* callee_value = BuildLoadNativeContextField(expr->context_index()); |
2558 Node* receiver_value = jsgraph()->UndefinedConstant(); | 2551 Node* receiver_value = jsgraph()->UndefinedConstant(); |
2559 | 2552 |
2560 environment()->Push(callee_value); | 2553 environment()->Push(callee_value); |
2561 environment()->Push(receiver_value); | 2554 environment()->Push(receiver_value); |
2562 | 2555 |
2563 // Evaluate all arguments to the JS runtime call. | 2556 // Evaluate all arguments to the JS runtime call. |
2564 ZoneList<Expression*>* args = expr->arguments(); | 2557 ZoneList<Expression*>* args = expr->arguments(); |
2565 VisitForValues(args); | 2558 VisitForValues(args); |
2566 | 2559 |
2567 // Create node to perform the JS runtime call. | 2560 // Create node to perform the JS runtime call. |
2568 const Operator* call = | 2561 const Operator* call = |
2569 javascript()->CallFunction(args->length() + 2, flags, language_mode()); | 2562 javascript()->CallFunction(args->length() + 2, language_mode()); |
2570 FrameStateBeforeAndAfter states(this, expr->CallId()); | 2563 FrameStateBeforeAndAfter states(this, expr->CallId()); |
2571 Node* value = ProcessArguments(call, args->length() + 2); | 2564 Node* value = ProcessArguments(call, args->length() + 2); |
2572 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | 2565 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
2573 ast_context()->ProduceValue(value); | 2566 ast_context()->ProduceValue(value); |
2574 } | 2567 } |
2575 | 2568 |
2576 | 2569 |
2577 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 2570 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
2578 // Handle calls to runtime functions implemented in JavaScript separately as | 2571 // Handle calls to runtime functions implemented in JavaScript separately as |
2579 // the call follows JavaScript ABI and the callee is statically unknown. | 2572 // the call follows JavaScript ABI and the callee is statically unknown. |
(...skipping 1782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4362 // Phi does not exist yet, introduce one. | 4355 // Phi does not exist yet, introduce one. |
4363 value = NewPhi(inputs, value, control); | 4356 value = NewPhi(inputs, value, control); |
4364 value->ReplaceInput(inputs - 1, other); | 4357 value->ReplaceInput(inputs - 1, other); |
4365 } | 4358 } |
4366 return value; | 4359 return value; |
4367 } | 4360 } |
4368 | 4361 |
4369 } // namespace compiler | 4362 } // namespace compiler |
4370 } // namespace internal | 4363 } // namespace internal |
4371 } // namespace v8 | 4364 } // namespace v8 |
OLD | NEW |