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 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 | 249 |
250 // ECMA-262 - 15.2.4.4 | 250 // ECMA-262 - 15.2.4.4 |
251 function ObjectValueOf() { | 251 function ObjectValueOf() { |
252 return ToObject(this); | 252 return ToObject(this); |
253 } | 253 } |
254 | 254 |
255 | 255 |
256 // ECMA-262 - 15.2.4.5 | 256 // ECMA-262 - 15.2.4.5 |
257 function ObjectHasOwnProperty(V) { | 257 function ObjectHasOwnProperty(V) { |
258 if (%IsJSProxy(this)) { | 258 if (%IsJSProxy(this)) { |
| 259 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 260 if (IS_SYMBOL(V)) return false; |
| 261 |
259 var handler = %GetHandler(this); | 262 var handler = %GetHandler(this); |
260 return CallTrap1(handler, "hasOwn", DerivedHasOwnTrap, ToName(V)); | 263 return CallTrap1(handler, "hasOwn", DerivedHasOwnTrap, ToName(V)); |
261 } | 264 } |
262 return %HasLocalProperty(TO_OBJECT_INLINE(this), ToName(V)); | 265 return %HasLocalProperty(TO_OBJECT_INLINE(this), ToName(V)); |
263 } | 266 } |
264 | 267 |
265 | 268 |
266 // ECMA-262 - 15.2.4.6 | 269 // ECMA-262 - 15.2.4.6 |
267 function ObjectIsPrototypeOf(V) { | 270 function ObjectIsPrototypeOf(V) { |
268 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | 271 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { |
269 throw MakeTypeError("called_on_null_or_undefined", | 272 throw MakeTypeError("called_on_null_or_undefined", |
270 ["Object.prototype.isPrototypeOf"]); | 273 ["Object.prototype.isPrototypeOf"]); |
271 } | 274 } |
272 if (!IS_SPEC_OBJECT(V)) return false; | 275 if (!IS_SPEC_OBJECT(V)) return false; |
273 return %IsInPrototypeChain(this, V); | 276 return %IsInPrototypeChain(this, V); |
274 } | 277 } |
275 | 278 |
276 | 279 |
277 // ECMA-262 - 15.2.4.6 | 280 // ECMA-262 - 15.2.4.6 |
278 function ObjectPropertyIsEnumerable(V) { | 281 function ObjectPropertyIsEnumerable(V) { |
279 var P = ToName(V); | 282 var P = ToName(V); |
280 if (%IsJSProxy(this)) { | 283 if (%IsJSProxy(this)) { |
| 284 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 285 if (IS_SYMBOL(V)) return false; |
| 286 |
281 var desc = GetOwnProperty(this, P); | 287 var desc = GetOwnProperty(this, P); |
282 return IS_UNDEFINED(desc) ? false : desc.isEnumerable(); | 288 return IS_UNDEFINED(desc) ? false : desc.isEnumerable(); |
283 } | 289 } |
284 return %IsPropertyEnumerable(ToObject(this), P); | 290 return %IsPropertyEnumerable(ToObject(this), P); |
285 } | 291 } |
286 | 292 |
287 | 293 |
288 // Extensions for providing property getters and setters. | 294 // Extensions for providing property getters and setters. |
289 function ObjectDefineGetter(name, fun) { | 295 function ObjectDefineGetter(name, fun) { |
290 var receiver = this; | 296 var receiver = this; |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 | 644 |
639 function CallTrap2(handler, name, defaultTrap, x, y) { | 645 function CallTrap2(handler, name, defaultTrap, x, y) { |
640 return %_CallFunction(handler, x, y, GetTrap(handler, name, defaultTrap)); | 646 return %_CallFunction(handler, x, y, GetTrap(handler, name, defaultTrap)); |
641 } | 647 } |
642 | 648 |
643 | 649 |
644 // ES5 section 8.12.1. | 650 // ES5 section 8.12.1. |
645 function GetOwnProperty(obj, v) { | 651 function GetOwnProperty(obj, v) { |
646 var p = ToName(v); | 652 var p = ToName(v); |
647 if (%IsJSProxy(obj)) { | 653 if (%IsJSProxy(obj)) { |
| 654 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 655 if (IS_SYMBOL(v)) return void 0; |
| 656 |
648 var handler = %GetHandler(obj); | 657 var handler = %GetHandler(obj); |
649 var descriptor = CallTrap1(handler, "getOwnPropertyDescriptor", void 0, p); | 658 var descriptor = CallTrap1(handler, "getOwnPropertyDescriptor", void 0, p); |
650 if (IS_UNDEFINED(descriptor)) return descriptor; | 659 if (IS_UNDEFINED(descriptor)) return descriptor; |
651 var desc = ToCompletePropertyDescriptor(descriptor); | 660 var desc = ToCompletePropertyDescriptor(descriptor); |
652 if (!desc.isConfigurable()) { | 661 if (!desc.isConfigurable()) { |
653 throw MakeTypeError("proxy_prop_not_configurable", | 662 throw MakeTypeError("proxy_prop_not_configurable", |
654 [handler, "getOwnPropertyDescriptor", p, descriptor]); | 663 [handler, "getOwnPropertyDescriptor", p, descriptor]); |
655 } | 664 } |
656 return desc; | 665 return desc; |
657 } | 666 } |
(...skipping 20 matching lines...) Expand all Loading... |
678 } else if (should_throw) { | 687 } else if (should_throw) { |
679 throw MakeTypeError("define_disallowed", [p]); | 688 throw MakeTypeError("define_disallowed", [p]); |
680 } else { | 689 } else { |
681 return; | 690 return; |
682 } | 691 } |
683 } | 692 } |
684 | 693 |
685 | 694 |
686 // Harmony proxies. | 695 // Harmony proxies. |
687 function DefineProxyProperty(obj, p, attributes, should_throw) { | 696 function DefineProxyProperty(obj, p, attributes, should_throw) { |
| 697 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 698 if (IS_SYMBOL(p)) return false; |
| 699 |
688 var handler = %GetHandler(obj); | 700 var handler = %GetHandler(obj); |
689 var result = CallTrap2(handler, "defineProperty", void 0, p, attributes); | 701 var result = CallTrap2(handler, "defineProperty", void 0, p, attributes); |
690 if (!ToBoolean(result)) { | 702 if (!ToBoolean(result)) { |
691 if (should_throw) { | 703 if (should_throw) { |
692 throw MakeTypeError("handler_returned_false", | 704 throw MakeTypeError("handler_returned_false", |
693 [handler, "defineProperty"]); | 705 [handler, "defineProperty"]); |
694 } else { | 706 } else { |
695 return false; | 707 return false; |
696 } | 708 } |
697 } | 709 } |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
943 } | 955 } |
944 | 956 |
945 // Step 5 - Fallback to default implementation. | 957 // Step 5 - Fallback to default implementation. |
946 return DefineObjectProperty(obj, p, desc, should_throw); | 958 return DefineObjectProperty(obj, p, desc, should_throw); |
947 } | 959 } |
948 | 960 |
949 | 961 |
950 // ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies. | 962 // ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies. |
951 function DefineOwnProperty(obj, p, desc, should_throw) { | 963 function DefineOwnProperty(obj, p, desc, should_throw) { |
952 if (%IsJSProxy(obj)) { | 964 if (%IsJSProxy(obj)) { |
| 965 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 966 if (IS_SYMBOL(p)) return false; |
| 967 |
953 var attributes = FromGenericPropertyDescriptor(desc); | 968 var attributes = FromGenericPropertyDescriptor(desc); |
954 return DefineProxyProperty(obj, p, attributes, should_throw); | 969 return DefineProxyProperty(obj, p, attributes, should_throw); |
955 } else if (IS_ARRAY(obj)) { | 970 } else if (IS_ARRAY(obj)) { |
956 return DefineArrayProperty(obj, p, desc, should_throw); | 971 return DefineArrayProperty(obj, p, desc, should_throw); |
957 } else { | 972 } else { |
958 return DefineObjectProperty(obj, p, desc, should_throw); | 973 return DefineObjectProperty(obj, p, desc, should_throw); |
959 } | 974 } |
960 } | 975 } |
961 | 976 |
962 | 977 |
(...skipping 17 matching lines...) Expand all Loading... |
980 } | 995 } |
981 | 996 |
982 | 997 |
983 // For Harmony proxies | 998 // For Harmony proxies |
984 function ToNameArray(obj, trap, includeSymbols) { | 999 function ToNameArray(obj, trap, includeSymbols) { |
985 if (!IS_SPEC_OBJECT(obj)) { | 1000 if (!IS_SPEC_OBJECT(obj)) { |
986 throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]); | 1001 throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]); |
987 } | 1002 } |
988 var n = ToUint32(obj.length); | 1003 var n = ToUint32(obj.length); |
989 var array = new $Array(n); | 1004 var array = new $Array(n); |
| 1005 var realLength = 0; |
990 var names = { __proto__: null }; // TODO(rossberg): use sets once ready. | 1006 var names = { __proto__: null }; // TODO(rossberg): use sets once ready. |
991 for (var index = 0; index < n; index++) { | 1007 for (var index = 0; index < n; index++) { |
992 var s = ToName(obj[index]); | 1008 var s = ToName(obj[index]); |
| 1009 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
993 if (IS_SYMBOL(s) && !includeSymbols) continue; | 1010 if (IS_SYMBOL(s) && !includeSymbols) continue; |
994 if (%HasLocalProperty(names, s)) { | 1011 if (%HasLocalProperty(names, s)) { |
995 throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]); | 1012 throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]); |
996 } | 1013 } |
997 array[index] = s; | 1014 array[index] = s; |
| 1015 ++realLength; |
998 names[s] = 0; | 1016 names[s] = 0; |
999 } | 1017 } |
| 1018 array.length = realLength; |
1000 return array; | 1019 return array; |
1001 } | 1020 } |
1002 | 1021 |
1003 | 1022 |
1004 // ES5 section 15.2.3.4. | 1023 // ES5 section 15.2.3.4. |
1005 function ObjectGetOwnPropertyNames(obj) { | 1024 function ObjectGetOwnPropertyNames(obj) { |
1006 if (!IS_SPEC_OBJECT(obj)) { | 1025 if (!IS_SPEC_OBJECT(obj)) { |
1007 throw MakeTypeError("called_on_non_object", ["Object.getOwnPropertyNames"]); | 1026 throw MakeTypeError("called_on_non_object", ["Object.getOwnPropertyNames"]); |
1008 } | 1027 } |
1009 // Special handling for proxies. | 1028 // Special handling for proxies. |
1010 if (%IsJSProxy(obj)) { | 1029 if (%IsJSProxy(obj)) { |
1011 var handler = %GetHandler(obj); | 1030 var handler = %GetHandler(obj); |
1012 var names = CallTrap0(handler, "getOwnPropertyNames", void 0); | 1031 var names = CallTrap0(handler, "getOwnPropertyNames", void 0); |
1013 return ToNameArray(names, "getOwnPropertyNames", true); | 1032 return ToNameArray(names, "getOwnPropertyNames", false); |
1014 } | 1033 } |
1015 | 1034 |
1016 var nameArrays = new InternalArray(); | 1035 var nameArrays = new InternalArray(); |
1017 | 1036 |
1018 // Find all the indexed properties. | 1037 // Find all the indexed properties. |
1019 | 1038 |
1020 // Get the local element names. | 1039 // Get the local element names. |
1021 var localElementNames = %GetLocalElementNames(obj); | 1040 var localElementNames = %GetLocalElementNames(obj); |
1022 for (var i = 0; i < localElementNames.length; ++i) { | 1041 for (var i = 0; i < localElementNames.length; ++i) { |
1023 localElementNames[i] = %_NumberToString(localElementNames[i]); | 1042 localElementNames[i] = %_NumberToString(localElementNames[i]); |
1024 } | 1043 } |
1025 nameArrays.push(localElementNames); | 1044 nameArrays.push(localElementNames); |
1026 | 1045 |
1027 // Get names for indexed interceptor properties. | 1046 // Get names for indexed interceptor properties. |
1028 var interceptorInfo = %GetInterceptorInfo(obj); | 1047 var interceptorInfo = %GetInterceptorInfo(obj); |
1029 if ((interceptorInfo & 1) != 0) { | 1048 if ((interceptorInfo & 1) != 0) { |
1030 var indexedInterceptorNames = %GetIndexedInterceptorElementNames(obj); | 1049 var indexedInterceptorNames = %GetIndexedInterceptorElementNames(obj); |
1031 if (!IS_UNDEFINED(indexedInterceptorNames)) { | 1050 if (!IS_UNDEFINED(indexedInterceptorNames)) { |
1032 nameArrays.push(indexedInterceptorNames); | 1051 nameArrays.push(indexedInterceptorNames); |
1033 } | 1052 } |
1034 } | 1053 } |
1035 | 1054 |
1036 // Find all the named properties. | 1055 // Find all the named properties. |
1037 | 1056 |
1038 // Get the local property names. | 1057 // Get the local property names. |
1039 nameArrays.push(%GetLocalPropertyNames(obj)); | 1058 nameArrays.push(%GetLocalPropertyNames(obj, false)); |
1040 | 1059 |
1041 // Get names for named interceptor properties if any. | 1060 // Get names for named interceptor properties if any. |
1042 if ((interceptorInfo & 2) != 0) { | 1061 if ((interceptorInfo & 2) != 0) { |
1043 var namedInterceptorNames = %GetNamedInterceptorPropertyNames(obj); | 1062 var namedInterceptorNames = %GetNamedInterceptorPropertyNames(obj); |
1044 if (!IS_UNDEFINED(namedInterceptorNames)) { | 1063 if (!IS_UNDEFINED(namedInterceptorNames)) { |
1045 nameArrays.push(namedInterceptorNames); | 1064 nameArrays.push(namedInterceptorNames); |
1046 } | 1065 } |
1047 } | 1066 } |
1048 | 1067 |
1049 var propertyNames = | 1068 var propertyNames = |
1050 %Apply(InternalArray.prototype.concat, | 1069 %Apply(InternalArray.prototype.concat, |
1051 nameArrays[0], nameArrays, 1, nameArrays.length - 1); | 1070 nameArrays[0], nameArrays, 1, nameArrays.length - 1); |
1052 | 1071 |
1053 // Property names are expected to be unique strings, | 1072 // Property names are expected to be unique strings, |
1054 // but interceptors can interfere with that assumption. | 1073 // but interceptors can interfere with that assumption. |
1055 if (interceptorInfo != 0) { | 1074 if (interceptorInfo != 0) { |
1056 var propertySet = { __proto__: null }; | 1075 var propertySet = { __proto__: null }; |
1057 var j = 0; | 1076 var j = 0; |
1058 for (var i = 0; i < propertyNames.length; ++i) { | 1077 for (var i = 0; i < propertyNames.length; ++i) { |
1059 var name = ToName(propertyNames[i]); | 1078 if (IS_SYMBOL(propertyNames[i])) continue; |
| 1079 var name = ToString(propertyNames[i]); |
1060 // We need to check for the exact property value since for intrinsic | 1080 // We need to check for the exact property value since for intrinsic |
1061 // properties like toString if(propertySet["toString"]) will always | 1081 // properties like toString if(propertySet["toString"]) will always |
1062 // succeed. | 1082 // succeed. |
1063 if (propertySet[name] === true) { | 1083 if (propertySet[name] === true) { |
1064 continue; | 1084 continue; |
1065 } | 1085 } |
1066 propertySet[name] = true; | 1086 propertySet[name] = true; |
1067 propertyNames[j++] = name; | 1087 propertyNames[j++] = name; |
1068 } | 1088 } |
1069 propertyNames.length = j; | 1089 propertyNames.length = j; |
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1731 | 1751 |
1732 function SetUpFunction() { | 1752 function SetUpFunction() { |
1733 %CheckIsBootstrapping(); | 1753 %CheckIsBootstrapping(); |
1734 InstallFunctions($Function.prototype, DONT_ENUM, $Array( | 1754 InstallFunctions($Function.prototype, DONT_ENUM, $Array( |
1735 "bind", FunctionBind, | 1755 "bind", FunctionBind, |
1736 "toString", FunctionToString | 1756 "toString", FunctionToString |
1737 )); | 1757 )); |
1738 } | 1758 } |
1739 | 1759 |
1740 SetUpFunction(); | 1760 SetUpFunction(); |
OLD | NEW |