| 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 |