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 |