OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 // ES5 8.10.3. | 329 // ES5 8.10.3. |
330 function IsGenericDescriptor(desc) { | 330 function IsGenericDescriptor(desc) { |
331 return !(IsAccessorDescriptor(desc) || IsDataDescriptor(desc)); | 331 return !(IsAccessorDescriptor(desc) || IsDataDescriptor(desc)); |
332 } | 332 } |
333 | 333 |
334 | 334 |
335 function IsInconsistentDescriptor(desc) { | 335 function IsInconsistentDescriptor(desc) { |
336 return IsAccessorDescriptor(desc) && IsDataDescriptor(desc); | 336 return IsAccessorDescriptor(desc) && IsDataDescriptor(desc); |
337 } | 337 } |
338 | 338 |
| 339 |
339 // ES5 8.10.4 | 340 // ES5 8.10.4 |
340 function FromPropertyDescriptor(desc) { | 341 function FromPropertyDescriptor(desc) { |
341 if (IS_UNDEFINED(desc)) return desc; | 342 if (IS_UNDEFINED(desc)) return desc; |
342 var obj = new $Object(); | 343 var obj = new $Object(); |
343 if (IsDataDescriptor(desc)) { | 344 if (IsDataDescriptor(desc)) { |
344 obj.value = desc.getValue(); | 345 obj.value = desc.getValue(); |
345 obj.writable = desc.isWritable(); | 346 obj.writable = desc.isWritable(); |
346 } | 347 } |
347 if (IsAccessorDescriptor(desc)) { | 348 if (IsAccessorDescriptor(desc)) { |
348 obj.get = desc.getGet(); | 349 obj.get = desc.getGet(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 desc.setSet(set); | 393 desc.setSet(set); |
393 } | 394 } |
394 | 395 |
395 if (IsInconsistentDescriptor(desc)) { | 396 if (IsInconsistentDescriptor(desc)) { |
396 throw MakeTypeError("value_and_accessor", [obj]); | 397 throw MakeTypeError("value_and_accessor", [obj]); |
397 } | 398 } |
398 return desc; | 399 return desc; |
399 } | 400 } |
400 | 401 |
401 | 402 |
| 403 // For Harmony proxies. |
| 404 function ToCompletePropertyDescriptor(obj) { |
| 405 var desc = ToPropertyDescriptor(obj) |
| 406 if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) { |
| 407 if (!("value" in desc)) desc.value = void 0; |
| 408 if (!("writable" in desc)) desc.writable = false; |
| 409 } else { |
| 410 // Is accessor descriptor. |
| 411 if (!("get" in desc)) desc.get = void 0; |
| 412 if (!("set" in desc)) desc.set = void 0; |
| 413 } |
| 414 if (!("enumerable" in desc)) desc.enumerable = false; |
| 415 if (!("configurable" in desc)) desc.configurable = false; |
| 416 return desc; |
| 417 } |
| 418 |
| 419 |
402 function PropertyDescriptor() { | 420 function PropertyDescriptor() { |
403 // Initialize here so they are all in-object and have the same map. | 421 // Initialize here so they are all in-object and have the same map. |
404 // Default values from ES5 8.6.1. | 422 // Default values from ES5 8.6.1. |
405 this.value_ = void 0; | 423 this.value_ = void 0; |
406 this.hasValue_ = false; | 424 this.hasValue_ = false; |
407 this.writable_ = false; | 425 this.writable_ = false; |
408 this.hasWritable_ = false; | 426 this.hasWritable_ = false; |
409 this.enumerable_ = false; | 427 this.enumerable_ = false; |
410 this.hasEnumerable_ = false; | 428 this.hasEnumerable_ = false; |
411 this.configurable_ = false; | 429 this.configurable_ = false; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 } | 558 } |
541 desc.setEnumerable(desc_array[ENUMERABLE_INDEX]); | 559 desc.setEnumerable(desc_array[ENUMERABLE_INDEX]); |
542 desc.setConfigurable(desc_array[CONFIGURABLE_INDEX]); | 560 desc.setConfigurable(desc_array[CONFIGURABLE_INDEX]); |
543 | 561 |
544 return desc; | 562 return desc; |
545 } | 563 } |
546 | 564 |
547 | 565 |
548 // ES5 section 8.12.2. | 566 // ES5 section 8.12.2. |
549 function GetProperty(obj, p) { | 567 function GetProperty(obj, p) { |
| 568 if (%IsJSProxy(obj)) { |
| 569 var handler = %GetHandler(obj); |
| 570 var getProperty = handler.getPropertyDescriptor; |
| 571 if (IS_UNDEFINED(getProperty)) { |
| 572 throw MakeTypeError("handler_trap_missing", |
| 573 [handler, "getPropertyDescriptor"]); |
| 574 } |
| 575 var descriptor = getProperty.call(handler, p); |
| 576 if (IS_UNDEFINED(descriptor)) return descriptor; |
| 577 var desc = ToCompletePropertyDescriptor(descriptor); |
| 578 if (!desc.configurable) { |
| 579 throw MakeTypeError("proxy_prop_not_configurable", |
| 580 [handler, "getPropertyDescriptor", p, descriptor]); |
| 581 } |
| 582 return desc; |
| 583 } |
550 var prop = GetOwnProperty(obj); | 584 var prop = GetOwnProperty(obj); |
551 if (!IS_UNDEFINED(prop)) return prop; | 585 if (!IS_UNDEFINED(prop)) return prop; |
552 var proto = obj.__proto__; | 586 var proto = %GetPrototype(obj); |
553 if (IS_NULL(proto)) return void 0; | 587 if (IS_NULL(proto)) return void 0; |
554 return GetProperty(proto, p); | 588 return GetProperty(proto, p); |
555 } | 589 } |
556 | 590 |
557 | 591 |
558 // ES5 section 8.12.6 | 592 // ES5 section 8.12.6 |
559 function HasProperty(obj, p) { | 593 function HasProperty(obj, p) { |
| 594 if (%IsJSProxy(obj)) { |
| 595 var handler = %GetHandler(obj) |
| 596 var has = handler.has |
| 597 if (IS_UNDEFINED(has)) has = DerivedHasTrap |
| 598 return ToBoolean(has.call(handler, obj, p)) |
| 599 } |
560 var desc = GetProperty(obj, p); | 600 var desc = GetProperty(obj, p); |
561 return IS_UNDEFINED(desc) ? false : true; | 601 return IS_UNDEFINED(desc) ? false : true; |
562 } | 602 } |
563 | 603 |
564 | 604 |
565 // ES5 section 8.12.1. | 605 // ES5 section 8.12.1. |
566 function GetOwnProperty(obj, p) { | 606 function GetOwnProperty(obj, p) { |
567 // GetOwnProperty returns an array indexed by the constants | 607 // GetOwnProperty returns an array indexed by the constants |
568 // defined in macros.py. | 608 // defined in macros.py. |
569 // If p is not a property on obj undefined is returned. | 609 // If p is not a property on obj undefined is returned. |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 } | 778 } |
739 } | 779 } |
740 return true; | 780 return true; |
741 } | 781 } |
742 | 782 |
743 | 783 |
744 // ES5 section 15.2.3.2. | 784 // ES5 section 15.2.3.2. |
745 function ObjectGetPrototypeOf(obj) { | 785 function ObjectGetPrototypeOf(obj) { |
746 if (!IS_SPEC_OBJECT(obj)) | 786 if (!IS_SPEC_OBJECT(obj)) |
747 throw MakeTypeError("obj_ctor_property_non_object", ["getPrototypeOf"]); | 787 throw MakeTypeError("obj_ctor_property_non_object", ["getPrototypeOf"]); |
748 return obj.__proto__; | 788 return %GetPrototype(obj); |
749 } | 789 } |
750 | 790 |
751 | 791 |
752 // ES5 section 15.2.3.3 | 792 // ES5 section 15.2.3.3 |
753 function ObjectGetOwnPropertyDescriptor(obj, p) { | 793 function ObjectGetOwnPropertyDescriptor(obj, p) { |
754 if (!IS_SPEC_OBJECT(obj)) | 794 if (!IS_SPEC_OBJECT(obj)) |
755 throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyDescript
or"]); | 795 throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyDescript
or"]); |
756 var desc = GetOwnProperty(obj, p); | 796 var desc = GetOwnProperty(obj, p); |
757 return FromPropertyDescriptor(desc); | 797 return FromPropertyDescriptor(desc); |
758 } | 798 } |
759 | 799 |
760 | 800 |
| 801 // For Harmony proxies |
| 802 function ToStringArray(obj, trap) { |
| 803 if (!IS_SPEC_OBJECT(obj)) { |
| 804 throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]); |
| 805 } |
| 806 var n = ToUint32(obj.length); |
| 807 var array = new $Array(n); |
| 808 var names = {} |
| 809 for (var index = 0; index < n; index++) { |
| 810 var s = ToString(obj[index]); |
| 811 if (s in names) { |
| 812 throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]) |
| 813 } |
| 814 array[index] = s; |
| 815 names.s = 0; |
| 816 } |
| 817 return array; |
| 818 } |
| 819 |
| 820 |
761 // ES5 section 15.2.3.4. | 821 // ES5 section 15.2.3.4. |
762 function ObjectGetOwnPropertyNames(obj) { | 822 function ObjectGetOwnPropertyNames(obj) { |
763 if (!IS_SPEC_OBJECT(obj)) | 823 if (!IS_SPEC_OBJECT(obj)) |
764 throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyNames"])
; | 824 throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyNames"])
; |
765 | 825 |
| 826 // Special handling for proxies. |
| 827 if (%IsJSProxy(obj)) { |
| 828 var handler = %GetHandler(obj); |
| 829 var getOwnPropertyNames = handler.getOwnPropertyNames; |
| 830 if (IS_UNDEFINED(getOwnPropertyNames)) { |
| 831 throw MakeTypeError("handler_trap_missing", |
| 832 [handler, "getOwnPropertyNames"]); |
| 833 } |
| 834 var names = getOwnPropertyNames.call(handler); |
| 835 return ToStringArray(names, "getOwnPropertyNames"); |
| 836 } |
| 837 |
766 // Find all the indexed properties. | 838 // Find all the indexed properties. |
767 | 839 |
768 // Get the local element names. | 840 // Get the local element names. |
769 var propertyNames = %GetLocalElementNames(obj); | 841 var propertyNames = %GetLocalElementNames(obj); |
770 | 842 |
771 // Get names for indexed interceptor properties. | 843 // Get names for indexed interceptor properties. |
772 if (%GetInterceptorInfo(obj) & 1) { | 844 if (%GetInterceptorInfo(obj) & 1) { |
773 var indexedInterceptorNames = | 845 var indexedInterceptorNames = |
774 %GetIndexedInterceptorElementNames(obj); | 846 %GetIndexedInterceptorElementNames(obj); |
775 if (indexedInterceptorNames) | 847 if (indexedInterceptorNames) |
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1314 // ---------------------------------------------------------------------------- | 1386 // ---------------------------------------------------------------------------- |
1315 | 1387 |
1316 function SetupFunction() { | 1388 function SetupFunction() { |
1317 InstallFunctions($Function.prototype, DONT_ENUM, $Array( | 1389 InstallFunctions($Function.prototype, DONT_ENUM, $Array( |
1318 "bind", FunctionBind, | 1390 "bind", FunctionBind, |
1319 "toString", FunctionToString | 1391 "toString", FunctionToString |
1320 )); | 1392 )); |
1321 } | 1393 } |
1322 | 1394 |
1323 SetupFunction(); | 1395 SetupFunction(); |
OLD | NEW |