| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 // ECMA-262 - 15.2.4.4 | 251 // ECMA-262 - 15.2.4.4 |
| 252 function ObjectValueOf() { | 252 function ObjectValueOf() { |
| 253 return ToObject(this); | 253 return ToObject(this); |
| 254 } | 254 } |
| 255 | 255 |
| 256 | 256 |
| 257 // ECMA-262 - 15.2.4.5 | 257 // ECMA-262 - 15.2.4.5 |
| 258 function ObjectHasOwnProperty(V) { | 258 function ObjectHasOwnProperty(V) { |
| 259 if (%IsJSProxy(this)) { | 259 if (%IsJSProxy(this)) { |
| 260 var handler = %GetHandler(this); | 260 var handler = %GetHandler(this); |
| 261 return CallTrap1(handler, "hasOwn", DerivedHasOwnTrap, TO_STRING_INLINE(V)); | 261 return CallTrap1(handler, "hasOwn", DerivedHasOwnTrap, ToName(V)); |
| 262 } | 262 } |
| 263 return %HasLocalProperty(TO_OBJECT_INLINE(this), TO_STRING_INLINE(V)); | 263 return %HasLocalProperty(TO_OBJECT_INLINE(this), ToName(V)); |
| 264 } | 264 } |
| 265 | 265 |
| 266 | 266 |
| 267 // ECMA-262 - 15.2.4.6 | 267 // ECMA-262 - 15.2.4.6 |
| 268 function ObjectIsPrototypeOf(V) { | 268 function ObjectIsPrototypeOf(V) { |
| 269 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | 269 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { |
| 270 throw MakeTypeError("called_on_null_or_undefined", | 270 throw MakeTypeError("called_on_null_or_undefined", |
| 271 ["Object.prototype.isPrototypeOf"]); | 271 ["Object.prototype.isPrototypeOf"]); |
| 272 } | 272 } |
| 273 if (!IS_SPEC_OBJECT(V)) return false; | 273 if (!IS_SPEC_OBJECT(V)) return false; |
| 274 return %IsInPrototypeChain(this, V); | 274 return %IsInPrototypeChain(this, V); |
| 275 } | 275 } |
| 276 | 276 |
| 277 | 277 |
| 278 // ECMA-262 - 15.2.4.6 | 278 // ECMA-262 - 15.2.4.6 |
| 279 function ObjectPropertyIsEnumerable(V) { | 279 function ObjectPropertyIsEnumerable(V) { |
| 280 var P = ToString(V); | 280 var P = ToName(V); |
| 281 if (%IsJSProxy(this)) { | 281 if (%IsJSProxy(this)) { |
| 282 var desc = GetOwnProperty(this, P); | 282 var desc = GetOwnProperty(this, P); |
| 283 return IS_UNDEFINED(desc) ? false : desc.isEnumerable(); | 283 return IS_UNDEFINED(desc) ? false : desc.isEnumerable(); |
| 284 } | 284 } |
| 285 return %IsPropertyEnumerable(ToObject(this), P); | 285 return %IsPropertyEnumerable(ToObject(this), P); |
| 286 } | 286 } |
| 287 | 287 |
| 288 | 288 |
| 289 // Extensions for providing property getters and setters. | 289 // Extensions for providing property getters and setters. |
| 290 function ObjectDefineGetter(name, fun) { | 290 function ObjectDefineGetter(name, fun) { |
| 291 var receiver = this; | 291 var receiver = this; |
| 292 if (receiver == null && !IS_UNDETECTABLE(receiver)) { | 292 if (receiver == null && !IS_UNDETECTABLE(receiver)) { |
| 293 receiver = %GlobalReceiver(global); | 293 receiver = %GlobalReceiver(global); |
| 294 } | 294 } |
| 295 if (!IS_SPEC_FUNCTION(fun)) { | 295 if (!IS_SPEC_FUNCTION(fun)) { |
| 296 throw new $TypeError( | 296 throw new $TypeError( |
| 297 'Object.prototype.__defineGetter__: Expecting function'); | 297 'Object.prototype.__defineGetter__: Expecting function'); |
| 298 } | 298 } |
| 299 var desc = new PropertyDescriptor(); | 299 var desc = new PropertyDescriptor(); |
| 300 desc.setGet(fun); | 300 desc.setGet(fun); |
| 301 desc.setEnumerable(true); | 301 desc.setEnumerable(true); |
| 302 desc.setConfigurable(true); | 302 desc.setConfigurable(true); |
| 303 DefineOwnProperty(ToObject(receiver), ToString(name), desc, false); | 303 DefineOwnProperty(ToObject(receiver), ToName(name), desc, false); |
| 304 } | 304 } |
| 305 | 305 |
| 306 | 306 |
| 307 function ObjectLookupGetter(name) { | 307 function ObjectLookupGetter(name) { |
| 308 var receiver = this; | 308 var receiver = this; |
| 309 if (receiver == null && !IS_UNDETECTABLE(receiver)) { | 309 if (receiver == null && !IS_UNDETECTABLE(receiver)) { |
| 310 receiver = %GlobalReceiver(global); | 310 receiver = %GlobalReceiver(global); |
| 311 } | 311 } |
| 312 return %LookupAccessor(ToObject(receiver), ToString(name), GETTER); | 312 return %LookupAccessor(ToObject(receiver), ToName(name), GETTER); |
| 313 } | 313 } |
| 314 | 314 |
| 315 | 315 |
| 316 function ObjectDefineSetter(name, fun) { | 316 function ObjectDefineSetter(name, fun) { |
| 317 var receiver = this; | 317 var receiver = this; |
| 318 if (receiver == null && !IS_UNDETECTABLE(receiver)) { | 318 if (receiver == null && !IS_UNDETECTABLE(receiver)) { |
| 319 receiver = %GlobalReceiver(global); | 319 receiver = %GlobalReceiver(global); |
| 320 } | 320 } |
| 321 if (!IS_SPEC_FUNCTION(fun)) { | 321 if (!IS_SPEC_FUNCTION(fun)) { |
| 322 throw new $TypeError( | 322 throw new $TypeError( |
| 323 'Object.prototype.__defineSetter__: Expecting function'); | 323 'Object.prototype.__defineSetter__: Expecting function'); |
| 324 } | 324 } |
| 325 var desc = new PropertyDescriptor(); | 325 var desc = new PropertyDescriptor(); |
| 326 desc.setSet(fun); | 326 desc.setSet(fun); |
| 327 desc.setEnumerable(true); | 327 desc.setEnumerable(true); |
| 328 desc.setConfigurable(true); | 328 desc.setConfigurable(true); |
| 329 DefineOwnProperty(ToObject(receiver), ToString(name), desc, false); | 329 DefineOwnProperty(ToObject(receiver), ToName(name), desc, false); |
| 330 } | 330 } |
| 331 | 331 |
| 332 | 332 |
| 333 function ObjectLookupSetter(name) { | 333 function ObjectLookupSetter(name) { |
| 334 var receiver = this; | 334 var receiver = this; |
| 335 if (receiver == null && !IS_UNDETECTABLE(receiver)) { | 335 if (receiver == null && !IS_UNDETECTABLE(receiver)) { |
| 336 receiver = %GlobalReceiver(global); | 336 receiver = %GlobalReceiver(global); |
| 337 } | 337 } |
| 338 return %LookupAccessor(ToObject(receiver), ToString(name), SETTER); | 338 return %LookupAccessor(ToObject(receiver), ToName(name), SETTER); |
| 339 } | 339 } |
| 340 | 340 |
| 341 | 341 |
| 342 function ObjectKeys(obj) { | 342 function ObjectKeys(obj) { |
| 343 if (!IS_SPEC_OBJECT(obj)) { | 343 if (!IS_SPEC_OBJECT(obj)) { |
| 344 throw MakeTypeError("called_on_non_object", ["Object.keys"]); | 344 throw MakeTypeError("called_on_non_object", ["Object.keys"]); |
| 345 } | 345 } |
| 346 if (%IsJSProxy(obj)) { | 346 if (%IsJSProxy(obj)) { |
| 347 var handler = %GetHandler(obj); | 347 var handler = %GetHandler(obj); |
| 348 var names = CallTrap0(handler, "keys", DerivedKeysTrap); | 348 var names = CallTrap0(handler, "keys", DerivedKeysTrap); |
| 349 return ToStringArray(names, "keys"); | 349 // TODO(rossberg): filter non-string keys. |
| 350 return ToNameArray(names, "keys"); |
| 350 } | 351 } |
| 351 return %LocalKeys(obj); | 352 return %LocalKeys(obj); |
| 352 } | 353 } |
| 353 | 354 |
| 354 | 355 |
| 355 // ES5 8.10.1. | 356 // ES5 8.10.1. |
| 356 function IsAccessorDescriptor(desc) { | 357 function IsAccessorDescriptor(desc) { |
| 357 if (IS_UNDEFINED(desc)) return false; | 358 if (IS_UNDEFINED(desc)) return false; |
| 358 return desc.hasGetter() || desc.hasSetter(); | 359 return desc.hasGetter() || desc.hasSetter(); |
| 359 } | 360 } |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 } | 638 } |
| 638 | 639 |
| 639 | 640 |
| 640 function CallTrap2(handler, name, defaultTrap, x, y) { | 641 function CallTrap2(handler, name, defaultTrap, x, y) { |
| 641 return %_CallFunction(handler, x, y, GetTrap(handler, name, defaultTrap)); | 642 return %_CallFunction(handler, x, y, GetTrap(handler, name, defaultTrap)); |
| 642 } | 643 } |
| 643 | 644 |
| 644 | 645 |
| 645 // ES5 section 8.12.1. | 646 // ES5 section 8.12.1. |
| 646 function GetOwnProperty(obj, v) { | 647 function GetOwnProperty(obj, v) { |
| 647 var p = ToString(v); | 648 var p = ToName(v); |
| 648 if (%IsJSProxy(obj)) { | 649 if (%IsJSProxy(obj)) { |
| 649 var handler = %GetHandler(obj); | 650 var handler = %GetHandler(obj); |
| 650 var descriptor = CallTrap1(handler, "getOwnPropertyDescriptor", void 0, p); | 651 var descriptor = CallTrap1(handler, "getOwnPropertyDescriptor", void 0, p); |
| 651 if (IS_UNDEFINED(descriptor)) return descriptor; | 652 if (IS_UNDEFINED(descriptor)) return descriptor; |
| 652 var desc = ToCompletePropertyDescriptor(descriptor); | 653 var desc = ToCompletePropertyDescriptor(descriptor); |
| 653 if (!desc.isConfigurable()) { | 654 if (!desc.isConfigurable()) { |
| 654 throw MakeTypeError("proxy_prop_not_configurable", | 655 throw MakeTypeError("proxy_prop_not_configurable", |
| 655 [handler, "getOwnPropertyDescriptor", p, descriptor]); | 656 [handler, "getOwnPropertyDescriptor", p, descriptor]); |
| 656 } | 657 } |
| 657 return desc; | 658 return desc; |
| 658 } | 659 } |
| 659 | 660 |
| 660 // GetOwnProperty returns an array indexed by the constants | 661 // GetOwnProperty returns an array indexed by the constants |
| 661 // defined in macros.py. | 662 // defined in macros.py. |
| 662 // If p is not a property on obj undefined is returned. | 663 // If p is not a property on obj undefined is returned. |
| 663 var props = %GetOwnProperty(ToObject(obj), ToString(v)); | 664 var props = %GetOwnProperty(ToObject(obj), p); |
| 664 | 665 |
| 665 // A false value here means that access checks failed. | 666 // A false value here means that access checks failed. |
| 666 if (props === false) return void 0; | 667 if (props === false) return void 0; |
| 667 | 668 |
| 668 return ConvertDescriptorArrayToDescriptor(props); | 669 return ConvertDescriptorArrayToDescriptor(props); |
| 669 } | 670 } |
| 670 | 671 |
| 671 | 672 |
| 672 // ES5 section 8.12.7. | 673 // ES5 section 8.12.7. |
| 673 function Delete(obj, p, should_throw) { | 674 function Delete(obj, p, should_throw) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 695 } else { | 696 } else { |
| 696 return false; | 697 return false; |
| 697 } | 698 } |
| 698 } | 699 } |
| 699 return true; | 700 return true; |
| 700 } | 701 } |
| 701 | 702 |
| 702 | 703 |
| 703 // ES5 8.12.9. | 704 // ES5 8.12.9. |
| 704 function DefineObjectProperty(obj, p, desc, should_throw) { | 705 function DefineObjectProperty(obj, p, desc, should_throw) { |
| 705 var current_or_access = %GetOwnProperty(ToObject(obj), ToString(p)); | 706 var current_or_access = %GetOwnProperty(ToObject(obj), ToName(p)); |
| 706 // A false value here means that access checks failed. | 707 // A false value here means that access checks failed. |
| 707 if (current_or_access === false) return void 0; | 708 if (current_or_access === false) return void 0; |
| 708 | 709 |
| 709 var current = ConvertDescriptorArrayToDescriptor(current_or_access); | 710 var current = ConvertDescriptorArrayToDescriptor(current_or_access); |
| 710 var extensible = %IsExtensible(ToObject(obj)); | 711 var extensible = %IsExtensible(ToObject(obj)); |
| 711 | 712 |
| 712 // Error handling according to spec. | 713 // Error handling according to spec. |
| 713 // Step 3 | 714 // Step 3 |
| 714 if (IS_UNDEFINED(current) && !extensible) { | 715 if (IS_UNDEFINED(current) && !extensible) { |
| 715 if (should_throw) { | 716 if (should_throw) { |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 if (!IS_SPEC_OBJECT(obj)) { | 976 if (!IS_SPEC_OBJECT(obj)) { |
| 976 throw MakeTypeError("called_on_non_object", | 977 throw MakeTypeError("called_on_non_object", |
| 977 ["Object.getOwnPropertyDescriptor"]); | 978 ["Object.getOwnPropertyDescriptor"]); |
| 978 } | 979 } |
| 979 var desc = GetOwnProperty(obj, p); | 980 var desc = GetOwnProperty(obj, p); |
| 980 return FromPropertyDescriptor(desc); | 981 return FromPropertyDescriptor(desc); |
| 981 } | 982 } |
| 982 | 983 |
| 983 | 984 |
| 984 // For Harmony proxies | 985 // For Harmony proxies |
| 985 function ToStringArray(obj, trap) { | 986 function ToNameArray(obj, trap) { |
| 986 if (!IS_SPEC_OBJECT(obj)) { | 987 if (!IS_SPEC_OBJECT(obj)) { |
| 987 throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]); | 988 throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]); |
| 988 } | 989 } |
| 989 var n = ToUint32(obj.length); | 990 var n = ToUint32(obj.length); |
| 990 var array = new $Array(n); | 991 var array = new $Array(n); |
| 991 var names = { __proto__: null }; // TODO(rossberg): use sets once ready. | 992 var names = { __proto__: null }; // TODO(rossberg): use sets once ready. |
| 992 for (var index = 0; index < n; index++) { | 993 for (var index = 0; index < n; index++) { |
| 993 var s = ToString(obj[index]); | 994 var s = ToName(obj[index]); |
| 994 if (%HasLocalProperty(names, s)) { | 995 if (%HasLocalProperty(names, s)) { |
| 995 throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]); | 996 throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]); |
| 996 } | 997 } |
| 997 array[index] = s; | 998 array[index] = s; |
| 998 names[s] = 0; | 999 names[s] = 0; |
| 999 } | 1000 } |
| 1000 return array; | 1001 return array; |
| 1001 } | 1002 } |
| 1002 | 1003 |
| 1003 | 1004 |
| 1004 // ES5 section 15.2.3.4. | 1005 // ES5 section 15.2.3.4. |
| 1005 function ObjectGetOwnPropertyNames(obj) { | 1006 function ObjectGetOwnPropertyNames(obj) { |
| 1006 if (!IS_SPEC_OBJECT(obj)) { | 1007 if (!IS_SPEC_OBJECT(obj)) { |
| 1007 throw MakeTypeError("called_on_non_object", ["Object.getOwnPropertyNames"]); | 1008 throw MakeTypeError("called_on_non_object", ["Object.getOwnPropertyNames"]); |
| 1008 } | 1009 } |
| 1009 // Special handling for proxies. | 1010 // Special handling for proxies. |
| 1010 if (%IsJSProxy(obj)) { | 1011 if (%IsJSProxy(obj)) { |
| 1011 var handler = %GetHandler(obj); | 1012 var handler = %GetHandler(obj); |
| 1012 var names = CallTrap0(handler, "getOwnPropertyNames", void 0); | 1013 var names = CallTrap0(handler, "getOwnPropertyNames", void 0); |
| 1013 return ToStringArray(names, "getOwnPropertyNames"); | 1014 return ToNameArray(names, "getOwnPropertyNames"); |
| 1014 } | 1015 } |
| 1015 | 1016 |
| 1016 // Find all the indexed properties. | 1017 // Find all the indexed properties. |
| 1017 | 1018 |
| 1018 // Get the local element names. | 1019 // Get the local element names. |
| 1019 var propertyNames = %GetLocalElementNames(obj); | 1020 var propertyNames = %GetLocalElementNames(obj); |
| 1020 | 1021 |
| 1021 // Get names for indexed interceptor properties. | 1022 // Get names for indexed interceptor properties. |
| 1022 if (%GetInterceptorInfo(obj) & 1) { | 1023 if (%GetInterceptorInfo(obj) & 1) { |
| 1023 var indexedInterceptorNames = | 1024 var indexedInterceptorNames = |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1035 // Get names for named interceptor properties if any. | 1036 // Get names for named interceptor properties if any. |
| 1036 | 1037 |
| 1037 if (%GetInterceptorInfo(obj) & 2) { | 1038 if (%GetInterceptorInfo(obj) & 2) { |
| 1038 var namedInterceptorNames = | 1039 var namedInterceptorNames = |
| 1039 %GetNamedInterceptorPropertyNames(obj); | 1040 %GetNamedInterceptorPropertyNames(obj); |
| 1040 if (namedInterceptorNames) { | 1041 if (namedInterceptorNames) { |
| 1041 propertyNames = propertyNames.concat(namedInterceptorNames); | 1042 propertyNames = propertyNames.concat(namedInterceptorNames); |
| 1042 } | 1043 } |
| 1043 } | 1044 } |
| 1044 | 1045 |
| 1045 // Property names are expected to be unique strings. | 1046 // Property names are expected to be unique. |
| 1046 var propertySet = { __proto__: null }; | 1047 var propertySet = { __proto__: null }; |
| 1047 var j = 0; | 1048 var j = 0; |
| 1048 for (var i = 0; i < propertyNames.length; ++i) { | 1049 for (var i = 0; i < propertyNames.length; ++i) { |
| 1049 var name = ToString(propertyNames[i]); | 1050 var name = ToName(propertyNames[i]); |
| 1050 // We need to check for the exact property value since for intrinsic | 1051 // We need to check for the exact property value since for intrinsic |
| 1051 // properties like toString if(propertySet["toString"]) will always | 1052 // properties like toString if(propertySet["toString"]) will always |
| 1052 // succeed. | 1053 // succeed. |
| 1053 if (propertySet[name] === true) { | 1054 if (propertySet[name] === true) { |
| 1054 continue; | 1055 continue; |
| 1055 } | 1056 } |
| 1056 propertySet[name] = true; | 1057 propertySet[name] = true; |
| 1057 propertyNames[j++] = name; | 1058 propertyNames[j++] = name; |
| 1058 } | 1059 } |
| 1059 propertyNames.length = j; | 1060 propertyNames.length = j; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1072 if (!IS_UNDEFINED(properties)) ObjectDefineProperties(obj, properties); | 1073 if (!IS_UNDEFINED(properties)) ObjectDefineProperties(obj, properties); |
| 1073 return obj; | 1074 return obj; |
| 1074 } | 1075 } |
| 1075 | 1076 |
| 1076 | 1077 |
| 1077 // ES5 section 15.2.3.6. | 1078 // ES5 section 15.2.3.6. |
| 1078 function ObjectDefineProperty(obj, p, attributes) { | 1079 function ObjectDefineProperty(obj, p, attributes) { |
| 1079 if (!IS_SPEC_OBJECT(obj)) { | 1080 if (!IS_SPEC_OBJECT(obj)) { |
| 1080 throw MakeTypeError("called_on_non_object", ["Object.defineProperty"]); | 1081 throw MakeTypeError("called_on_non_object", ["Object.defineProperty"]); |
| 1081 } | 1082 } |
| 1082 var name = ToString(p); | 1083 var name = ToName(p); |
| 1083 if (%IsJSProxy(obj)) { | 1084 if (%IsJSProxy(obj)) { |
| 1084 // Clone the attributes object for protection. | 1085 // Clone the attributes object for protection. |
| 1085 // TODO(rossberg): not spec'ed yet, so not sure if this should involve | 1086 // TODO(rossberg): not spec'ed yet, so not sure if this should involve |
| 1086 // non-own properties as it does (or non-enumerable ones, as it doesn't?). | 1087 // non-own properties as it does (or non-enumerable ones, as it doesn't?). |
| 1087 var attributesClone = { __proto__: null }; | 1088 var attributesClone = { __proto__: null }; |
| 1088 for (var a in attributes) { | 1089 for (var a in attributes) { |
| 1089 attributesClone[a] = attributes[a]; | 1090 attributesClone[a] = attributes[a]; |
| 1090 } | 1091 } |
| 1091 DefineProxyProperty(obj, name, attributesClone, true); | 1092 DefineProxyProperty(obj, name, attributesClone, true); |
| 1092 // The following would implement the spec as in the current proposal, | 1093 // The following would implement the spec as in the current proposal, |
| (...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1717 | 1718 |
| 1718 function SetUpFunction() { | 1719 function SetUpFunction() { |
| 1719 %CheckIsBootstrapping(); | 1720 %CheckIsBootstrapping(); |
| 1720 InstallFunctions($Function.prototype, DONT_ENUM, $Array( | 1721 InstallFunctions($Function.prototype, DONT_ENUM, $Array( |
| 1721 "bind", FunctionBind, | 1722 "bind", FunctionBind, |
| 1722 "toString", FunctionToString | 1723 "toString", FunctionToString |
| 1723 )); | 1724 )); |
| 1724 } | 1725 } |
| 1725 | 1726 |
| 1726 SetUpFunction(); | 1727 SetUpFunction(); |
| OLD | NEW |