| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 2479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2490 } | 2490 } |
| 2491 exit.Bind(); | 2491 exit.Bind(); |
| 2492 } | 2492 } |
| 2493 | 2493 |
| 2494 | 2494 |
| 2495 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { | 2495 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { |
| 2496 if (slot->type() == Slot::LOOKUP) { | 2496 if (slot->type() == Slot::LOOKUP) { |
| 2497 ASSERT(slot->var()->mode() == Variable::DYNAMIC); | 2497 ASSERT(slot->var()->mode() == Variable::DYNAMIC); |
| 2498 | 2498 |
| 2499 // For now, just do a runtime call. | 2499 // For now, just do a runtime call. |
| 2500 frame_->SpillAll(); |
| 2500 frame_->EmitPush(esi); | 2501 frame_->EmitPush(esi); |
| 2501 frame_->EmitPush(Immediate(slot->var()->name())); | 2502 frame_->EmitPush(Immediate(slot->var()->name())); |
| 2502 | 2503 |
| 2503 if (typeof_state == INSIDE_TYPEOF) { | 2504 if (typeof_state == INSIDE_TYPEOF) { |
| 2504 frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 2505 frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
| 2505 } else { | 2506 } else { |
| 2506 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); | 2507 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); |
| 2507 } | 2508 } |
| 2508 frame_->EmitPush(eax); | 2509 frame_->EmitPush(eax); |
| 2509 | 2510 |
| 2510 } else { | 2511 } else { |
| 2511 // Note: We would like to keep the assert below, but it fires because of | 2512 // Note: We would like to keep the assert below, but it fires because of |
| 2512 // some nasty code in LoadTypeofExpression() which should be removed... | 2513 // some nasty code in LoadTypeofExpression() which should be removed... |
| 2513 // ASSERT(slot->var()->mode() != Variable::DYNAMIC); | 2514 // ASSERT(slot->var()->mode() != Variable::DYNAMIC); |
| 2514 if (slot->var()->mode() == Variable::CONST) { | 2515 if (slot->var()->mode() == Variable::CONST) { |
| 2515 // Const slots may contain 'the hole' value (the constant hasn't been | 2516 // Const slots may contain 'the hole' value (the constant hasn't been |
| 2516 // initialized yet) which needs to be converted into the 'undefined' | 2517 // initialized yet) which needs to be converted into the 'undefined' |
| 2517 // value. | 2518 // value. |
| 2519 frame_->SpillAll(); |
| 2518 Comment cmnt(masm_, "[ Load const"); | 2520 Comment cmnt(masm_, "[ Load const"); |
| 2519 JumpTarget exit(this); | 2521 JumpTarget exit(this); |
| 2520 __ mov(eax, SlotOperand(slot, ecx)); | 2522 __ mov(eax, SlotOperand(slot, ecx)); |
| 2521 __ cmp(eax, Factory::the_hole_value()); | 2523 __ cmp(eax, Factory::the_hole_value()); |
| 2522 exit.Branch(not_equal); | 2524 exit.Branch(not_equal); |
| 2523 __ mov(eax, Factory::undefined_value()); | 2525 __ mov(eax, Factory::undefined_value()); |
| 2524 exit.Bind(); | 2526 exit.Bind(); |
| 2525 frame_->EmitPush(eax); | 2527 frame_->EmitPush(eax); |
| 2526 } else { | 2528 } else { |
| 2527 frame_->EmitPush(SlotOperand(slot, ecx)); | 2529 if (slot->type() == Slot::PARAMETER) { |
| 2530 frame_->LoadParameterAt(slot->index()); |
| 2531 } else if (slot->type() == Slot::LOCAL) { |
| 2532 frame_->LoadLocalAt(slot->index()); |
| 2533 } else { |
| 2534 // The other remaining slot types (LOOKUP and GLOBAL) cannot reach |
| 2535 // here. |
| 2536 ASSERT(slot->type() == Slot::CONTEXT); |
| 2537 frame_->SpillAll(); |
| 2538 frame_->EmitPush(SlotOperand(slot, ecx)); |
| 2539 } |
| 2528 } | 2540 } |
| 2529 } | 2541 } |
| 2530 } | 2542 } |
| 2531 | 2543 |
| 2532 | 2544 |
| 2533 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) { | 2545 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) { |
| 2534 if (slot->type() == Slot::LOOKUP) { | 2546 if (slot->type() == Slot::LOOKUP) { |
| 2535 ASSERT(slot->var()->mode() == Variable::DYNAMIC); | 2547 ASSERT(slot->var()->mode() == Variable::DYNAMIC); |
| 2536 | 2548 |
| 2537 // For now, just do a runtime call. | 2549 // For now, just do a runtime call. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2605 // to bind the exit label. Doing so can defeat peephole | 2617 // to bind the exit label. Doing so can defeat peephole |
| 2606 // optimization. | 2618 // optimization. |
| 2607 if (init_state == CONST_INIT) { | 2619 if (init_state == CONST_INIT) { |
| 2608 exit.Bind(); | 2620 exit.Bind(); |
| 2609 } | 2621 } |
| 2610 } | 2622 } |
| 2611 } | 2623 } |
| 2612 | 2624 |
| 2613 | 2625 |
| 2614 void CodeGenerator::VisitSlot(Slot* node) { | 2626 void CodeGenerator::VisitSlot(Slot* node) { |
| 2615 frame_->SpillAll(); | |
| 2616 Comment cmnt(masm_, "[ Slot"); | 2627 Comment cmnt(masm_, "[ Slot"); |
| 2617 LoadFromSlot(node, typeof_state()); | 2628 LoadFromSlot(node, typeof_state()); |
| 2618 } | 2629 } |
| 2619 | 2630 |
| 2620 | 2631 |
| 2621 void CodeGenerator::VisitVariableProxy(VariableProxy* node) { | 2632 void CodeGenerator::VisitVariableProxy(VariableProxy* node) { |
| 2622 frame_->SpillAll(); | |
| 2623 Comment cmnt(masm_, "[ VariableProxy"); | 2633 Comment cmnt(masm_, "[ VariableProxy"); |
| 2624 Variable* var = node->var(); | 2634 Variable* var = node->var(); |
| 2625 Expression* expr = var->rewrite(); | 2635 Expression* expr = var->rewrite(); |
| 2626 if (expr != NULL) { | 2636 if (expr != NULL) { |
| 2627 // We have to be wary of calling Visit directly on expressions. Because | 2637 // We have to be wary of calling Visit directly on expressions. Because |
| 2628 // of special casing comparisons of the form typeof<expr> === "string", | 2638 // of special casing comparisons of the form typeof<expr> === "string", |
| 2629 // we can return from a call from Visit (to a comparison or a unary | 2639 // we can return from a call from Visit (to a comparison or a unary |
| 2630 // operation) without a virtual frame; which will probably crash if we | 2640 // operation) without a virtual frame; which will probably crash if we |
| 2631 // try to emit frame code before reestablishing a frame. Here we're | 2641 // try to emit frame code before reestablishing a frame. Here we're |
| 2632 // safe as long as variable proxies can't rewrite into typeof | 2642 // safe as long as variable proxies can't rewrite into typeof |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2913 } | 2923 } |
| 2914 | 2924 |
| 2915 if (node->op() == Token::ASSIGN || | 2925 if (node->op() == Token::ASSIGN || |
| 2916 node->op() == Token::INIT_VAR || | 2926 node->op() == Token::INIT_VAR || |
| 2917 node->op() == Token::INIT_CONST) { | 2927 node->op() == Token::INIT_CONST) { |
| 2918 Load(node->value()); | 2928 Load(node->value()); |
| 2919 | 2929 |
| 2920 } else { | 2930 } else { |
| 2921 frame_->SpillAll(); | 2931 frame_->SpillAll(); |
| 2922 target.GetValue(NOT_INSIDE_TYPEOF); | 2932 target.GetValue(NOT_INSIDE_TYPEOF); |
| 2933 frame_->SpillAll(); |
| 2923 Literal* literal = node->value()->AsLiteral(); | 2934 Literal* literal = node->value()->AsLiteral(); |
| 2924 if (IsInlineSmi(literal)) { | 2935 if (IsInlineSmi(literal)) { |
| 2925 SmiOperation(node->binary_op(), node->type(), literal->handle(), false, | 2936 SmiOperation(node->binary_op(), node->type(), literal->handle(), false, |
| 2926 NO_OVERWRITE); | 2937 NO_OVERWRITE); |
| 2927 } else { | 2938 } else { |
| 2928 Load(node->value()); | 2939 Load(node->value()); |
| 2929 frame_->SpillAll(); | 2940 frame_->SpillAll(); |
| 2930 GenericBinaryOperation(node->binary_op(), node->type()); | 2941 GenericBinaryOperation(node->binary_op(), node->type()); |
| 2931 } | 2942 } |
| 2932 } | 2943 } |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3076 __ mov(frame_->Top(), eax); | 3087 __ mov(frame_->Top(), eax); |
| 3077 | 3088 |
| 3078 } else { | 3089 } else { |
| 3079 // ------------------------------------------- | 3090 // ------------------------------------------- |
| 3080 // JavaScript example: 'array[index](1, 2, 3)' | 3091 // JavaScript example: 'array[index](1, 2, 3)' |
| 3081 // ------------------------------------------- | 3092 // ------------------------------------------- |
| 3082 | 3093 |
| 3083 // Load the function to call from the property through a reference. | 3094 // Load the function to call from the property through a reference. |
| 3084 Reference ref(this, property); | 3095 Reference ref(this, property); |
| 3085 ref.GetValue(NOT_INSIDE_TYPEOF); | 3096 ref.GetValue(NOT_INSIDE_TYPEOF); |
| 3097 frame_->SpillAll(); |
| 3086 | 3098 |
| 3087 // Pass receiver to called function. | 3099 // Pass receiver to called function. |
| 3088 // The reference's size is non-negative. | 3100 // The reference's size is non-negative. |
| 3089 frame_->EmitPush(frame_->ElementAt(ref.size())); | 3101 frame_->EmitPush(frame_->ElementAt(ref.size())); |
| 3090 | 3102 |
| 3091 // Call the function. | 3103 // Call the function. |
| 3092 CallWithArguments(args, node->position()); | 3104 CallWithArguments(args, node->position()); |
| 3093 } | 3105 } |
| 3094 | 3106 |
| 3095 } else { | 3107 } else { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3237 ASSERT(args->length() == 2); | 3249 ASSERT(args->length() == 2); |
| 3238 | 3250 |
| 3239 JumpTarget slow_case(this); | 3251 JumpTarget slow_case(this); |
| 3240 JumpTarget end(this); | 3252 JumpTarget end(this); |
| 3241 JumpTarget not_a_flat_string(this); | 3253 JumpTarget not_a_flat_string(this); |
| 3242 JumpTarget not_a_cons_string_either(this); | 3254 JumpTarget not_a_cons_string_either(this); |
| 3243 JumpTarget try_again_with_new_string(this); | 3255 JumpTarget try_again_with_new_string(this); |
| 3244 JumpTarget ascii_string(this); | 3256 JumpTarget ascii_string(this); |
| 3245 JumpTarget got_char_code(this); | 3257 JumpTarget got_char_code(this); |
| 3246 | 3258 |
| 3247 // Load the string into eax. | 3259 // Load the string into eax and the index into ebx. |
| 3248 Load(args->at(0)); | 3260 Load(args->at(0)); |
| 3249 frame_->SpillAll(); | 3261 frame_->SpillAll(); |
| 3262 Load(args->at(1)); |
| 3263 frame_->SpillAll(); |
| 3264 frame_->EmitPop(ebx); |
| 3250 frame_->EmitPop(eax); | 3265 frame_->EmitPop(eax); |
| 3251 // If the receiver is a smi return undefined. | 3266 // If the receiver is a smi return undefined. |
| 3252 ASSERT(kSmiTag == 0); | 3267 ASSERT(kSmiTag == 0); |
| 3253 __ test(eax, Immediate(kSmiTagMask)); | 3268 __ test(eax, Immediate(kSmiTagMask)); |
| 3254 slow_case.Branch(zero, not_taken); | 3269 slow_case.Branch(zero, not_taken); |
| 3255 | 3270 |
| 3256 // Load the index into ebx. | |
| 3257 Load(args->at(1)); | |
| 3258 frame_->SpillAll(); | |
| 3259 frame_->EmitPop(ebx); | |
| 3260 | |
| 3261 // Check for negative or non-smi index. | 3271 // Check for negative or non-smi index. |
| 3262 ASSERT(kSmiTag == 0); | 3272 ASSERT(kSmiTag == 0); |
| 3263 __ test(ebx, Immediate(kSmiTagMask | 0x80000000)); | 3273 __ test(ebx, Immediate(kSmiTagMask | 0x80000000)); |
| 3264 slow_case.Branch(not_zero, not_taken); | 3274 slow_case.Branch(not_zero, not_taken); |
| 3265 // Get rid of the smi tag on the index. | 3275 // Get rid of the smi tag on the index. |
| 3266 __ sar(ebx, kSmiTagSize); | 3276 __ sar(ebx, kSmiTagSize); |
| 3267 | 3277 |
| 3268 try_again_with_new_string.Bind(); | 3278 try_again_with_new_string.Bind(); |
| 3269 // Get the type of the heap object into edi. | 3279 // Get the type of the heap object into edi. |
| 3270 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); | 3280 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3744 { Reference target(this, node->expression()); | 3754 { Reference target(this, node->expression()); |
| 3745 if (target.is_illegal()) { | 3755 if (target.is_illegal()) { |
| 3746 // Spoof the virtual frame to have the expected height (one higher | 3756 // Spoof the virtual frame to have the expected height (one higher |
| 3747 // than on entry). | 3757 // than on entry). |
| 3748 if (!is_postfix) { | 3758 if (!is_postfix) { |
| 3749 frame_->EmitPush(Immediate(Smi::FromInt(0))); | 3759 frame_->EmitPush(Immediate(Smi::FromInt(0))); |
| 3750 } | 3760 } |
| 3751 return; | 3761 return; |
| 3752 } | 3762 } |
| 3753 target.GetValue(NOT_INSIDE_TYPEOF); | 3763 target.GetValue(NOT_INSIDE_TYPEOF); |
| 3764 frame_->SpillAll(); |
| 3754 | 3765 |
| 3755 CountOperationDeferred* deferred = | 3766 CountOperationDeferred* deferred = |
| 3756 new CountOperationDeferred(this, is_postfix, is_increment, | 3767 new CountOperationDeferred(this, is_postfix, is_increment, |
| 3757 target.size() * kPointerSize); | 3768 target.size() * kPointerSize); |
| 3758 | 3769 |
| 3759 frame_->EmitPop(eax); // Load TOS into eax for calculations below | 3770 frame_->EmitPop(eax); // Load TOS into eax for calculations below |
| 3760 | 3771 |
| 3761 // Postfix: Store the old value as the result. | 3772 // Postfix: Store the old value as the result. |
| 3762 if (is_postfix) { | 3773 if (is_postfix) { |
| 3763 __ mov(frame_->ElementAt(target.size()), eax); | 3774 __ mov(frame_->ElementAt(target.size()), eax); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3950 | 3961 |
| 3951 void Generate(MacroAssembler* masm); | 3962 void Generate(MacroAssembler* masm); |
| 3952 | 3963 |
| 3953 private: | 3964 private: |
| 3954 Major MajorKey() { return Instanceof; } | 3965 Major MajorKey() { return Instanceof; } |
| 3955 int MinorKey() { return 0; } | 3966 int MinorKey() { return 0; } |
| 3956 }; | 3967 }; |
| 3957 | 3968 |
| 3958 | 3969 |
| 3959 void CodeGenerator::VisitCompareOperation(CompareOperation* node) { | 3970 void CodeGenerator::VisitCompareOperation(CompareOperation* node) { |
| 3960 frame_->SpillAll(); | |
| 3961 Comment cmnt(masm_, "[ CompareOperation"); | 3971 Comment cmnt(masm_, "[ CompareOperation"); |
| 3962 | 3972 |
| 3963 // Get the expressions from the node. | 3973 // Get the expressions from the node. |
| 3964 Expression* left = node->left(); | 3974 Expression* left = node->left(); |
| 3965 Expression* right = node->right(); | 3975 Expression* right = node->right(); |
| 3966 Token::Value op = node->op(); | 3976 Token::Value op = node->op(); |
| 3967 | 3977 |
| 3968 // To make null checks efficient, we check if either left or right is the | 3978 // To make null checks efficient, we check if either left or right is the |
| 3969 // literal 'null'. If so, we optimize the code by inlining a null check | 3979 // literal 'null'. If so, we optimize the code by inlining a null check |
| 3970 // instead of calling the (very) general runtime routine for checking | 3980 // instead of calling the (very) general runtime routine for checking |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4009 // 'typeof <expression> == <string>'. | 4019 // 'typeof <expression> == <string>'. |
| 4010 UnaryOperation* operation = left->AsUnaryOperation(); | 4020 UnaryOperation* operation = left->AsUnaryOperation(); |
| 4011 if ((op == Token::EQ || op == Token::EQ_STRICT) && | 4021 if ((op == Token::EQ || op == Token::EQ_STRICT) && |
| 4012 (operation != NULL && operation->op() == Token::TYPEOF) && | 4022 (operation != NULL && operation->op() == Token::TYPEOF) && |
| 4013 (right->AsLiteral() != NULL && | 4023 (right->AsLiteral() != NULL && |
| 4014 right->AsLiteral()->handle()->IsString())) { | 4024 right->AsLiteral()->handle()->IsString())) { |
| 4015 Handle<String> check(String::cast(*right->AsLiteral()->handle())); | 4025 Handle<String> check(String::cast(*right->AsLiteral()->handle())); |
| 4016 | 4026 |
| 4017 // Load the operand and move it to register edx. | 4027 // Load the operand and move it to register edx. |
| 4018 LoadTypeofExpression(operation->expression()); | 4028 LoadTypeofExpression(operation->expression()); |
| 4029 frame_->SpillAll(); |
| 4019 frame_->EmitPop(edx); | 4030 frame_->EmitPop(edx); |
| 4020 | 4031 |
| 4021 if (check->Equals(Heap::number_symbol())) { | 4032 if (check->Equals(Heap::number_symbol())) { |
| 4022 __ test(edx, Immediate(kSmiTagMask)); | 4033 __ test(edx, Immediate(kSmiTagMask)); |
| 4023 true_target()->Branch(zero); | 4034 true_target()->Branch(zero); |
| 4024 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset)); | 4035 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset)); |
| 4025 __ cmp(edx, Factory::heap_number_map()); | 4036 __ cmp(edx, Factory::heap_number_map()); |
| 4026 cc_reg_ = equal; | 4037 cc_reg_ = equal; |
| 4027 | 4038 |
| 4028 } else if (check->Equals(Heap::string_symbol())) { | 4039 } else if (check->Equals(Heap::string_symbol())) { |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4218 cgen_->LoadFromSlot(slot, typeof_state); | 4229 cgen_->LoadFromSlot(slot, typeof_state); |
| 4219 break; | 4230 break; |
| 4220 } | 4231 } |
| 4221 | 4232 |
| 4222 case NAMED: { | 4233 case NAMED: { |
| 4223 // TODO(1241834): Make sure that this it is safe to ignore the | 4234 // TODO(1241834): Make sure that this it is safe to ignore the |
| 4224 // distinction between expressions in a typeof and not in a typeof. If | 4235 // distinction between expressions in a typeof and not in a typeof. If |
| 4225 // there is a chance that reference errors can be thrown below, we | 4236 // there is a chance that reference errors can be thrown below, we |
| 4226 // must distinguish between the two kinds of loads (typeof expression | 4237 // must distinguish between the two kinds of loads (typeof expression |
| 4227 // loads must not throw a reference error). | 4238 // loads must not throw a reference error). |
| 4239 frame->SpillAll(); |
| 4228 Comment cmnt(masm, "[ Load from named Property"); | 4240 Comment cmnt(masm, "[ Load from named Property"); |
| 4229 Handle<String> name(GetName()); | 4241 Handle<String> name(GetName()); |
| 4230 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 4242 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 4231 // Setup the name register. | 4243 // Setup the name register. |
| 4232 __ mov(ecx, name); | 4244 __ mov(ecx, name); |
| 4233 | 4245 |
| 4234 Variable* var = expression_->AsVariableProxy()->AsVariable(); | 4246 Variable* var = expression_->AsVariableProxy()->AsVariable(); |
| 4235 if (var != NULL) { | 4247 if (var != NULL) { |
| 4236 ASSERT(var->is_global()); | 4248 ASSERT(var->is_global()); |
| 4237 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET_CONTEXT, 0); | 4249 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET_CONTEXT, 0); |
| 4238 } else { | 4250 } else { |
| 4239 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); | 4251 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); |
| 4240 } | 4252 } |
| 4241 frame->EmitPush(eax); // IC call leaves result in eax, push it out | 4253 frame->EmitPush(eax); // IC call leaves result in eax, push it out |
| 4242 break; | 4254 break; |
| 4243 } | 4255 } |
| 4244 | 4256 |
| 4245 case KEYED: { | 4257 case KEYED: { |
| 4246 // TODO(1241834): Make sure that this it is safe to ignore the | 4258 // TODO(1241834): Make sure that this it is safe to ignore the |
| 4247 // distinction between expressions in a typeof and not in a typeof. | 4259 // distinction between expressions in a typeof and not in a typeof. |
| 4260 frame->SpillAll(); |
| 4248 Comment cmnt(masm, "[ Load from keyed Property"); | 4261 Comment cmnt(masm, "[ Load from keyed Property"); |
| 4249 Property* property = expression_->AsProperty(); | 4262 Property* property = expression_->AsProperty(); |
| 4250 ASSERT(property != NULL); | 4263 ASSERT(property != NULL); |
| 4251 __ RecordPosition(property->position()); | 4264 __ RecordPosition(property->position()); |
| 4252 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 4265 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 4253 | 4266 |
| 4254 Variable* var = expression_->AsVariableProxy()->AsVariable(); | 4267 Variable* var = expression_->AsVariableProxy()->AsVariable(); |
| 4255 if (var != NULL) { | 4268 if (var != NULL) { |
| 4256 ASSERT(var->is_global()); | 4269 ASSERT(var->is_global()); |
| 4257 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET_CONTEXT, 0); | 4270 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET_CONTEXT, 0); |
| (...skipping 1434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5692 | 5705 |
| 5693 // Slow-case: Go through the JavaScript implementation. | 5706 // Slow-case: Go through the JavaScript implementation. |
| 5694 __ bind(&slow); | 5707 __ bind(&slow); |
| 5695 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 5708 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
| 5696 } | 5709 } |
| 5697 | 5710 |
| 5698 | 5711 |
| 5699 #undef __ | 5712 #undef __ |
| 5700 | 5713 |
| 5701 } } // namespace v8::internal | 5714 } } // namespace v8::internal |
| OLD | NEW |