Chromium Code Reviews| Index: src/v8natives.js | 
| diff --git a/src/v8natives.js b/src/v8natives.js | 
| index 9843635866323d5c5495edf0ffbdb9d12400f01e..601ae38a006b7470f0dc28517f3d7bda4de9c1db 100644 | 
| --- a/src/v8natives.js | 
| +++ b/src/v8natives.js | 
| @@ -232,6 +232,10 @@ function ObjectValueOf() { | 
| // ECMA-262 - 15.2.4.5 | 
| function ObjectHasOwnProperty(V) { | 
| + if (%IsJSProxy(this)) { | 
| + var handler = %GetHandler(this); | 
| + return CallTrap1(handler, "hasOwn", TO_STRING_INLINE(V), DerivedHasOwnTrap); | 
| + } | 
| return %HasLocalProperty(TO_OBJECT_INLINE(this), TO_STRING_INLINE(V)); | 
| } | 
| @@ -249,7 +253,12 @@ function ObjectIsPrototypeOf(V) { | 
| // ECMA-262 - 15.2.4.6 | 
| function ObjectPropertyIsEnumerable(V) { | 
| - return %IsPropertyEnumerable(ToObject(this), ToString(V)); | 
| + var P = ToString(V); | 
| + if (%IsJSProxy(this)) { | 
| + var desc = GetOwnProperty(this, P); | 
| + return IS_UNDEFINED(desc) ? false : desc.isEnumerable(); | 
| + } | 
| + return %IsPropertyEnumerable(ToObject(this), P); | 
| } | 
| @@ -310,9 +319,7 @@ function ObjectKeys(obj) { | 
| throw MakeTypeError("obj_ctor_property_non_object", ["keys"]); | 
| if (%IsJSProxy(obj)) { | 
| var handler = %GetHandler(obj); | 
| - var keys = handler.keys; | 
| - if (IS_UNDEFINED(keys)) keys = DerivedKeysTrap; | 
| - var names = %_CallFunction(handler, keys); | 
| + var names = CallTrap0(handler, "keys", DerivedKeysTrap); | 
| return ToStringArray(names); | 
| } | 
| return %LocalKeys(obj); | 
| @@ -583,16 +590,41 @@ function ConvertDescriptorArrayToDescriptor(desc_array) { | 
| } | 
| +// For Harmony proxies. | 
| +function GetTrap(handler, name, defaultTrap) { | 
| + var trap = handler[name]; | 
| + if (IS_UNDEFINED(trap)) { | 
| + if (IS_UNDEFINED(defaultTrap)) { | 
| + throw MakeTypeError("handler_trap_missing", [handler, name]); | 
| + } | 
| + trap = defaultTrap; | 
| + } else if (!IS_FUNCTION(trap)) { | 
| + throw MakeTypeError("handler_trap_must_be_callable", [handler, name]); | 
| + } | 
| + return trap; | 
| +} | 
| + | 
| + | 
| +function CallTrap0(handler, name, defaultTrap) { | 
| + return %_CallFunction(handler, GetTrap(handler, name, defaultTrap)); | 
| +} | 
| + | 
| + | 
| +function CallTrap1(handler, name, x, defaultTrap) { | 
| 
 
Mads Ager (chromium)
2011/07/19 15:41:05
Maybe put the arguments last in the parameter list
 
rossberg
2011/07/21 11:08:42
Done.
 
 | 
| + return %_CallFunction(handler, x, GetTrap(handler, name, defaultTrap)); | 
| +} | 
| + | 
| + | 
| +function CallTrap2(handler, name, x, y, defaultTrap) { | 
| + return %_CallFunction(handler, x, y, GetTrap(handler, name, defaultTrap)); | 
| +} | 
| + | 
| + | 
| // ES5 section 8.12.2. | 
| function GetProperty(obj, p) { | 
| if (%IsJSProxy(obj)) { | 
| var handler = %GetHandler(obj); | 
| - var getProperty = handler.getPropertyDescriptor; | 
| - if (IS_UNDEFINED(getProperty)) { | 
| - throw MakeTypeError("handler_trap_missing", | 
| - [handler, "getPropertyDescriptor"]); | 
| - } | 
| - var descriptor = %_CallFunction(handler, p, getProperty); | 
| + var descriptor = CallTrap1(obj, "getPropertyDescriptor", p); | 
| if (IS_UNDEFINED(descriptor)) return descriptor; | 
| var desc = ToCompletePropertyDescriptor(descriptor); | 
| if (!desc.isConfigurable()) { | 
| @@ -613,9 +645,7 @@ function GetProperty(obj, p) { | 
| function HasProperty(obj, p) { | 
| if (%IsJSProxy(obj)) { | 
| var handler = %GetHandler(obj); | 
| - var has = handler.has; | 
| - if (IS_UNDEFINED(has)) has = DerivedHasTrap; | 
| - return ToBoolean(%_CallFunction(handler, obj, p, has)); | 
| + return ToBoolean(CallTrap1(handler, "has", p, DerivedHasTrap)); | 
| } | 
| var desc = GetProperty(obj, p); | 
| return IS_UNDEFINED(desc) ? false : true; | 
| @@ -623,15 +653,11 @@ function HasProperty(obj, p) { | 
| // ES5 section 8.12.1. | 
| -function GetOwnProperty(obj, p) { | 
| +function GetOwnProperty(obj, v) { | 
| + var p = ToString(v); | 
| if (%IsJSProxy(obj)) { | 
| var handler = %GetHandler(obj); | 
| - var getOwnProperty = handler.getOwnPropertyDescriptor; | 
| - if (IS_UNDEFINED(getOwnProperty)) { | 
| - throw MakeTypeError("handler_trap_missing", | 
| - [handler, "getOwnPropertyDescriptor"]); | 
| - } | 
| - var descriptor = %_CallFunction(handler, p, getOwnProperty); | 
| + var descriptor = CallTrap1(handler, "getOwnPropertyDescriptor", p); | 
| if (IS_UNDEFINED(descriptor)) return descriptor; | 
| var desc = ToCompletePropertyDescriptor(descriptor); | 
| if (!desc.isConfigurable()) { | 
| @@ -644,7 +670,7 @@ function GetOwnProperty(obj, p) { | 
| // GetOwnProperty returns an array indexed by the constants | 
| // defined in macros.py. | 
| // If p is not a property on obj undefined is returned. | 
| - var props = %GetOwnProperty(ToObject(obj), ToString(p)); | 
| + var props = %GetOwnProperty(ToObject(obj), ToString(v)); | 
| // A false value here means that access checks failed. | 
| if (props === false) return void 0; | 
| @@ -656,11 +682,7 @@ function GetOwnProperty(obj, p) { | 
| // Harmony proxies. | 
| function DefineProxyProperty(obj, p, attributes, should_throw) { | 
| var handler = %GetHandler(obj); | 
| - var defineProperty = handler.defineProperty; | 
| - if (IS_UNDEFINED(defineProperty)) { | 
| - throw MakeTypeError("handler_trap_missing", [handler, "defineProperty"]); | 
| - } | 
| - var result = %_CallFunction(handler, p, attributes, defineProperty); | 
| + var result = CallTrap2(handler, "defineProperty", p, attributes); | 
| if (!ToBoolean(result)) { | 
| if (should_throw) { | 
| throw MakeTypeError("handler_returned_false", | 
| @@ -889,12 +911,7 @@ function ObjectGetOwnPropertyNames(obj) { | 
| // Special handling for proxies. | 
| if (%IsJSProxy(obj)) { | 
| var handler = %GetHandler(obj); | 
| - var getOwnPropertyNames = handler.getOwnPropertyNames; | 
| - if (IS_UNDEFINED(getOwnPropertyNames)) { | 
| - throw MakeTypeError("handler_trap_missing", | 
| - [handler, "getOwnPropertyNames"]); | 
| - } | 
| - var names = %_CallFunction(handler, getOwnPropertyNames); | 
| + var names = CallTrap0(handler, "getOwnPropertyNames"); | 
| return ToStringArray(names, "getOwnPropertyNames"); | 
| } | 
| @@ -1024,11 +1041,7 @@ function ObjectDefineProperties(obj, properties) { | 
| // Harmony proxies. | 
| function ProxyFix(obj) { | 
| var handler = %GetHandler(obj); | 
| - var fix = handler.fix; | 
| - if (IS_UNDEFINED(fix)) { | 
| - throw MakeTypeError("handler_trap_missing", [handler, "fix"]); | 
| - } | 
| - var props = %_CallFunction(handler, fix); | 
| + var props = CallTrap0(handler, "fix"); | 
| if (IS_UNDEFINED(props)) { | 
| throw MakeTypeError("handler_returned_undefined", [handler, "fix"]); | 
| } |