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 2402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2413 if (possibly_eval && args->length() > 0) { | 2413 if (possibly_eval && args->length() > 0) { |
2414 int arg_count = args->length(); | 2414 int arg_count = args->length(); |
2415 | 2415 |
2416 // Extract callee and source string from the environment. | 2416 // Extract callee and source string from the environment. |
2417 Node* callee = environment()->Peek(arg_count + 1); | 2417 Node* callee = environment()->Peek(arg_count + 1); |
2418 Node* source = environment()->Peek(arg_count - 1); | 2418 Node* source = environment()->Peek(arg_count - 1); |
2419 | 2419 |
2420 // Create node to ask for help resolving potential eval call. This will | 2420 // Create node to ask for help resolving potential eval call. This will |
2421 // provide a fully resolved callee and the corresponding receiver. | 2421 // provide a fully resolved callee and the corresponding receiver. |
2422 Node* function = GetFunctionClosure(); | 2422 Node* function = GetFunctionClosure(); |
2423 // TODO(wingo): ResolvePossibleDirectEval doesn't really need a receiver, | |
2424 // now that eval scopes don't have "this" declarations. Remove this hack | |
2425 // once ResolvePossibleDirectEval changes. | |
2426 Node* receiver; | |
2427 { | |
2428 Variable* variable = info()->scope()->LookupThis(); | |
2429 if (variable->IsStackAllocated()) { | |
2430 receiver = environment()->Lookup(variable); | |
2431 } else { | |
2432 DCHECK(variable->IsContextSlot()); | |
2433 int depth = current_scope()->ContextChainLength(variable->scope()); | |
2434 bool immutable = variable->maybe_assigned() == kNotAssigned; | |
2435 const Operator* op = | |
2436 javascript()->LoadContext(depth, variable->index(), immutable); | |
2437 receiver = NewNode(op, current_context()); | |
2438 } | |
2439 } | |
2440 Node* language = jsgraph()->Constant(language_mode()); | 2423 Node* language = jsgraph()->Constant(language_mode()); |
2441 Node* position = jsgraph()->Constant(current_scope()->start_position()); | 2424 Node* position = jsgraph()->Constant(current_scope()->start_position()); |
2442 const Operator* op = | 2425 const Operator* op = |
2443 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); | 2426 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); |
2444 Node* pair = | 2427 Node* new_callee = |
2445 NewNode(op, callee, source, function, receiver, language, position); | 2428 NewNode(op, callee, source, function, language, position); |
2446 PrepareFrameState(pair, expr->EvalOrLookupId(), | 2429 PrepareFrameState(new_callee, expr->EvalOrLookupId(), |
2447 OutputFrameStateCombine::PokeAt(arg_count + 1)); | 2430 OutputFrameStateCombine::PokeAt(arg_count + 1)); |
2448 Node* new_callee = NewNode(common()->Projection(0), pair); | |
2449 Node* new_receiver = NewNode(common()->Projection(1), pair); | |
2450 | 2431 |
2451 // Patch callee and receiver on the environment. | 2432 // Patch callee on the environment. |
2452 environment()->Poke(arg_count + 1, new_callee); | 2433 environment()->Poke(arg_count + 1, new_callee); |
2453 environment()->Poke(arg_count + 0, new_receiver); | |
2454 } | 2434 } |
2455 | 2435 |
2456 // Create node to perform the function call. | 2436 // Create node to perform the function call. |
2457 const Operator* call = | 2437 const Operator* call = |
2458 javascript()->CallFunction(args->length() + 2, flags, language_mode()); | 2438 javascript()->CallFunction(args->length() + 2, flags, language_mode()); |
2459 Node* value = ProcessArguments(call, args->length() + 2); | 2439 Node* value = ProcessArguments(call, args->length() + 2); |
2460 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2440 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
2461 ast_context()->ProduceValue(value); | 2441 ast_context()->ProduceValue(value); |
2462 } | 2442 } |
2463 | 2443 |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2866 Visit(stmt->body()); | 2846 Visit(stmt->body()); |
2867 } | 2847 } |
2868 | 2848 |
2869 | 2849 |
2870 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) { | 2850 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) { |
2871 Node* value; | 2851 Node* value; |
2872 if (expr->expression()->IsVariableProxy()) { | 2852 if (expr->expression()->IsVariableProxy()) { |
2873 // Delete of an unqualified identifier is only allowed in classic mode but | 2853 // Delete of an unqualified identifier is only allowed in classic mode but |
2874 // deleting "this" is allowed in all language modes. | 2854 // deleting "this" is allowed in all language modes. |
2875 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 2855 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
2876 DCHECK(is_sloppy(language_mode()) || variable->is_this()); | 2856 // Delete of an unqualified identifier is disallowed in strict mode but |
| 2857 // "delete this" is allowed. |
| 2858 DCHECK(is_sloppy(language_mode()) || variable->HasThisName(isolate())); |
2877 value = BuildVariableDelete(variable, expr->id(), | 2859 value = BuildVariableDelete(variable, expr->id(), |
2878 ast_context()->GetStateCombine()); | 2860 ast_context()->GetStateCombine()); |
2879 } else if (expr->expression()->IsProperty()) { | 2861 } else if (expr->expression()->IsProperty()) { |
2880 Property* property = expr->expression()->AsProperty(); | 2862 Property* property = expr->expression()->AsProperty(); |
2881 VisitForValue(property->obj()); | 2863 VisitForValue(property->obj()); |
2882 VisitForValue(property->key()); | 2864 VisitForValue(property->key()); |
2883 Node* key = environment()->Pop(); | 2865 Node* key = environment()->Pop(); |
2884 Node* object = environment()->Pop(); | 2866 Node* object = environment()->Pop(); |
2885 value = NewNode(javascript()->DeleteProperty(language_mode()), object, key); | 2867 value = NewNode(javascript()->DeleteProperty(language_mode()), object, key); |
2886 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2868 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3314 // Global var, const, or let variable. | 3296 // Global var, const, or let variable. |
3315 Node* global = BuildLoadGlobalObject(); | 3297 Node* global = BuildLoadGlobalObject(); |
3316 Node* name = jsgraph()->Constant(variable->name()); | 3298 Node* name = jsgraph()->Constant(variable->name()); |
3317 const Operator* op = javascript()->DeleteProperty(language_mode()); | 3299 const Operator* op = javascript()->DeleteProperty(language_mode()); |
3318 Node* result = NewNode(op, global, name); | 3300 Node* result = NewNode(op, global, name); |
3319 PrepareFrameState(result, bailout_id, combine); | 3301 PrepareFrameState(result, bailout_id, combine); |
3320 return result; | 3302 return result; |
3321 } | 3303 } |
3322 case Variable::PARAMETER: | 3304 case Variable::PARAMETER: |
3323 case Variable::LOCAL: | 3305 case Variable::LOCAL: |
3324 case Variable::CONTEXT: | 3306 case Variable::CONTEXT: { |
3325 // Local var, const, or let variable or context variable. | 3307 // Local var, const, or let variable or context variable. |
3326 return jsgraph()->BooleanConstant(variable->is_this()); | 3308 return jsgraph()->BooleanConstant(variable->HasThisName(isolate())); |
| 3309 } |
3327 case Variable::LOOKUP: { | 3310 case Variable::LOOKUP: { |
3328 // Dynamic lookup of context variable (anywhere in the chain). | 3311 // Dynamic lookup of context variable (anywhere in the chain). |
3329 Node* name = jsgraph()->Constant(variable->name()); | 3312 Node* name = jsgraph()->Constant(variable->name()); |
3330 const Operator* op = | 3313 const Operator* op = |
3331 javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2); | 3314 javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2); |
3332 Node* result = NewNode(op, current_context(), name); | 3315 Node* result = NewNode(op, current_context(), name); |
3333 PrepareFrameState(result, bailout_id, combine); | 3316 PrepareFrameState(result, bailout_id, combine); |
3334 return result; | 3317 return result; |
3335 } | 3318 } |
3336 } | 3319 } |
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4078 // Phi does not exist yet, introduce one. | 4061 // Phi does not exist yet, introduce one. |
4079 value = NewPhi(inputs, value, control); | 4062 value = NewPhi(inputs, value, control); |
4080 value->ReplaceInput(inputs - 1, other); | 4063 value->ReplaceInput(inputs - 1, other); |
4081 } | 4064 } |
4082 return value; | 4065 return value; |
4083 } | 4066 } |
4084 | 4067 |
4085 } // namespace compiler | 4068 } // namespace compiler |
4086 } // namespace internal | 4069 } // namespace internal |
4087 } // namespace v8 | 4070 } // namespace v8 |
OLD | NEW |