Revision: 22518
Author: [email protected]
Date: Tue Jul 22 08:28:49 2014 UTC
Log: Support setting named properties on non-JSObjects.
BUG=
[email protected]
Review URL: https://codereview.chromium.org/407953002
http://code.google.com/p/v8/source/detail?r=22518
Modified:
/branches/bleeding_edge/src/debug.cc
/branches/bleeding_edge/src/factory.cc
/branches/bleeding_edge/src/ic.cc
/branches/bleeding_edge/src/liveedit.cc
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/test/mjsunit/value-wrapper-accessor.js
=======================================
--- /branches/bleeding_edge/src/debug.cc Mon Jul 21 13:10:14 2014 UTC
+++ /branches/bleeding_edge/src/debug.cc Tue Jul 22 08:28:49 2014 UTC
@@ -824,7 +824,7 @@
Handle<JSBuiltinsObject> builtin =
Handle<JSBuiltinsObject>(global->builtins(), isolate_);
RETURN_ON_EXCEPTION_VALUE(
- isolate_, JSReceiver::SetProperty(global, key, builtin, SLOPPY),
false);
+ isolate_, Object::SetProperty(global, key, builtin, SLOPPY), false);
// Compile the JavaScript for the debugger in the debugger context.
bool caught_exception =
=======================================
--- /branches/bleeding_edge/src/factory.cc Mon Jul 21 13:51:42 2014 UTC
+++ /branches/bleeding_edge/src/factory.cc Tue Jul 22 08:28:49 2014 UTC
@@ -2084,9 +2084,9 @@
ASSERT(!isolate()->has_pending_exception());
Handle<JSObject> result = NewJSObjectFromMap(map);
Handle<Smi> value(Smi::FromInt(length), isolate());
- JSReceiver::SetProperty(result, length_string(), value, STRICT).Assert();
+ Object::SetProperty(result, length_string(), value, STRICT).Assert();
if (!strict_mode_callee) {
- JSReceiver::SetProperty(result, callee_string(), callee,
STRICT).Assert();
+ Object::SetProperty(result, callee_string(), callee, STRICT).Assert();
}
return result;
}
=======================================
--- /branches/bleeding_edge/src/ic.cc Mon Jul 21 13:10:14 2014 UTC
+++ /branches/bleeding_edge/src/ic.cc Tue Jul 22 08:28:49 2014 UTC
@@ -1195,11 +1195,12 @@
}
-static bool LookupForWrite(Handle<JSObject> receiver,
- Handle<String> name,
- Handle<Object> value,
- LookupResult* lookup,
- IC* ic) {
+static bool LookupForWrite(Handle<Object> object, Handle<String> name,
+ Handle<Object> value, LookupResult* lookup, IC*
ic) {
+ // Disable ICs for non-JSObjects for now.
+ if (!object->IsJSObject()) return false;
+ Handle<JSObject> receiver = Handle<JSObject>::cast(object);
+
Handle<JSObject> holder = receiver;
receiver->Lookup(name, lookup);
if (lookup->IsFound()) {
@@ -1268,11 +1269,10 @@
// TODO(verwaest): Let SetProperty do the migration, since storing a
property
// might deprecate the current map again, if value does not fit.
if (MigrateDeprecated(object) || object->IsJSProxy()) {
- Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(
isolate(), result,
- JSReceiver::SetProperty(receiver, name, value, strict_mode()),
Object);
+ Object::SetProperty(object, name, value, strict_mode()), Object);
return result;
}
@@ -1281,22 +1281,15 @@
if (object->IsUndefined() || object->IsNull()) {
return TypeError("non_object_property_store", object, name);
}
-
- // The length property of string values is read-only. Throw in strict
mode.
- if (strict_mode() == STRICT && object->IsString() &&
- String::Equals(isolate()->factory()->length_string(), name)) {
- return TypeError("strict_read_only_property", object, name);
- }
-
- // Ignore other stores where the receiver is not a JSObject.
- // TODO(1475): Must check prototype chains of object wrappers.
- if (!object->IsJSObject()) return value;
-
- Handle<JSObject> receiver = Handle<JSObject>::cast(object);
// Check if the given name is an array index.
uint32_t index;
if (name->AsArrayIndex(&index)) {
+ // Ignore other stores where the receiver is not a JSObject.
+ // TODO(1475): Must check prototype chains of object wrappers.
+ if (!object->IsJSObject()) return value;
+ Handle<JSObject> receiver = Handle<JSObject>::cast(object);
+
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(
isolate(),
@@ -1307,17 +1300,18 @@
}
// Observed objects are always modified through the runtime.
- if (receiver->map()->is_observed()) {
+ if (object->IsHeapObject() &&
+ Handle<HeapObject>::cast(object)->map()->is_observed()) {
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(
- isolate(), result, JSReceiver::SetProperty(receiver, name, value,
- strict_mode(),
store_mode),
+ isolate(), result,
+ Object::SetProperty(object, name, value, strict_mode(),
store_mode),
Object);
return result;
}
LookupResult lookup(isolate());
- bool can_store = LookupForWrite(receiver, name, value, &lookup, this);
+ bool can_store = LookupForWrite(object, name, value, &lookup, this);
if (!can_store &&
strict_mode() == STRICT &&
!(lookup.IsProperty() && lookup.IsReadOnly()) &&
@@ -1331,7 +1325,7 @@
set_target(*stub);
TRACE_IC("StoreIC", name);
} else if (can_store) {
- UpdateCaches(&lookup, receiver, name, value);
+ UpdateCaches(&lookup, Handle<JSObject>::cast(object), name, value);
} else if (lookup.IsNormal() ||
(lookup.IsField() && lookup.CanHoldValue(value))) {
Handle<Code> stub = generic_stub();
@@ -1343,7 +1337,7 @@
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(
isolate(), result,
- JSReceiver::SetProperty(receiver, name, value, strict_mode(),
store_mode),
+ Object::SetProperty(object, name, value, strict_mode(), store_mode),
Object);
return result;
}
=======================================
--- /branches/bleeding_edge/src/liveedit.cc Mon Jul 21 13:10:14 2014 UTC
+++ /branches/bleeding_edge/src/liveedit.cc Tue Jul 22 08:28:49 2014 UTC
@@ -885,12 +885,12 @@
Handle<Smi> end_pos(Smi::FromInt(message_location.end_pos()),
isolate);
Handle<JSObject> script_obj =
Script::GetWrapper(message_location.script());
- JSReceiver::SetProperty(rethrow_exception, start_pos_key, start_pos,
- SLOPPY).Assert();
- JSReceiver::SetProperty(rethrow_exception, end_pos_key, end_pos,
SLOPPY)
+ Object::SetProperty(rethrow_exception, start_pos_key, start_pos,
SLOPPY)
.Assert();
- JSReceiver::SetProperty(rethrow_exception, script_obj_key,
script_obj,
- SLOPPY).Assert();
+ Object::SetProperty(rethrow_exception, end_pos_key, end_pos, SLOPPY)
+ .Assert();
+ Object::SetProperty(rethrow_exception, script_obj_key, script_obj,
SLOPPY)
+ .Assert();
}
}
=======================================
--- /branches/bleeding_edge/src/objects.cc Mon Jul 21 16:01:50 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc Tue Jul 22 08:28:49 2014 UTC
@@ -471,6 +471,8 @@
// value since a const declaration would conflict with the setter.
ASSERT(!structure->IsForeign());
if (structure->IsExecutableAccessorInfo()) {
+ // Don't call executable accessor setters with non-JSObject receivers.
+ if (!receiver->IsJSObject()) return value;
// api style callbacks
ExecutableAccessorInfo* data =
ExecutableAccessorInfo::cast(*structure);
if (!data->IsCompatibleReceiver(*receiver)) {
@@ -554,10 +556,9 @@
}
Handle<Object> argv[] = { value };
- RETURN_ON_EXCEPTION(
- isolate,
- Execution::Call(isolate, setter, receiver, ARRAY_SIZE(argv), argv),
- Object);
+ RETURN_ON_EXCEPTION(isolate, Execution::Call(isolate, setter, receiver,
+ ARRAY_SIZE(argv), argv,
true),
+ Object);
return value;
}
@@ -2959,13 +2960,12 @@
}
-MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
- Handle<Name> name,
- Handle<Object> value,
- StrictMode strict_mode,
- StoreFromKeyed store_mode) {
+MaybeHandle<Object> Object::SetProperty(Handle<Object> object,
+ Handle<Name> name, Handle<Object>
value,
+ StrictMode strict_mode,
+ StoreFromKeyed store_mode) {
LookupIterator it(object, name);
- return Object::SetProperty(&it, value, strict_mode, store_mode);
+ return SetProperty(&it, value, strict_mode, store_mode);
}
=======================================
--- /branches/bleeding_edge/src/objects.h Mon Jul 21 16:01:50 2014 UTC
+++ /branches/bleeding_edge/src/objects.h Tue Jul 22 08:28:49 2014 UTC
@@ -1483,6 +1483,13 @@
void Lookup(Handle<Name> name, LookupResult* result);
MUST_USE_RESULT static MaybeHandle<Object> GetProperty(LookupIterator*
it);
+
+ // Implementation of [[Put]], ECMA-262 5th edition, section 8.12.5.
+ MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
+ Handle<Object> object, Handle<Name> key, Handle<Object> value,
+ StrictMode strict_mode,
+ StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
+
MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
LookupIterator* it, Handle<Object> value, StrictMode strict_mode,
StoreFromKeyed store_mode);
@@ -1941,13 +1948,6 @@
DECLARE_CAST(JSReceiver)
- // Implementation of [[Put]], ECMA-262 5th edition, section 8.12.5.
- MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
- Handle<JSReceiver> object,
- Handle<Name> key,
- Handle<Object> value,
- StrictMode strict_mode,
- StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
MUST_USE_RESULT static MaybeHandle<Object> SetElement(
Handle<JSReceiver> object,
uint32_t index,
@@ -2023,14 +2023,6 @@
KeyCollectionType type);
private:
- MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
- Handle<JSReceiver> receiver,
- LookupResult* result,
- Handle<Name> key,
- Handle<Object> value,
- StrictMode strict_mode,
- StoreFromKeyed store_from_keyed);
-
DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
};
=======================================
--- /branches/bleeding_edge/src/runtime.cc Mon Jul 21 16:01:50 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc Tue Jul 22 08:28:49 2014 UTC
@@ -2231,8 +2231,7 @@
Handle<GlobalObject> global(isolate->context()->global_object());
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- JSReceiver::SetProperty(global, name, value, strict_mode));
+ isolate, result, Object::SetProperty(global, name, value,
strict_mode));
return *result;
}
@@ -5026,18 +5025,17 @@
isolate, name_object, Execution::ToString(isolate, key), Object);
}
Handle<Name> name = Handle<Name>::cast(name_object);
- return JSReceiver::SetProperty(Handle<JSProxy>::cast(object), name,
value,
- strict_mode);
+ return Object::SetProperty(Handle<JSProxy>::cast(object), name, value,
+ strict_mode);
}
-
- // If the object isn't a JavaScript object, we ignore the store.
- if (!object->IsJSObject()) return value;
-
- Handle<JSObject> js_object = Handle<JSObject>::cast(object);
// Check if the given key is an array index.
uint32_t index;
if (key->ToArrayIndex(&index)) {
+ // TODO(verwaest): Support non-JSObject receivers.
+ if (!object->IsJSObject()) return value;
+ Handle<JSObject> js_object = Handle<JSObject>::cast(object);
+
// In Firefox/SpiderMonkey, Safari and Opera you can access the
characters
// of a string using [] notation. We need to support this too in
// JavaScript.
@@ -5068,6 +5066,9 @@
if (key->IsName()) {
Handle<Name> name = Handle<Name>::cast(key);
if (name->AsArrayIndex(&index)) {
+ // TODO(verwaest): Support non-JSObject receivers.
+ if (!object->IsJSObject()) return value;
+ Handle<JSObject> js_object = Handle<JSObject>::cast(object);
if (js_object->HasExternalArrayElements()) {
if (!value->IsNumber() && !value->IsUndefined()) {
ASSIGN_RETURN_ON_EXCEPTION(
@@ -5078,7 +5079,7 @@
true, SET_PROPERTY);
} else {
if (name->IsString()) name =
String::Flatten(Handle<String>::cast(name));
- return JSReceiver::SetProperty(js_object, name, value, strict_mode);
+ return Object::SetProperty(object, name, value, strict_mode);
}
}
@@ -5089,11 +5090,13 @@
Handle<String> name = Handle<String>::cast(converted);
if (name->AsArrayIndex(&index)) {
+ // TODO(verwaest): Support non-JSObject receivers.
+ if (!object->IsJSObject()) return value;
+ Handle<JSObject> js_object = Handle<JSObject>::cast(object);
return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
true, SET_PROPERTY);
- } else {
- return JSReceiver::SetProperty(js_object, name, value, strict_mode);
}
+ return Object::SetProperty(object, name, value, strict_mode);
}
@@ -9267,7 +9270,7 @@
}
RETURN_FAILURE_ON_EXCEPTION(
- isolate, JSReceiver::SetProperty(object, name, value, strict_mode));
+ isolate, Object::SetProperty(object, name, value, strict_mode));
return *value;
}
=======================================
--- /branches/bleeding_edge/test/mjsunit/value-wrapper-accessor.js Tue Mar
11 14:39:08 2014 UTC
+++ /branches/bleeding_edge/test/mjsunit/value-wrapper-accessor.js Tue Jul
22 08:28:49 2014 UTC
@@ -77,20 +77,14 @@
%OptimizeFunctionOnNextCall(nonstrict);
result = undefined;
nonstrict(object);
- // TODO(1475): Support storing to primitive values.
- // This should return "object" once storing to primitive values is
- // supported.
- assertEquals("undefined", typeof result);
+ assertEquals("object", typeof result);
strict(object);
strict(object);
%OptimizeFunctionOnNextCall(strict);
result = undefined;
strict(object);
- // TODO(1475): Support storing to primitive values.
- // This should return "object" once storing to primitive values is
- // supported.
- assertEquals("undefined", typeof result);
+ assertEquals(object, result);
})();
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.