| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 | 779 |
| 780 | 780 |
| 781 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { | 781 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { |
| 782 // The variable in the declaration always resides in the current function | 782 // The variable in the declaration always resides in the current function |
| 783 // context. | 783 // context. |
| 784 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); | 784 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); |
| 785 if (generate_debug_code_) { | 785 if (generate_debug_code_) { |
| 786 // Check that we're not inside a with or catch context. | 786 // Check that we're not inside a with or catch context. |
| 787 __ ldr(r1, FieldMemOperand(cp, HeapObject::kMapOffset)); | 787 __ ldr(r1, FieldMemOperand(cp, HeapObject::kMapOffset)); |
| 788 __ CompareRoot(r1, Heap::kWithContextMapRootIndex); | 788 __ CompareRoot(r1, Heap::kWithContextMapRootIndex); |
| 789 __ Check(ne, kDeclarationInWithContext); | 789 __ Check(ne, "Declaration in with context."); |
| 790 __ CompareRoot(r1, Heap::kCatchContextMapRootIndex); | 790 __ CompareRoot(r1, Heap::kCatchContextMapRootIndex); |
| 791 __ Check(ne, kDeclarationInCatchContext); | 791 __ Check(ne, "Declaration in catch context."); |
| 792 } | 792 } |
| 793 } | 793 } |
| 794 | 794 |
| 795 | 795 |
| 796 void FullCodeGenerator::VisitVariableDeclaration( | 796 void FullCodeGenerator::VisitVariableDeclaration( |
| 797 VariableDeclaration* declaration) { | 797 VariableDeclaration* declaration) { |
| 798 // If it was not possible to allocate the variable at compile time, we | 798 // If it was not possible to allocate the variable at compile time, we |
| 799 // need to "declare" it at runtime to make sure it actually exists in the | 799 // need to "declare" it at runtime to make sure it actually exists in the |
| 800 // local context. | 800 // local context. |
| 801 VariableProxy* proxy = declaration->proxy(); | 801 VariableProxy* proxy = declaration->proxy(); |
| (...skipping 1703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2505 | 2505 |
| 2506 } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) { | 2506 } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) { |
| 2507 // Assignment to var or initializing assignment to let/const | 2507 // Assignment to var or initializing assignment to let/const |
| 2508 // in harmony mode. | 2508 // in harmony mode. |
| 2509 if (var->IsStackAllocated() || var->IsContextSlot()) { | 2509 if (var->IsStackAllocated() || var->IsContextSlot()) { |
| 2510 MemOperand location = VarOperand(var, r1); | 2510 MemOperand location = VarOperand(var, r1); |
| 2511 if (generate_debug_code_ && op == Token::INIT_LET) { | 2511 if (generate_debug_code_ && op == Token::INIT_LET) { |
| 2512 // Check for an uninitialized let binding. | 2512 // Check for an uninitialized let binding. |
| 2513 __ ldr(r2, location); | 2513 __ ldr(r2, location); |
| 2514 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); | 2514 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); |
| 2515 __ Check(eq, kLetBindingReInitialization); | 2515 __ Check(eq, "Let binding re-initialization."); |
| 2516 } | 2516 } |
| 2517 // Perform the assignment. | 2517 // Perform the assignment. |
| 2518 __ str(r0, location); | 2518 __ str(r0, location); |
| 2519 if (var->IsContextSlot()) { | 2519 if (var->IsContextSlot()) { |
| 2520 __ mov(r3, r0); | 2520 __ mov(r3, r0); |
| 2521 int offset = Context::SlotOffset(var->index()); | 2521 int offset = Context::SlotOffset(var->index()); |
| 2522 __ RecordWriteContextSlot( | 2522 __ RecordWriteContextSlot( |
| 2523 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs); | 2523 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs); |
| 2524 } | 2524 } |
| 2525 } else { | 2525 } else { |
| (...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3466 __ bind(&done); | 3466 __ bind(&done); |
| 3467 context()->Plug(r0); | 3467 context()->Plug(r0); |
| 3468 } | 3468 } |
| 3469 | 3469 |
| 3470 | 3470 |
| 3471 void FullCodeGenerator::EmitSeqStringSetCharCheck(Register string, | 3471 void FullCodeGenerator::EmitSeqStringSetCharCheck(Register string, |
| 3472 Register index, | 3472 Register index, |
| 3473 Register value, | 3473 Register value, |
| 3474 uint32_t encoding_mask) { | 3474 uint32_t encoding_mask) { |
| 3475 __ SmiTst(index); | 3475 __ SmiTst(index); |
| 3476 __ Check(eq, kNonSmiIndex); | 3476 __ Check(eq, "Non-smi index"); |
| 3477 __ SmiTst(value); | 3477 __ SmiTst(value); |
| 3478 __ Check(eq, kNonSmiValue); | 3478 __ Check(eq, "Non-smi value"); |
| 3479 | 3479 |
| 3480 __ ldr(ip, FieldMemOperand(string, String::kLengthOffset)); | 3480 __ ldr(ip, FieldMemOperand(string, String::kLengthOffset)); |
| 3481 __ cmp(index, ip); | 3481 __ cmp(index, ip); |
| 3482 __ Check(lt, kIndexIsTooLarge); | 3482 __ Check(lt, "Index is too large"); |
| 3483 | 3483 |
| 3484 __ cmp(index, Operand(Smi::FromInt(0))); | 3484 __ cmp(index, Operand(Smi::FromInt(0))); |
| 3485 __ Check(ge, kIndexIsNegative); | 3485 __ Check(ge, "Index is negative"); |
| 3486 | 3486 |
| 3487 __ ldr(ip, FieldMemOperand(string, HeapObject::kMapOffset)); | 3487 __ ldr(ip, FieldMemOperand(string, HeapObject::kMapOffset)); |
| 3488 __ ldrb(ip, FieldMemOperand(ip, Map::kInstanceTypeOffset)); | 3488 __ ldrb(ip, FieldMemOperand(ip, Map::kInstanceTypeOffset)); |
| 3489 | 3489 |
| 3490 __ and_(ip, ip, Operand(kStringRepresentationMask | kStringEncodingMask)); | 3490 __ and_(ip, ip, Operand(kStringRepresentationMask | kStringEncodingMask)); |
| 3491 __ cmp(ip, Operand(encoding_mask)); | 3491 __ cmp(ip, Operand(encoding_mask)); |
| 3492 __ Check(eq, kUnexpectedStringType); | 3492 __ Check(eq, "Unexpected string type"); |
| 3493 } | 3493 } |
| 3494 | 3494 |
| 3495 | 3495 |
| 3496 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { | 3496 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { |
| 3497 ZoneList<Expression*>* args = expr->arguments(); | 3497 ZoneList<Expression*>* args = expr->arguments(); |
| 3498 ASSERT_EQ(3, args->length()); | 3498 ASSERT_EQ(3, args->length()); |
| 3499 | 3499 |
| 3500 Register string = r0; | 3500 Register string = r0; |
| 3501 Register index = r1; | 3501 Register index = r1; |
| 3502 Register value = r2; | 3502 Register value = r2; |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3842 | 3842 |
| 3843 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { | 3843 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { |
| 3844 ZoneList<Expression*>* args = expr->arguments(); | 3844 ZoneList<Expression*>* args = expr->arguments(); |
| 3845 ASSERT_EQ(2, args->length()); | 3845 ASSERT_EQ(2, args->length()); |
| 3846 ASSERT_NE(NULL, args->at(0)->AsLiteral()); | 3846 ASSERT_NE(NULL, args->at(0)->AsLiteral()); |
| 3847 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value(); | 3847 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value(); |
| 3848 | 3848 |
| 3849 Handle<FixedArray> jsfunction_result_caches( | 3849 Handle<FixedArray> jsfunction_result_caches( |
| 3850 isolate()->native_context()->jsfunction_result_caches()); | 3850 isolate()->native_context()->jsfunction_result_caches()); |
| 3851 if (jsfunction_result_caches->length() <= cache_id) { | 3851 if (jsfunction_result_caches->length() <= cache_id) { |
| 3852 __ Abort(kAttemptToUseUndefinedCache); | 3852 __ Abort("Attempt to use undefined cache."); |
| 3853 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 3853 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
| 3854 context()->Plug(r0); | 3854 context()->Plug(r0); |
| 3855 return; | 3855 return; |
| 3856 } | 3856 } |
| 3857 | 3857 |
| 3858 VisitForAccumulatorValue(args->at(1)); | 3858 VisitForAccumulatorValue(args->at(1)); |
| 3859 | 3859 |
| 3860 Register key = r0; | 3860 Register key = r0; |
| 3861 Register cache = r1; | 3861 Register cache = r1; |
| 3862 __ ldr(cache, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); | 3862 __ ldr(cache, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4023 // Loop condition: while (element < elements_end). | 4023 // Loop condition: while (element < elements_end). |
| 4024 // Live values in registers: | 4024 // Live values in registers: |
| 4025 // elements: Fixed array of strings. | 4025 // elements: Fixed array of strings. |
| 4026 // array_length: Length of the fixed array of strings (not smi) | 4026 // array_length: Length of the fixed array of strings (not smi) |
| 4027 // separator: Separator string | 4027 // separator: Separator string |
| 4028 // string_length: Accumulated sum of string lengths (smi). | 4028 // string_length: Accumulated sum of string lengths (smi). |
| 4029 // element: Current array element. | 4029 // element: Current array element. |
| 4030 // elements_end: Array end. | 4030 // elements_end: Array end. |
| 4031 if (generate_debug_code_) { | 4031 if (generate_debug_code_) { |
| 4032 __ cmp(array_length, Operand::Zero()); | 4032 __ cmp(array_length, Operand::Zero()); |
| 4033 __ Assert(gt, kNoEmptyArraysHereInEmitFastAsciiArrayJoin); | 4033 __ Assert(gt, "No empty arrays here in EmitFastAsciiArrayJoin"); |
| 4034 } | 4034 } |
| 4035 __ bind(&loop); | 4035 __ bind(&loop); |
| 4036 __ ldr(string, MemOperand(element, kPointerSize, PostIndex)); | 4036 __ ldr(string, MemOperand(element, kPointerSize, PostIndex)); |
| 4037 __ JumpIfSmi(string, &bailout); | 4037 __ JumpIfSmi(string, &bailout); |
| 4038 __ ldr(scratch1, FieldMemOperand(string, HeapObject::kMapOffset)); | 4038 __ ldr(scratch1, FieldMemOperand(string, HeapObject::kMapOffset)); |
| 4039 __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); | 4039 __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); |
| 4040 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout); | 4040 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout); |
| 4041 __ ldr(scratch1, FieldMemOperand(string, SeqOneByteString::kLengthOffset)); | 4041 __ ldr(scratch1, FieldMemOperand(string, SeqOneByteString::kLengthOffset)); |
| 4042 __ add(string_length, string_length, Operand(scratch1), SetCC); | 4042 __ add(string_length, string_length, Operand(scratch1), SetCC); |
| 4043 __ b(vs, &bailout); | 4043 __ b(vs, &bailout); |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4342 case Token::TYPEOF: { | 4342 case Token::TYPEOF: { |
| 4343 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); | 4343 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); |
| 4344 { StackValueContext context(this); | 4344 { StackValueContext context(this); |
| 4345 VisitForTypeofValue(expr->expression()); | 4345 VisitForTypeofValue(expr->expression()); |
| 4346 } | 4346 } |
| 4347 __ CallRuntime(Runtime::kTypeof, 1); | 4347 __ CallRuntime(Runtime::kTypeof, 1); |
| 4348 context()->Plug(r0); | 4348 context()->Plug(r0); |
| 4349 break; | 4349 break; |
| 4350 } | 4350 } |
| 4351 | 4351 |
| 4352 case Token::SUB: |
| 4353 EmitUnaryOperation(expr, "[ UnaryOperation (SUB)"); |
| 4354 break; |
| 4355 |
| 4356 case Token::BIT_NOT: |
| 4357 EmitUnaryOperation(expr, "[ UnaryOperation (BIT_NOT)"); |
| 4358 break; |
| 4359 |
| 4352 default: | 4360 default: |
| 4353 UNREACHABLE(); | 4361 UNREACHABLE(); |
| 4354 } | 4362 } |
| 4355 } | 4363 } |
| 4356 | 4364 |
| 4357 | 4365 |
| 4366 void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr, |
| 4367 const char* comment) { |
| 4368 // TODO(svenpanne): Allowing format strings in Comment would be nice here... |
| 4369 Comment cmt(masm_, comment); |
| 4370 UnaryOpStub stub(expr->op()); |
| 4371 // UnaryOpStub expects the argument to be in the |
| 4372 // accumulator register r0. |
| 4373 VisitForAccumulatorValue(expr->expression()); |
| 4374 SetSourcePosition(expr->position()); |
| 4375 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, |
| 4376 expr->UnaryOperationFeedbackId()); |
| 4377 context()->Plug(r0); |
| 4378 } |
| 4379 |
| 4380 |
| 4358 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4381 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 4359 Comment cmnt(masm_, "[ CountOperation"); | 4382 Comment cmnt(masm_, "[ CountOperation"); |
| 4360 SetSourcePosition(expr->position()); | 4383 SetSourcePosition(expr->position()); |
| 4361 | 4384 |
| 4362 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' | 4385 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' |
| 4363 // as the left-hand side. | 4386 // as the left-hand side. |
| 4364 if (!expr->expression()->IsValidLeftHandSide()) { | 4387 if (!expr->expression()->IsValidLeftHandSide()) { |
| 4365 VisitForEffect(expr->expression()); | 4388 VisitForEffect(expr->expression()); |
| 4366 return; | 4389 return; |
| 4367 } | 4390 } |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4892 *context_length = 0; | 4915 *context_length = 0; |
| 4893 return previous_; | 4916 return previous_; |
| 4894 } | 4917 } |
| 4895 | 4918 |
| 4896 | 4919 |
| 4897 #undef __ | 4920 #undef __ |
| 4898 | 4921 |
| 4899 } } // namespace v8::internal | 4922 } } // namespace v8::internal |
| 4900 | 4923 |
| 4901 #endif // V8_TARGET_ARCH_ARM | 4924 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |