| Index: src/ic.cc
|
| diff --git a/src/ic.cc b/src/ic.cc
|
| index 7482830ae0bdf990cb8acecaa93b0efb59eb70b9..6d00d14e82086ea9ff8a5823d487d6eb8002b022 100644
|
| --- a/src/ic.cc
|
| +++ b/src/ic.cc
|
| @@ -343,7 +343,7 @@ void StoreIC::Clear(Address address, Code* target) {
|
| if (target->ic_state() == UNINITIALIZED) return;
|
| ClearInlinedVersion(address);
|
| SetTargetAtAddress(address,
|
| - target->extra_ic_state() == kStoreICStrict
|
| + target->extra_ic_state() == kStrictMode
|
| ? initialize_stub_strict()
|
| : initialize_stub());
|
| }
|
| @@ -366,7 +366,10 @@ void KeyedStoreIC::RestoreInlinedVersion(Address address) {
|
|
|
| void KeyedStoreIC::Clear(Address address, Code* target) {
|
| if (target->ic_state() == UNINITIALIZED) return;
|
| - SetTargetAtAddress(address, initialize_stub());
|
| + SetTargetAtAddress(address,
|
| + target->extra_ic_state() == kStrictMode
|
| + ? initialize_stub_strict()
|
| + : initialize_stub());
|
| }
|
|
|
|
|
| @@ -1226,7 +1229,8 @@ MaybeObject* KeyedLoadIC::Load(State state,
|
| if (receiver->HasExternalArrayElements()) {
|
| MaybeObject* probe =
|
| StubCache::ComputeKeyedLoadOrStoreExternalArray(*receiver,
|
| - false);
|
| + false,
|
| + kNonStrictMode);
|
| stub = probe->IsFailure() ?
|
| NULL : Code::cast(probe->ToObjectUnchecked());
|
| } else if (receiver->HasIndexedInterceptor()) {
|
| @@ -1412,11 +1416,12 @@ MaybeObject* StoreIC::Store(State state,
|
| #ifdef DEBUG
|
| if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
|
| #endif
|
| - Builtins::Name target = (extra_ic_state == kStoreICStrict)
|
| + Builtins::Name target = (extra_ic_state == kStrictMode)
|
| ? Builtins::StoreIC_ArrayLength_Strict
|
| : Builtins::StoreIC_ArrayLength;
|
| set_target(Builtins::builtin(target));
|
| - return receiver->SetProperty(*name, *value, NONE);
|
| + return receiver->SetProperty(*name, *value, NONE,
|
| + static_cast<StrictModeFlag>(extra_ic_state));
|
| }
|
|
|
| // Lookup the property locally in the receiver.
|
| @@ -1446,7 +1451,9 @@ MaybeObject* StoreIC::Store(State state,
|
| PrintF("[StoreIC : inline patch %s]\n", *name->ToCString());
|
| }
|
| #endif
|
| - return receiver->SetProperty(*name, *value, NONE);
|
| + return receiver->SetProperty(
|
| + *name, *value, NONE,
|
| + static_cast<StrictModeFlag>(extra_ic_state));
|
| #ifdef DEBUG
|
|
|
| } else {
|
| @@ -1476,8 +1483,12 @@ MaybeObject* StoreIC::Store(State state,
|
| UpdateCaches(&lookup, state, extra_ic_state, receiver, name, value);
|
| } else {
|
| // Strict mode doesn't allow setting non-existent global property.
|
| - if (extra_ic_state == kStoreICStrict && IsContextual(object)) {
|
| - return ReferenceError("not_defined", name);
|
| + if (extra_ic_state == kStrictMode) {
|
| + if (lookup.IsFound() && lookup.IsReadOnly()) {
|
| + return TypeError("strict_rdonly_property", object, name);
|
| + } else if (IsContextual(object)) {
|
| + return ReferenceError("not_defined", name);
|
| + }
|
| }
|
| }
|
| }
|
| @@ -1485,7 +1496,7 @@ MaybeObject* StoreIC::Store(State state,
|
| if (receiver->IsJSGlobalProxy()) {
|
| // Generate a generic stub that goes to the runtime when we see a global
|
| // proxy as receiver.
|
| - Code* stub = (extra_ic_state == kStoreICStrict)
|
| + Code* stub = (extra_ic_state == kStrictMode)
|
| ? global_proxy_stub_strict()
|
| : global_proxy_stub();
|
| if (target() != stub) {
|
| @@ -1497,7 +1508,8 @@ MaybeObject* StoreIC::Store(State state,
|
| }
|
|
|
| // Set the property.
|
| - return receiver->SetProperty(*name, *value, NONE);
|
| + return receiver->SetProperty(*name, *value, NONE,
|
| + static_cast<StrictModeFlag>(extra_ic_state));
|
| }
|
|
|
|
|
| @@ -1582,7 +1594,7 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
|
| } else if (state == MONOMORPHIC) {
|
| // Only move to megamorphic if the target changes.
|
| if (target() != Code::cast(code)) {
|
| - set_target(extra_ic_state == kStoreICStrict
|
| + set_target(extra_ic_state == kStrictMode
|
| ? megamorphic_stub_strict()
|
| : megamorphic_stub());
|
| }
|
| @@ -1598,6 +1610,7 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
|
|
|
|
|
| MaybeObject* KeyedStoreIC::Store(State state,
|
| + Code::ExtraICState extra_ic_state,
|
| Handle<Object> object,
|
| Handle<Object> key,
|
| Handle<Object> value) {
|
| @@ -1633,7 +1646,8 @@ MaybeObject* KeyedStoreIC::Store(State state,
|
| }
|
|
|
| // Set the property.
|
| - return receiver->SetProperty(*name, *value, NONE);
|
| + return receiver->SetProperty(*name, *value, NONE,
|
| + static_cast<StrictModeFlag>(extra_ic_state));
|
| }
|
|
|
| // Do not use ICs for objects that require access checks (including
|
| @@ -1642,13 +1656,18 @@ MaybeObject* KeyedStoreIC::Store(State state,
|
| ASSERT(!(use_ic && object->IsJSGlobalProxy()));
|
|
|
| if (use_ic) {
|
| - Code* stub = generic_stub();
|
| + Code* stub = extra_ic_state == kStrictMode
|
| + ? generic_stub_strict()
|
| + : generic_stub();
|
| + // TODO(mmaly): Fix IC specialization to take strict mode into account.
|
| + // Currently they jump to KeyedStoreIC_Miss which is non-strict.
|
| if (state == UNINITIALIZED) {
|
| if (object->IsJSObject()) {
|
| Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
| if (receiver->HasExternalArrayElements()) {
|
| MaybeObject* probe =
|
| - StubCache::ComputeKeyedLoadOrStoreExternalArray(*receiver, true);
|
| + StubCache::ComputeKeyedLoadOrStoreExternalArray(
|
| + *receiver, true, extra_ic_state);
|
| stub = probe->IsFailure() ?
|
| NULL : Code::cast(probe->ToObjectUnchecked());
|
| } else if (receiver->HasPixelElements()) {
|
| @@ -1668,7 +1687,9 @@ MaybeObject* KeyedStoreIC::Store(State state,
|
| }
|
|
|
| // Set the property.
|
| - return Runtime::SetObjectProperty(object, key, value, NONE);
|
| + ASSERT(extra_ic_state == kStrictMode || extra_ic_state == kNonStrictMode);
|
| + return Runtime::SetObjectProperty(
|
| + object, key, value, NONE, static_cast<StrictModeFlag>(extra_ic_state));
|
| }
|
|
|
|
|
| @@ -1900,8 +1921,10 @@ MUST_USE_RESULT MaybeObject* KeyedStoreIC_Miss(Arguments args) {
|
| ASSERT(args.length() == 3);
|
| KeyedStoreIC ic;
|
| IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
|
| - return ic.Store(state, args.at<Object>(0), args.at<Object>(1),
|
| - args.at<Object>(2));
|
| + Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
|
| + // TODO(mmaly): Validate extra_ic_state here and pass StrictModeFlag directly.
|
| + return ic.Store(state, extra_ic_state, args.at<Object>(0),
|
| + args.at<Object>(1), args.at<Object>(2));
|
| }
|
|
|
|
|
|
|