Commit 42f0a73a authored by rossberg@chromium.org's avatar rossberg@chromium.org

Make proxies work as prototypes.

Fix a couple of other proxy bugs along the way.
Refactor trap invocation in native code.

R=kmillikin@chromium.org
BUG=v8:1543
TEST=

Review URL: http://codereview.chromium.org/7799026

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9312 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ff5e1c98
......@@ -1351,7 +1351,7 @@ static bool StoreICableLookup(LookupResult* lookup) {
}
static bool LookupForWrite(JSReceiver* receiver,
static bool LookupForWrite(JSObject* receiver,
String* name,
LookupResult* lookup) {
receiver->LocalLookup(name, lookup);
......@@ -1359,12 +1359,10 @@ static bool LookupForWrite(JSReceiver* receiver,
return false;
}
if (lookup->type() == INTERCEPTOR) {
JSObject* object = JSObject::cast(receiver);
if (object->GetNamedInterceptor()->setter()->IsUndefined()) {
object->LocalLookupRealNamedProperty(name, lookup);
return StoreICableLookup(lookup);
}
if (lookup->type() == INTERCEPTOR &&
receiver->GetNamedInterceptor()->setter()->IsUndefined()) {
receiver->LocalLookupRealNamedProperty(name, lookup);
return StoreICableLookup(lookup);
}
return true;
......@@ -1376,28 +1374,28 @@ MaybeObject* StoreIC::Store(State state,
Handle<Object> object,
Handle<String> name,
Handle<Object> value) {
// If the object is undefined or null it's illegal to try to set any
// properties on it; throw a TypeError in that case.
if (object->IsUndefined() || object->IsNull()) {
return TypeError("non_object_property_store", object, name);
}
if (!object->IsJSObject()) {
// Handle proxies.
if (object->IsJSProxy()) {
return JSProxy::cast(*object)->
SetProperty(*name, *value, NONE, strict_mode);
}
// If the object is undefined or null it's illegal to try to set any
// properties on it; throw a TypeError in that case.
if (object->IsUndefined() || object->IsNull()) {
return TypeError("non_object_property_store", object, name);
}
if (!object->IsJSReceiver()) {
// The length property of string values is read-only. Throw in strict mode.
if (strict_mode == kStrictMode && object->IsString() &&
name->Equals(isolate()->heap()->length_symbol())) {
return TypeError("strict_read_only_property", object, name);
}
// Ignore stores where the receiver is not a JSObject.
// Ignore other stores where the receiver is not a JSObject.
return *value;
}
// Handle proxies.
if (object->IsJSProxy()) {
return JSReceiver::cast(*object)->
SetProperty(*name, *value, NONE, strict_mode);
}
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
// Check if the given name is an array index.
......
This diff is collapsed.
......@@ -907,9 +907,6 @@ class Object : public MaybeObject {
Object* structure,
String* name,
Object* holder);
MUST_USE_RESULT MaybeObject* GetPropertyWithHandler(Object* receiver,
String* name,
Object* handler);
MUST_USE_RESULT MaybeObject* GetPropertyWithDefinedGetter(Object* receiver,
JSFunction* getter);
......@@ -1448,6 +1445,8 @@ class JSReceiver: public HeapObject {
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* SetPropertyWithDefinedSetter(JSFunction* setter,
Object* value);
MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode);
......@@ -1554,6 +1553,7 @@ class JSObject: public JSReceiver {
// a dictionary, and it will stay a dictionary.
MUST_USE_RESULT MaybeObject* PrepareSlowElementsForSort(uint32_t limit);
// Can cause GC.
MUST_USE_RESULT MaybeObject* SetPropertyForResult(LookupResult* result,
String* key,
Object* value,
......@@ -1571,8 +1571,6 @@ class JSObject: public JSReceiver {
Object* value,
JSObject* holder,
StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* SetPropertyWithDefinedSetter(JSFunction* setter,
Object* value);
MUST_USE_RESULT MaybeObject* SetPropertyWithInterceptor(
String* name,
Object* value,
......@@ -1801,10 +1799,6 @@ class JSObject: public JSReceiver {
inline Object* GetInternalField(int index);
inline void SetInternalField(int index, Object* value);
// Lookup a property. If found, the result is valid and has
// detailed information.
void LocalLookup(String* name, LookupResult* result);
// The following lookup functions skip interceptors.
void LocalLookupRealNamedProperty(String* name, LookupResult* result);
void LookupRealNamedProperty(String* name, LookupResult* result);
......@@ -6708,6 +6702,10 @@ class JSProxy: public JSReceiver {
bool HasPropertyWithHandler(String* name);
MUST_USE_RESULT MaybeObject* GetPropertyWithHandler(
Object* receiver,
String* name);
MUST_USE_RESULT MaybeObject* SetPropertyWithHandler(
String* name,
Object* value,
......@@ -6720,8 +6718,7 @@ class JSProxy: public JSReceiver {
MUST_USE_RESULT PropertyAttributes GetPropertyAttributeWithHandler(
JSReceiver* receiver,
String* name,
bool* has_exception);
String* name);
// Turn this into an (empty) JSObject.
void Fix();
......@@ -6729,6 +6726,13 @@ class JSProxy: public JSReceiver {
// Initializes the body after the handler slot.
inline void InitializeBody(int object_size, Object* value);
// Invoke a trap by name. If the trap does not exist on this's handler,
// but derived_trap is non-NULL, invoke that instead. May cause GC.
Handle<Object> CallTrap(const char* name,
Handle<Object> derived_trap,
int argc,
Handle<Object> args[]);
// Dispatched behavior.
#ifdef OBJECT_PRINT
inline void JSProxyPrint() {
......
......@@ -202,9 +202,9 @@ class LookupResult BASE_EMBEDDED {
number_ = entry;
}
void HandlerResult() {
void HandlerResult(JSProxy* proxy) {
lookup_type_ = HANDLER_TYPE;
holder_ = NULL;
holder_ = proxy;
details_ = PropertyDetails(NONE, HANDLER);
cacheable_ = false;
}
......@@ -221,7 +221,12 @@ class LookupResult BASE_EMBEDDED {
JSObject* holder() {
ASSERT(IsFound());
return holder_;
return JSObject::cast(holder_);
}
JSProxy* proxy() {
ASSERT(IsFound());
return JSProxy::cast(holder_);
}
PropertyType type() {
......@@ -354,7 +359,7 @@ class LookupResult BASE_EMBEDDED {
CONSTANT_TYPE
} lookup_type_;
JSObject* holder_;
JSReceiver* holder_;
int number_;
bool cacheable_;
PropertyDetails details_;
......
......@@ -4645,7 +4645,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) {
if (args[0]->IsJSReceiver()) {
JSReceiver* receiver = JSReceiver::cast(args[0]);
CONVERT_CHECKED(String, key, args[1]);
if (receiver->HasProperty(key)) return isolate->heap()->true_value();
bool result = receiver->HasProperty(key);
if (isolate->has_pending_exception()) return Failure::Exception();
return isolate->heap()->ToBoolean(result);
}
return isolate->heap()->false_value();
}
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment