Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/x64/codegen-x64.cc

Issue 6576024: (early draft) Strict mode - throw exception on assignment to read only property. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 4587 matching lines...) Expand 10 before | Expand all | Expand 10 after
4598 // context slot declaration, but we cannot initialize it at the same 4598 // context slot declaration, but we cannot initialize it at the same
4599 // time, because the const declaration may be at the end of the eval 4599 // time, because the const declaration may be at the end of the eval
4600 // code (sigh...) and the const variable may have been used before 4600 // code (sigh...) and the const variable may have been used before
4601 // (where its value is 'undefined'). Thus, we can only do the 4601 // (where its value is 'undefined'). Thus, we can only do the
4602 // initialization when we actually encounter the expression and when 4602 // initialization when we actually encounter the expression and when
4603 // the expression operands are defined and valid, and thus we need the 4603 // the expression operands are defined and valid, and thus we need the
4604 // split into 2 operations: declaration of the context slot followed 4604 // split into 2 operations: declaration of the context slot followed
4605 // by initialization. 4605 // by initialization.
4606 value = frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3); 4606 value = frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3);
4607 } else { 4607 } else {
4608 value = frame_->CallRuntime(Runtime::kStoreContextSlot, 3); 4608 frame_->Push(Smi::FromInt(strict_mode_flag()));
4609 value = frame_->CallRuntime(Runtime::kStoreContextSlot, 4);
4609 } 4610 }
4610 // Storing a variable must keep the (new) value on the expression 4611 // Storing a variable must keep the (new) value on the expression
4611 // stack. This is necessary for compiling chained assignment 4612 // stack. This is necessary for compiling chained assignment
4612 // expressions. 4613 // expressions.
4613 frame_->Push(&value); 4614 frame_->Push(&value);
4614 } else { 4615 } else {
4615 ASSERT(!slot->var()->is_dynamic()); 4616 ASSERT(!slot->var()->is_dynamic());
4616 4617
4617 JumpTarget exit; 4618 JumpTarget exit;
4618 if (init_state == CONST_INIT) { 4619 if (init_state == CONST_INIT) {
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
4907 break; 4908 break;
4908 } 4909 }
4909 // Fall through 4910 // Fall through
4910 } 4911 }
4911 case ObjectLiteral::Property::PROTOTYPE: { 4912 case ObjectLiteral::Property::PROTOTYPE: {
4912 // Duplicate the object as an argument to the runtime call. 4913 // Duplicate the object as an argument to the runtime call.
4913 frame_->Dup(); 4914 frame_->Dup();
4914 Load(property->key()); 4915 Load(property->key());
4915 Load(property->value()); 4916 Load(property->value());
4916 if (property->emit_store()) { 4917 if (property->emit_store()) {
4918 frame_->Push(Smi::FromInt(NONE)); // PropertyAttributes
4917 // Ignore the result. 4919 // Ignore the result.
4918 Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 3); 4920 Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 4);
4919 } else { 4921 } else {
4920 frame_->Drop(3); 4922 frame_->Drop(3);
4921 } 4923 }
4922 break; 4924 break;
4923 } 4925 }
4924 case ObjectLiteral::Property::SETTER: { 4926 case ObjectLiteral::Property::SETTER: {
4925 // Duplicate the object as an argument to the runtime call. 4927 // Duplicate the object as an argument to the runtime call.
4926 frame_->Dup(); 4928 frame_->Dup();
4927 Load(property->key()); 4929 Load(property->key());
4928 frame_->Push(Smi::FromInt(1)); 4930 frame_->Push(Smi::FromInt(1));
(...skipping 3136 matching lines...) Expand 10 before | Expand all | Expand 10 after
8065 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1); 8067 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1);
8066 8068
8067 if (!dst_.is(rax)) __ movq(dst_, rax); 8069 if (!dst_.is(rax)) __ movq(dst_, rax);
8068 } 8070 }
8069 8071
8070 8072
8071 class DeferredReferenceSetKeyedValue: public DeferredCode { 8073 class DeferredReferenceSetKeyedValue: public DeferredCode {
8072 public: 8074 public:
8073 DeferredReferenceSetKeyedValue(Register value, 8075 DeferredReferenceSetKeyedValue(Register value,
8074 Register key, 8076 Register key,
8075 Register receiver) 8077 Register receiver,
8076 : value_(value), key_(key), receiver_(receiver) { 8078 StrictModeFlag strict)
8079 : value_(value), key_(key), receiver_(receiver), strict_(strict) {
8077 set_comment("[ DeferredReferenceSetKeyedValue"); 8080 set_comment("[ DeferredReferenceSetKeyedValue");
8078 } 8081 }
8079 8082
8080 virtual void Generate(); 8083 virtual void Generate();
8081 8084
8082 Label* patch_site() { return &patch_site_; } 8085 Label* patch_site() { return &patch_site_; }
8083 8086
8084 private: 8087 private:
8085 Register value_; 8088 Register value_;
8086 Register key_; 8089 Register key_;
8087 Register receiver_; 8090 Register receiver_;
8088 Label patch_site_; 8091 Label patch_site_;
8092 StrictModeFlag strict_;
8089 }; 8093 };
8090 8094
8091 8095
8092 void DeferredReferenceSetKeyedValue::Generate() { 8096 void DeferredReferenceSetKeyedValue::Generate() {
8093 __ IncrementCounter(&Counters::keyed_store_inline_miss, 1); 8097 __ IncrementCounter(&Counters::keyed_store_inline_miss, 1);
8094 // Move value, receiver, and key to registers rax, rdx, and rcx, as 8098 // Move value, receiver, and key to registers rax, rdx, and rcx, as
8095 // the IC stub expects. 8099 // the IC stub expects.
8096 // Move value to rax, using xchg if the receiver or key is in rax. 8100 // Move value to rax, using xchg if the receiver or key is in rax.
8097 if (!value_.is(rax)) { 8101 if (!value_.is(rax)) {
8098 if (!receiver_.is(rax) && !key_.is(rax)) { 8102 if (!receiver_.is(rax) && !key_.is(rax)) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
8130 __ movq(rcx, key_); 8134 __ movq(rcx, key_);
8131 } 8135 }
8132 } else if (key_.is(rcx)) { 8136 } else if (key_.is(rcx)) {
8133 __ movq(rdx, receiver_); 8137 __ movq(rdx, receiver_);
8134 } else { 8138 } else {
8135 __ movq(rcx, key_); 8139 __ movq(rcx, key_);
8136 __ movq(rdx, receiver_); 8140 __ movq(rdx, receiver_);
8137 } 8141 }
8138 8142
8139 // Call the IC stub. 8143 // Call the IC stub.
8140 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 8144 Handle<Code> ic(Builtins::builtin(
8145 strict_ == kStrictMode ? Builtins::KeyedStoreIC_Initialize_Strict
8146 : Builtins::KeyedStoreIC_Initialize));
8141 __ Call(ic, RelocInfo::CODE_TARGET); 8147 __ Call(ic, RelocInfo::CODE_TARGET);
8142 // The delta from the start of the map-compare instructions (initial movq) 8148 // The delta from the start of the map-compare instructions (initial movq)
8143 // to the test instruction. We use masm_-> directly here instead of the 8149 // to the test instruction. We use masm_-> directly here instead of the
8144 // __ macro because the macro sometimes uses macro expansion to turn 8150 // __ macro because the macro sometimes uses macro expansion to turn
8145 // into something that can't return a value. This is encountered 8151 // into something that can't return a value. This is encountered
8146 // when doing generated code coverage tests. 8152 // when doing generated code coverage tests.
8147 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); 8153 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site());
8148 // Here we use masm_-> instead of the __ macro because this is the 8154 // Here we use masm_-> instead of the __ macro because this is the
8149 // instruction that gets patched and coverage code gets in the way. 8155 // instruction that gets patched and coverage code gets in the way.
8150 masm_->testl(rax, Immediate(-delta_to_patch_site)); 8156 masm_->testl(rax, Immediate(-delta_to_patch_site));
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
8471 bool value_is_constant = result.is_constant(); 8477 bool value_is_constant = result.is_constant();
8472 8478
8473 // Make sure that value, key and receiver are in registers. 8479 // Make sure that value, key and receiver are in registers.
8474 result.ToRegister(); 8480 result.ToRegister();
8475 key.ToRegister(); 8481 key.ToRegister();
8476 receiver.ToRegister(); 8482 receiver.ToRegister();
8477 8483
8478 DeferredReferenceSetKeyedValue* deferred = 8484 DeferredReferenceSetKeyedValue* deferred =
8479 new DeferredReferenceSetKeyedValue(result.reg(), 8485 new DeferredReferenceSetKeyedValue(result.reg(),
8480 key.reg(), 8486 key.reg(),
8481 receiver.reg()); 8487 receiver.reg(),
8488 strict_mode_flag());
8482 8489
8483 // Check that the receiver is not a smi. 8490 // Check that the receiver is not a smi.
8484 __ JumpIfSmi(receiver.reg(), deferred->entry_label()); 8491 __ JumpIfSmi(receiver.reg(), deferred->entry_label());
8485 8492
8486 // Check that the key is a smi. 8493 // Check that the key is a smi.
8487 if (!key.is_smi()) { 8494 if (!key.is_smi()) {
8488 __ JumpIfNotSmi(key.reg(), deferred->entry_label()); 8495 __ JumpIfNotSmi(key.reg(), deferred->entry_label());
8489 } else if (FLAG_debug_code) { 8496 } else if (FLAG_debug_code) {
8490 __ AbortIfNotSmi(key.reg()); 8497 __ AbortIfNotSmi(key.reg());
8491 } 8498 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
8533 masm()->SmiToIndex(kScratchRegister, key.reg(), kPointerSizeLog2); 8540 masm()->SmiToIndex(kScratchRegister, key.reg(), kPointerSizeLog2);
8534 __ movq(FieldOperand(tmp.reg(), 8541 __ movq(FieldOperand(tmp.reg(),
8535 index.reg, 8542 index.reg,
8536 index.scale, 8543 index.scale,
8537 FixedArray::kHeaderSize), 8544 FixedArray::kHeaderSize),
8538 result.reg()); 8545 result.reg());
8539 __ IncrementCounter(&Counters::keyed_store_inline, 1); 8546 __ IncrementCounter(&Counters::keyed_store_inline, 1);
8540 8547
8541 deferred->BindExit(); 8548 deferred->BindExit();
8542 } else { 8549 } else {
8543 result = frame()->CallKeyedStoreIC(); 8550 result = frame()->CallKeyedStoreIC(strict_mode_flag());
8544 // Make sure that we do not have a test instruction after the 8551 // Make sure that we do not have a test instruction after the
8545 // call. A test instruction after the call is used to 8552 // call. A test instruction after the call is used to
8546 // indicate that we have generated an inline version of the 8553 // indicate that we have generated an inline version of the
8547 // keyed store. 8554 // keyed store.
8548 __ nop(); 8555 __ nop();
8549 } 8556 }
8550 ASSERT(frame()->height() == original_height - 3); 8557 ASSERT(frame()->height() == original_height - 3);
8551 return result; 8558 return result;
8552 } 8559 }
8553 8560
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
8812 } 8819 }
8813 8820
8814 #endif 8821 #endif
8815 8822
8816 8823
8817 #undef __ 8824 #undef __
8818 8825
8819 } } // namespace v8::internal 8826 } } // namespace v8::internal
8820 8827
8821 #endif // V8_TARGET_ARCH_X64 8828 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698