OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2379 // Initialize specials and locals to undefined. | 2379 // Initialize specials and locals to undefined. |
2380 for (int i = environment()->parameter_count() + 1; | 2380 for (int i = environment()->parameter_count() + 1; |
2381 i < environment()->length(); | 2381 i < environment()->length(); |
2382 ++i) { | 2382 ++i) { |
2383 environment()->Bind(i, undefined_constant); | 2383 environment()->Bind(i, undefined_constant); |
2384 } | 2384 } |
2385 | 2385 |
2386 // Handle the arguments and arguments shadow variables specially (they do | 2386 // Handle the arguments and arguments shadow variables specially (they do |
2387 // not have declarations). | 2387 // not have declarations). |
2388 if (scope->arguments() != NULL) { | 2388 if (scope->arguments() != NULL) { |
2389 if (!scope->arguments()->IsStackAllocated() || | 2389 if (!scope->arguments()->IsStackAllocated()) { |
2390 (scope->arguments_shadow() != NULL && | |
2391 !scope->arguments_shadow()->IsStackAllocated())) { | |
2392 return Bailout("context-allocated arguments"); | 2390 return Bailout("context-allocated arguments"); |
2393 } | 2391 } |
2394 HArgumentsObject* object = new(zone()) HArgumentsObject; | 2392 HArgumentsObject* object = new(zone()) HArgumentsObject; |
2395 AddInstruction(object); | 2393 AddInstruction(object); |
2396 graph()->SetArgumentsObject(object); | 2394 graph()->SetArgumentsObject(object); |
2397 environment()->Bind(scope->arguments(), object); | 2395 environment()->Bind(scope->arguments(), object); |
2398 if (scope->arguments_shadow() != NULL) { | |
2399 environment()->Bind(scope->arguments_shadow(), object); | |
2400 } | |
2401 } | 2396 } |
2402 } | 2397 } |
2403 | 2398 |
2404 | 2399 |
2405 void HGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { | 2400 void HGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { |
2406 for (int i = 0; i < statements->length(); i++) { | 2401 for (int i = 0; i < statements->length(); i++) { |
2407 CHECK_ALIVE(Visit(statements->at(i))); | 2402 CHECK_ALIVE(Visit(statements->at(i))); |
2408 } | 2403 } |
2409 } | 2404 } |
2410 | 2405 |
(...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3513 CHECK_ALIVE(VisitForValue(operation)); | 3508 CHECK_ALIVE(VisitForValue(operation)); |
3514 | 3509 |
3515 if (var->is_global()) { | 3510 if (var->is_global()) { |
3516 HandleGlobalVariableAssignment(var, | 3511 HandleGlobalVariableAssignment(var, |
3517 Top(), | 3512 Top(), |
3518 expr->position(), | 3513 expr->position(), |
3519 expr->AssignmentId()); | 3514 expr->AssignmentId()); |
3520 } else if (var->IsStackAllocated()) { | 3515 } else if (var->IsStackAllocated()) { |
3521 Bind(var, Top()); | 3516 Bind(var, Top()); |
3522 } else if (var->IsContextSlot()) { | 3517 } else if (var->IsContextSlot()) { |
| 3518 // Bail out if we try to mutate a parameter value in a function using |
| 3519 // the arguments object. We do not (yet) correctly handle the |
| 3520 // arguments property of the function. |
| 3521 if (info()->scope()->arguments() != NULL) { |
| 3522 // Parameters will rewrite to context slots. We have no direct way |
| 3523 // to detect that the variable is a parameter. |
| 3524 int count = info()->scope()->num_parameters(); |
| 3525 for (int i = 0; i < count; ++i) { |
| 3526 if (var == info()->scope()->parameter(i)) { |
| 3527 Bailout("assignment to parameter, function uses arguments object"); |
| 3528 } |
| 3529 } |
| 3530 } |
| 3531 |
3523 HValue* context = BuildContextChainWalk(var); | 3532 HValue* context = BuildContextChainWalk(var); |
3524 int index = var->AsSlot()->index(); | 3533 int index = var->AsSlot()->index(); |
3525 HStoreContextSlot* instr = | 3534 HStoreContextSlot* instr = |
3526 new(zone()) HStoreContextSlot(context, index, Top()); | 3535 new(zone()) HStoreContextSlot(context, index, Top()); |
3527 AddInstruction(instr); | 3536 AddInstruction(instr); |
3528 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3537 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
3529 } else { | 3538 } else { |
3530 return Bailout("compound assignment to lookup slot"); | 3539 return Bailout("compound assignment to lookup slot"); |
3531 } | 3540 } |
3532 ast_context()->ReturnValue(Pop()); | 3541 ast_context()->ReturnValue(Pop()); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3636 // We do not allow the arguments object to occur in a context where it | 3645 // We do not allow the arguments object to occur in a context where it |
3637 // may escape, but assignments to stack-allocated locals are | 3646 // may escape, but assignments to stack-allocated locals are |
3638 // permitted. | 3647 // permitted. |
3639 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); | 3648 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); |
3640 HValue* value = Pop(); | 3649 HValue* value = Pop(); |
3641 Bind(var, value); | 3650 Bind(var, value); |
3642 ast_context()->ReturnValue(value); | 3651 ast_context()->ReturnValue(value); |
3643 | 3652 |
3644 } else if (var->IsContextSlot()) { | 3653 } else if (var->IsContextSlot()) { |
3645 ASSERT(var->mode() != Variable::CONST); | 3654 ASSERT(var->mode() != Variable::CONST); |
| 3655 // Bail out if we try to mutate a parameter value in a function using |
| 3656 // the arguments object. We do not (yet) correctly handle the |
| 3657 // arguments property of the function. |
| 3658 if (info()->scope()->arguments() != NULL) { |
| 3659 // Parameters will rewrite to context slots. We have no direct way |
| 3660 // to detect that the variable is a parameter. |
| 3661 int count = info()->scope()->num_parameters(); |
| 3662 for (int i = 0; i < count; ++i) { |
| 3663 if (var == info()->scope()->parameter(i)) { |
| 3664 Bailout("assignment to parameter, function uses arguments object"); |
| 3665 } |
| 3666 } |
| 3667 } |
| 3668 |
3646 CHECK_ALIVE(VisitForValue(expr->value())); | 3669 CHECK_ALIVE(VisitForValue(expr->value())); |
3647 HValue* context = BuildContextChainWalk(var); | 3670 HValue* context = BuildContextChainWalk(var); |
3648 int index = var->AsSlot()->index(); | 3671 int index = var->AsSlot()->index(); |
3649 HStoreContextSlot* instr = | 3672 HStoreContextSlot* instr = |
3650 new(zone()) HStoreContextSlot(context, index, Top()); | 3673 new(zone()) HStoreContextSlot(context, index, Top()); |
3651 AddInstruction(instr); | 3674 AddInstruction(instr); |
3652 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3675 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
3653 ast_context()->ReturnValue(Pop()); | 3676 ast_context()->ReturnValue(Pop()); |
3654 | 3677 |
3655 } else if (var->is_global()) { | 3678 } else if (var->is_global()) { |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3901 val = floor_val; | 3924 val = floor_val; |
3902 break; | 3925 break; |
3903 } | 3926 } |
3904 case JSObject::EXTERNAL_FLOAT_ELEMENTS: | 3927 case JSObject::EXTERNAL_FLOAT_ELEMENTS: |
3905 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: | 3928 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: |
3906 break; | 3929 break; |
3907 | 3930 |
3908 case JSObject::FAST_ELEMENTS: | 3931 case JSObject::FAST_ELEMENTS: |
3909 case JSObject::FAST_DOUBLE_ELEMENTS: | 3932 case JSObject::FAST_DOUBLE_ELEMENTS: |
3910 case JSObject::DICTIONARY_ELEMENTS: | 3933 case JSObject::DICTIONARY_ELEMENTS: |
| 3934 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: |
3911 UNREACHABLE(); | 3935 UNREACHABLE(); |
3912 break; | 3936 break; |
3913 } | 3937 } |
3914 return new(zone()) HStoreKeyedSpecializedArrayElement( | 3938 return new(zone()) HStoreKeyedSpecializedArrayElement( |
3915 external_elements, | 3939 external_elements, |
3916 checked_key, | 3940 checked_key, |
3917 val, | 3941 val, |
3918 map->elements_kind()); | 3942 map->elements_kind()); |
3919 } | 3943 } |
3920 | 3944 |
(...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4797 var->AsSlot() != NULL && | 4821 var->AsSlot() != NULL && |
4798 var->AsSlot()->type() != Slot::LOOKUP) { | 4822 var->AsSlot()->type() != Slot::LOOKUP) { |
4799 // Result of deleting non-global, non-dynamic variables is false. | 4823 // Result of deleting non-global, non-dynamic variables is false. |
4800 // The subexpression does not have side effects. | 4824 // The subexpression does not have side effects. |
4801 ast_context()->ReturnValue(graph()->GetConstantFalse()); | 4825 ast_context()->ReturnValue(graph()->GetConstantFalse()); |
4802 } else if (prop != NULL) { | 4826 } else if (prop != NULL) { |
4803 if (prop->is_synthetic()) { | 4827 if (prop->is_synthetic()) { |
4804 // Result of deleting parameters is false, even when they rewrite | 4828 // Result of deleting parameters is false, even when they rewrite |
4805 // to accesses on the arguments object. | 4829 // to accesses on the arguments object. |
4806 ast_context()->ReturnValue(graph()->GetConstantFalse()); | 4830 ast_context()->ReturnValue(graph()->GetConstantFalse()); |
4807 } else { | 4831 } else { |
4808 CHECK_ALIVE(VisitForValue(prop->obj())); | 4832 CHECK_ALIVE(VisitForValue(prop->obj())); |
4809 CHECK_ALIVE(VisitForValue(prop->key())); | 4833 CHECK_ALIVE(VisitForValue(prop->key())); |
4810 HValue* key = Pop(); | 4834 HValue* key = Pop(); |
4811 HValue* obj = Pop(); | 4835 HValue* obj = Pop(); |
4812 HDeleteProperty* instr = new(zone()) HDeleteProperty(obj, key); | 4836 HDeleteProperty* instr = new(zone()) HDeleteProperty(obj, key); |
4813 ast_context()->ReturnInstruction(instr, expr->id()); | 4837 ast_context()->ReturnInstruction(instr, expr->id()); |
4814 } | 4838 } |
4815 } else if (var->is_global()) { | 4839 } else if (var->is_global()) { |
4816 Bailout("delete with global variable"); | 4840 Bailout("delete with global variable"); |
4817 } else { | 4841 } else { |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4982 Push(after); | 5006 Push(after); |
4983 | 5007 |
4984 if (var->is_global()) { | 5008 if (var->is_global()) { |
4985 HandleGlobalVariableAssignment(var, | 5009 HandleGlobalVariableAssignment(var, |
4986 after, | 5010 after, |
4987 expr->position(), | 5011 expr->position(), |
4988 expr->AssignmentId()); | 5012 expr->AssignmentId()); |
4989 } else if (var->IsStackAllocated()) { | 5013 } else if (var->IsStackAllocated()) { |
4990 Bind(var, after); | 5014 Bind(var, after); |
4991 } else if (var->IsContextSlot()) { | 5015 } else if (var->IsContextSlot()) { |
| 5016 // Bail out if we try to mutate a parameter value in a function using |
| 5017 // the arguments object. We do not (yet) correctly handle the |
| 5018 // arguments property of the function. |
| 5019 if (info()->scope()->arguments() != NULL) { |
| 5020 // Parameters will rewrite to context slots. We have no direct way |
| 5021 // to detect that the variable is a parameter. |
| 5022 int count = info()->scope()->num_parameters(); |
| 5023 for (int i = 0; i < count; ++i) { |
| 5024 if (var == info()->scope()->parameter(i)) { |
| 5025 Bailout("assignment to parameter, function uses arguments object"); |
| 5026 } |
| 5027 } |
| 5028 } |
| 5029 |
4992 HValue* context = BuildContextChainWalk(var); | 5030 HValue* context = BuildContextChainWalk(var); |
4993 int index = var->AsSlot()->index(); | 5031 int index = var->AsSlot()->index(); |
4994 HStoreContextSlot* instr = | 5032 HStoreContextSlot* instr = |
4995 new(zone()) HStoreContextSlot(context, index, after); | 5033 new(zone()) HStoreContextSlot(context, index, after); |
4996 AddInstruction(instr); | 5034 AddInstruction(instr); |
4997 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 5035 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
4998 } else { | 5036 } else { |
4999 return Bailout("lookup variable in count operation"); | 5037 return Bailout("lookup variable in count operation"); |
5000 } | 5038 } |
5001 | 5039 |
(...skipping 1405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6407 } | 6445 } |
6408 } | 6446 } |
6409 | 6447 |
6410 #ifdef DEBUG | 6448 #ifdef DEBUG |
6411 if (graph_ != NULL) graph_->Verify(); | 6449 if (graph_ != NULL) graph_->Verify(); |
6412 if (allocator_ != NULL) allocator_->Verify(); | 6450 if (allocator_ != NULL) allocator_->Verify(); |
6413 #endif | 6451 #endif |
6414 } | 6452 } |
6415 | 6453 |
6416 } } // namespace v8::internal | 6454 } } // namespace v8::internal |
OLD | NEW |