Changeset 215272 in webkit for trunk/Source/JavaScriptCore
- Timestamp:
- Apr 12, 2017, 10:35:31 AM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r215270 r215272 1 2017-04-12 Michael Saboff <[email protected]> 2 3 Implement Object.isFrozen() and Object.isSealed() per ECMA spec 4 https://bugs.webkit.org/show_bug.cgi?id=170753 5 6 Reviewed by Mark Lam. 7 8 * runtime/ObjectConstructor.cpp: 9 (JSC::testIntegrityLevel): Added local helper as described in the ECMA standard. 10 11 (JSC::objectConstructorSeal): 12 (JSC::objectConstructorFreeze): 13 Eliminated incomplete special handling of JSFinalObjects. 14 15 (JSC::objectConstructorIsSealed): 16 (JSC::objectConstructorIsFrozen): 17 Refactored to use the new testIntegrityLevel() helper. 18 1 19 2017-04-12 Yusuke Suzuki <[email protected]> 2 20 -
trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
r215234 r215272 547 547 return true; 548 548 } 549 549 550 template<IntegrityLevel level> 551 bool testIntegrityLevel(ExecState* exec, VM& vm, JSObject* object) 552 { 553 auto scope = DECLARE_THROW_SCOPE(vm); 554 555 // 1. Assert: Type(O) is Object. 556 // 2. Assert: level is either "sealed" or "frozen". 557 558 // 3. Let status be ?IsExtensible(O). 559 bool status = object->isExtensible(exec); 560 RETURN_IF_EXCEPTION(scope, { }); 561 562 // 4. If status is true, return false. 563 if (status) 564 return false; 565 566 // 6. Let keys be ? O.[[OwnPropertyKeys]](). 567 PropertyNameArray keys(exec, PropertyNameMode::StringsAndSymbols); 568 object->methodTable(vm)->getOwnPropertyNames(object, exec, keys, EnumerationMode(DontEnumPropertiesMode::Include)); 569 RETURN_IF_EXCEPTION(scope, { }); 570 571 // 7. For each element k of keys, do 572 PropertyNameArray::const_iterator end = keys.end(); 573 for (PropertyNameArray::const_iterator iter = keys.begin(); iter != end; ++iter) { 574 Identifier propertyName = *iter; 575 if (vm.propertyNames->isPrivateName(propertyName)) 576 continue; 577 578 // a. Let currentDesc be ? O.[[GetOwnProperty]](k) 579 PropertyDescriptor desc; 580 bool didGetDescriptor = object->getOwnPropertyDescriptor(exec, propertyName, desc); 581 RETURN_IF_EXCEPTION(scope, { }); 582 583 // b. If currentDesc is not undefined, then 584 if (!didGetDescriptor) 585 continue; 586 587 // i. If currentDesc.[[Configurable]] is true, return false. 588 if (desc.configurable()) 589 return false; 590 591 // ii. If level is "frozen" and IsDataDescriptor(currentDesc) is true, then 592 // 1. If currentDesc.[[Writable]] is true, return false. 593 if (level == IntegrityLevel::Frozen && desc.isDataDescriptor() && desc.writable()) 594 return false; 595 } 596 597 return true; 598 } 599 550 600 EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState* exec) 551 601 { … … 559 609 JSObject* object = asObject(obj); 560 610 561 if (isJSFinalObject(object)) {562 object->seal(vm);563 return JSValue::encode(obj);564 }565 566 611 bool success = setIntegrityLevel<IntegrityLevel::Sealed>(exec, vm, object); 567 612 RETURN_IF_EXCEPTION(scope, encodedJSValue()); … … 578 623 VM& vm = exec->vm(); 579 624 auto scope = DECLARE_THROW_SCOPE(vm); 580 581 if (isJSFinalObject(object) && !hasIndexedProperties(object->indexingType())) {582 object->freeze(vm);583 return object;584 }585 625 586 626 bool success = setIntegrityLevel<IntegrityLevel::Frozen>(exec, vm, object); … … 618 658 { 619 659 VM& vm = exec->vm(); 620 auto scope = DECLARE_THROW_SCOPE(vm);621 660 622 661 // 1. If Type(O) is not Object, return true. … … 626 665 JSObject* object = asObject(obj); 627 666 628 if (isJSFinalObject(object)) 629 return JSValue::encode(jsBoolean(object->isSealed(vm))); 630 631 // 2. For each named own property name P of O, 632 PropertyNameArray properties(exec, PropertyNameMode::StringsAndSymbols); 633 object->methodTable(vm)->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include)); 634 RETURN_IF_EXCEPTION(scope, { }); 635 PropertyNameArray::const_iterator end = properties.end(); 636 for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) { 637 Identifier propertyName = *iter; 638 if (vm.propertyNames->isPrivateName(propertyName)) 639 continue; 640 // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P. 641 PropertyDescriptor desc; 642 bool didGetDescriptor = object->getOwnPropertyDescriptor(exec, propertyName, desc); 643 RETURN_IF_EXCEPTION(scope, { }); 644 if (!didGetDescriptor) 645 continue; 646 // b. If desc.[[Configurable]] is true, then return false. 647 if (desc.configurable()) 648 return JSValue::encode(jsBoolean(false)); 649 } 650 651 // 3. If the [[Extensible]] internal property of O is false, then return true. 652 // 4. Otherwise, return false. 653 bool isExtensible = object->isExtensible(exec); 654 RETURN_IF_EXCEPTION(scope, { }); 655 return JSValue::encode(jsBoolean(!isExtensible)); 667 // 2. Return ? TestIntegrityLevel(O, "sealed"). 668 return JSValue::encode(jsBoolean(testIntegrityLevel<IntegrityLevel::Sealed>(exec, vm, object))); 656 669 } 657 670 … … 659 672 { 660 673 VM& vm = exec->vm(); 661 auto scope = DECLARE_THROW_SCOPE(vm);662 674 663 675 // 1. If Type(O) is not Object, return true. … … 667 679 JSObject* object = asObject(obj); 668 680 669 if (isJSFinalObject(object)) 670 return JSValue::encode(jsBoolean(object->isFrozen(vm))); 671 672 // 2. For each named own property name P of O, 673 PropertyNameArray properties(exec, PropertyNameMode::StringsAndSymbols); 674 object->methodTable(vm)->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include)); 675 RETURN_IF_EXCEPTION(scope, { }); 676 PropertyNameArray::const_iterator end = properties.end(); 677 for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) { 678 Identifier propertyName = *iter; 679 if (vm.propertyNames->isPrivateName(propertyName)) 680 continue; 681 // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P. 682 PropertyDescriptor desc; 683 bool didGetDescriptor = object->getOwnPropertyDescriptor(exec, propertyName, desc); 684 RETURN_IF_EXCEPTION(scope, { }); 685 if (!didGetDescriptor) 686 continue; 687 // b. If IsDataDescriptor(desc) is true then 688 // i. If desc.[[Writable]] is true, return false. c. If desc.[[Configurable]] is true, then return false. 689 if ((desc.isDataDescriptor() && desc.writable()) || desc.configurable()) 690 return JSValue::encode(jsBoolean(false)); 691 } 692 693 // 3. If the [[Extensible]] internal property of O is false, then return true. 694 // 4. Otherwise, return false. 695 bool isExtensible = object->isExtensible(exec); 696 RETURN_IF_EXCEPTION(scope, { }); 697 return JSValue::encode(jsBoolean(!isExtensible)); 681 // 2. Return ? TestIntegrityLevel(O, "frozen"). 682 return JSValue::encode(jsBoolean(testIntegrityLevel<IntegrityLevel::Frozen>(exec, vm, object))); 698 683 } 699 684
Note:
See TracChangeset
for help on using the changeset viewer.