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