| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 | 347 |
| 348 | 348 |
| 349 function IsInconsistentDescriptor(desc) { | 349 function IsInconsistentDescriptor(desc) { |
| 350 return IsAccessorDescriptor(desc) && IsDataDescriptor(desc); | 350 return IsAccessorDescriptor(desc) && IsDataDescriptor(desc); |
| 351 } | 351 } |
| 352 | 352 |
| 353 | 353 |
| 354 // ES5 8.10.4 | 354 // ES5 8.10.4 |
| 355 function FromPropertyDescriptor(desc) { | 355 function FromPropertyDescriptor(desc) { |
| 356 if (IS_UNDEFINED(desc)) return desc; | 356 if (IS_UNDEFINED(desc)) return desc; |
| 357 var obj = new $Object(); | 357 |
| 358 if (IsDataDescriptor(desc)) { | 358 if (IsDataDescriptor(desc)) { |
| 359 obj.value = desc.getValue(); | 359 return { value: desc.getValue(), |
| 360 obj.writable = desc.isWritable(); | 360 writable: desc.isWritable(), |
| 361 enumerable: desc.isEnumerable(), |
| 362 configurable: desc.isConfigurable() }; |
| 361 } | 363 } |
| 362 if (IsAccessorDescriptor(desc)) { | 364 // Must be an AccessorDescriptor then. We never return a generic descriptor. |
| 363 obj.get = desc.getGet(); | 365 return { get: desc.getGet(), |
| 364 obj.set = desc.getSet(); | 366 set: desc.getSet(), |
| 365 } | 367 enumerable: desc.isEnumerable(), |
| 366 obj.enumerable = desc.isEnumerable(); | 368 configurable: desc.isConfigurable() }; |
| 367 obj.configurable = desc.isConfigurable(); | |
| 368 return obj; | |
| 369 } | 369 } |
| 370 | 370 |
| 371 |
| 371 // Harmony Proxies | 372 // Harmony Proxies |
| 372 function FromGenericPropertyDescriptor(desc) { | 373 function FromGenericPropertyDescriptor(desc) { |
| 373 if (IS_UNDEFINED(desc)) return desc; | 374 if (IS_UNDEFINED(desc)) return desc; |
| 374 var obj = new $Object(); | 375 var obj = new $Object(); |
| 375 if (desc.hasValue()) obj.value = desc.getValue(); | 376 |
| 376 if (desc.hasWritable()) obj.writable = desc.isWritable(); | 377 if (desc.hasValue()) { |
| 377 if (desc.hasGetter()) obj.get = desc.getGet(); | 378 %IgnoreAttributesAndSetProperty(obj, "value", desc.getValue(), NONE); |
| 378 if (desc.hasSetter()) obj.set = desc.getSet(); | 379 } |
| 379 if (desc.hasEnumerable()) obj.enumerable = desc.isEnumerable(); | 380 if (desc.hasWritable()) { |
| 380 if (desc.hasConfigurable()) obj.configurable = desc.isConfigurable(); | 381 %IgnoreAttributesAndSetProperty(obj, "writable", desc.isWritable(), NONE); |
| 382 } |
| 383 if (desc.hasGetter()) { |
| 384 %IgnoreAttributesAndSetProperty(obj, "get", desc.getGet(), NONE); |
| 385 } |
| 386 if (desc.hasSetter()) { |
| 387 %IgnoreAttributesAndSetProperty(obj, "set", desc.getSet(), NONE); |
| 388 } |
| 389 if (desc.hasEnumerable()) { |
| 390 %IgnoreAttributesAndSetProperty(obj, "enumerable", |
| 391 desc.isEnumerable(), NONE); |
| 392 } |
| 393 if (desc.hasConfigurable()) { |
| 394 %IgnoreAttributesAndSetProperty(obj, "configurable", |
| 395 desc.isConfigurable(), NONE); |
| 396 } |
| 381 return obj; | 397 return obj; |
| 382 } | 398 } |
| 383 | 399 |
| 400 |
| 384 // ES5 8.10.5. | 401 // ES5 8.10.5. |
| 385 function ToPropertyDescriptor(obj) { | 402 function ToPropertyDescriptor(obj) { |
| 386 if (!IS_SPEC_OBJECT(obj)) { | 403 if (!IS_SPEC_OBJECT(obj)) { |
| 387 throw MakeTypeError("property_desc_object", [obj]); | 404 throw MakeTypeError("property_desc_object", [obj]); |
| 388 } | 405 } |
| 389 var desc = new PropertyDescriptor(); | 406 var desc = new PropertyDescriptor(); |
| 390 | 407 |
| 391 if ("enumerable" in obj) { | 408 if ("enumerable" in obj) { |
| 392 desc.setEnumerable(ToBoolean(obj.enumerable)); | 409 desc.setEnumerable(ToBoolean(obj.enumerable)); |
| 393 } | 410 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 this.hasEnumerable_ = false; | 472 this.hasEnumerable_ = false; |
| 456 this.configurable_ = false; | 473 this.configurable_ = false; |
| 457 this.hasConfigurable_ = false; | 474 this.hasConfigurable_ = false; |
| 458 this.get_ = void 0; | 475 this.get_ = void 0; |
| 459 this.hasGetter_ = false; | 476 this.hasGetter_ = false; |
| 460 this.set_ = void 0; | 477 this.set_ = void 0; |
| 461 this.hasSetter_ = false; | 478 this.hasSetter_ = false; |
| 462 } | 479 } |
| 463 | 480 |
| 464 PropertyDescriptor.prototype.__proto__ = null; | 481 PropertyDescriptor.prototype.__proto__ = null; |
| 482 |
| 465 PropertyDescriptor.prototype.toString = function() { | 483 PropertyDescriptor.prototype.toString = function() { |
| 466 return "[object PropertyDescriptor]"; | 484 return "[object PropertyDescriptor]"; |
| 467 }; | 485 }; |
| 468 | 486 |
| 469 PropertyDescriptor.prototype.setValue = function(value) { | 487 PropertyDescriptor.prototype.setValue = function(value) { |
| 470 this.value_ = value; | 488 this.value_ = value; |
| 471 this.hasValue_ = true; | 489 this.hasValue_ = true; |
| 472 } | 490 } |
| 473 | 491 |
| 474 | 492 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 function CallTrap1(handler, name, defaultTrap, x) { | 631 function CallTrap1(handler, name, defaultTrap, x) { |
| 614 return %_CallFunction(handler, x, GetTrap(handler, name, defaultTrap)); | 632 return %_CallFunction(handler, x, GetTrap(handler, name, defaultTrap)); |
| 615 } | 633 } |
| 616 | 634 |
| 617 | 635 |
| 618 function CallTrap2(handler, name, defaultTrap, x, y) { | 636 function CallTrap2(handler, name, defaultTrap, x, y) { |
| 619 return %_CallFunction(handler, x, y, GetTrap(handler, name, defaultTrap)); | 637 return %_CallFunction(handler, x, y, GetTrap(handler, name, defaultTrap)); |
| 620 } | 638 } |
| 621 | 639 |
| 622 | 640 |
| 623 // ES5 section 8.12.2. | |
| 624 function GetProperty(obj, p) { | |
| 625 if (%IsJSProxy(obj)) { | |
| 626 var handler = %GetHandler(obj); | |
| 627 var descriptor = CallTrap1(obj, "getPropertyDescriptor", void 0, p); | |
| 628 if (IS_UNDEFINED(descriptor)) return descriptor; | |
| 629 var desc = ToCompletePropertyDescriptor(descriptor); | |
| 630 if (!desc.isConfigurable()) { | |
| 631 throw MakeTypeError("proxy_prop_not_configurable", | |
| 632 [handler, "getPropertyDescriptor", p, descriptor]); | |
| 633 } | |
| 634 return desc; | |
| 635 } | |
| 636 var prop = GetOwnProperty(obj); | |
| 637 if (!IS_UNDEFINED(prop)) return prop; | |
| 638 var proto = %GetPrototype(obj); | |
| 639 if (IS_NULL(proto)) return void 0; | |
| 640 return GetProperty(proto, p); | |
| 641 } | |
| 642 | |
| 643 | |
| 644 // ES5 section 8.12.6 | |
| 645 function HasProperty(obj, p) { | |
| 646 if (%IsJSProxy(obj)) { | |
| 647 var handler = %GetHandler(obj); | |
| 648 return ToBoolean(CallTrap1(handler, "has", DerivedHasTrap, p)); | |
| 649 } | |
| 650 var desc = GetProperty(obj, p); | |
| 651 return IS_UNDEFINED(desc) ? false : true; | |
| 652 } | |
| 653 | |
| 654 | |
| 655 // ES5 section 8.12.1. | 641 // ES5 section 8.12.1. |
| 656 function GetOwnProperty(obj, v) { | 642 function GetOwnProperty(obj, v) { |
| 657 var p = ToString(v); | 643 var p = ToString(v); |
| 658 if (%IsJSProxy(obj)) { | 644 if (%IsJSProxy(obj)) { |
| 659 var handler = %GetHandler(obj); | 645 var handler = %GetHandler(obj); |
| 660 var descriptor = CallTrap1(handler, "getOwnPropertyDescriptor", void 0, p); | 646 var descriptor = CallTrap1(handler, "getOwnPropertyDescriptor", void 0, p); |
| 661 if (IS_UNDEFINED(descriptor)) return descriptor; | 647 if (IS_UNDEFINED(descriptor)) return descriptor; |
| 662 var desc = ToCompletePropertyDescriptor(descriptor); | 648 var desc = ToCompletePropertyDescriptor(descriptor); |
| 663 if (!desc.isConfigurable()) { | 649 if (!desc.isConfigurable()) { |
| 664 throw MakeTypeError("proxy_prop_not_configurable", | 650 throw MakeTypeError("proxy_prop_not_configurable", |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1008 desc = descObj; | 994 desc = descObj; |
| 1009 */ | 995 */ |
| 1010 } else { | 996 } else { |
| 1011 var desc = ToPropertyDescriptor(attributes); | 997 var desc = ToPropertyDescriptor(attributes); |
| 1012 DefineOwnProperty(obj, name, desc, true); | 998 DefineOwnProperty(obj, name, desc, true); |
| 1013 } | 999 } |
| 1014 return obj; | 1000 return obj; |
| 1015 } | 1001 } |
| 1016 | 1002 |
| 1017 | 1003 |
| 1004 function GetOwnEnumerablePropertyNames(properties) { |
| 1005 var names = new InternalArray(); |
| 1006 for (var key in properties) { |
| 1007 if (%HasLocalProperty(properties, key)) { |
| 1008 names.push(key); |
| 1009 } |
| 1010 } |
| 1011 return names; |
| 1012 } |
| 1013 |
| 1014 |
| 1018 // ES5 section 15.2.3.7. | 1015 // ES5 section 15.2.3.7. |
| 1019 function ObjectDefineProperties(obj, properties) { | 1016 function ObjectDefineProperties(obj, properties) { |
| 1020 if (!IS_SPEC_OBJECT(obj)) | 1017 if (!IS_SPEC_OBJECT(obj)) |
| 1021 throw MakeTypeError("obj_ctor_property_non_object", ["defineProperties"]); | 1018 throw MakeTypeError("obj_ctor_property_non_object", ["defineProperties"]); |
| 1022 var props = ToObject(properties); | 1019 var props = ToObject(properties); |
| 1023 var key_values = []; | 1020 var names = GetOwnEnumerablePropertyNames(props); |
| 1024 for (var key in props) { | 1021 for (var i = 0; i < names.length; i++) { |
| 1025 if (%HasLocalProperty(props, key)) { | 1022 var name = names[i]; |
| 1026 key_values.push(key); | 1023 var desc = ToPropertyDescriptor(props[name]); |
| 1027 var value = props[key]; | 1024 DefineOwnProperty(obj, name, desc, true); |
| 1028 var desc = ToPropertyDescriptor(value); | |
| 1029 key_values.push(desc); | |
| 1030 } | |
| 1031 } | |
| 1032 for (var i = 0; i < key_values.length; i += 2) { | |
| 1033 var key = key_values[i]; | |
| 1034 var desc = key_values[i + 1]; | |
| 1035 DefineOwnProperty(obj, key, desc, true); | |
| 1036 } | 1025 } |
| 1037 return obj; | 1026 return obj; |
| 1038 } | 1027 } |
| 1039 | 1028 |
| 1040 | 1029 |
| 1041 // Harmony proxies. | 1030 // Harmony proxies. |
| 1042 function ProxyFix(obj) { | 1031 function ProxyFix(obj) { |
| 1043 var handler = %GetHandler(obj); | 1032 var handler = %GetHandler(obj); |
| 1044 var props = CallTrap0(handler, "fix", void 0); | 1033 var props = CallTrap0(handler, "fix", void 0); |
| 1045 if (IS_UNDEFINED(props)) { | 1034 if (IS_UNDEFINED(props)) { |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1534 // ---------------------------------------------------------------------------- | 1523 // ---------------------------------------------------------------------------- |
| 1535 | 1524 |
| 1536 function SetupFunction() { | 1525 function SetupFunction() { |
| 1537 InstallFunctions($Function.prototype, DONT_ENUM, $Array( | 1526 InstallFunctions($Function.prototype, DONT_ENUM, $Array( |
| 1538 "bind", FunctionBind, | 1527 "bind", FunctionBind, |
| 1539 "toString", FunctionToString | 1528 "toString", FunctionToString |
| 1540 )); | 1529 )); |
| 1541 } | 1530 } |
| 1542 | 1531 |
| 1543 SetupFunction(); | 1532 SetupFunction(); |
| OLD | NEW |