@@ -637,7 +637,7 @@ public static long toArrayIndexOrRangeError(Number len, Number len32, BranchProf
637637 @ TruffleBoundary
638638 public boolean defineOwnProperty (DynamicObject thisObj , Object key , PropertyDescriptor descriptor , boolean doThrow ) {
639639 if (key .equals (LENGTH )) {
640- return defineOwnPropertyLength (thisObj , key , descriptor , doThrow );
640+ return defineOwnPropertyLength (thisObj , descriptor , doThrow );
641641 } else if (key instanceof String && JSRuntime .isArrayIndex ((String ) key )) {
642642 return defineOwnPropertyIndex (thisObj , (String ) key , descriptor , doThrow );
643643 } else {
@@ -651,17 +651,18 @@ public boolean defineOwnProperty(DynamicObject thisObj, Object key, PropertyDesc
651651 *
652652 * @return whether the operation was successful
653653 */
654- private boolean defineOwnPropertyLength (DynamicObject thisObj , Object key , PropertyDescriptor descriptor , boolean doThrow ) {
654+ private boolean defineOwnPropertyLength (DynamicObject thisObj , PropertyDescriptor descriptor , boolean doThrow ) {
655655 if (!descriptor .hasValue ()) {
656- if (descriptor .hasWritable () && !descriptor .getWritable ()) {
656+ boolean success = DefinePropertyUtil .ordinaryDefineOwnProperty (thisObj , LENGTH , descriptor , doThrow );
657+ if (success && descriptor .hasWritable () && !descriptor .getWritable ()) {
657658 setLengthNotWritable (thisObj );
658659 }
659- return DefinePropertyUtil . ordinaryDefineOwnProperty ( thisObj , key , descriptor , doThrow ) ;
660+ return success ;
660661 }
661662
662- Number newLenNum = JSRuntime .toNumber (descriptor .getValue ());
663- long newLen = JSRuntime .toUInt32 ( newLenNum );
664- if (JSRuntime .doubleValue (newLenNum ) != newLen ) {
663+ long newLen = JSRuntime .toUInt32 (descriptor .getValue ());
664+ Number numberLen = JSRuntime .toNumber ( descriptor . getValue () );
665+ if (JSRuntime .doubleValue (numberLen ) != newLen ) {
665666 throw Errors .createRangeErrorInvalidArrayLength ();
666667 }
667668 PropertyDescriptor lenDesc = getOwnProperty (thisObj , LENGTH );
@@ -715,32 +716,26 @@ private boolean deleteElementsAfterShortening(DynamicObject thisObj, PropertyDes
715716
716717 private boolean definePropertyLength (DynamicObject thisObj , PropertyDescriptor descriptor , PropertyDescriptor currentDesc , long len , boolean doThrow ) {
717718 assert JSRuntime .isValidArrayLength (len );
719+ assert !currentDesc .getConfigurable ();
718720 boolean currentWritable = currentDesc .getWritable ();
719721 boolean currentEnumerable = currentDesc .getEnumerable ();
720- boolean currentConfigurable = currentDesc .getConfigurable ();
721722
722723 boolean newWritable = descriptor .getIfHasWritable (currentWritable );
723724 boolean newEnumerable = descriptor .getIfHasEnumerable (currentEnumerable );
724- boolean newConfigurable = descriptor .getIfHasConfigurable (currentConfigurable );
725+ boolean newConfigurable = descriptor .getIfHasConfigurable (false );
725726
726- if (currentConfigurable ) {
727- if (!currentWritable && !newWritable ) {
728- return DefinePropertyUtil .reject (doThrow , LENGTH_PROPERTY_NOT_WRITABLE );
729- }
730- } else {
731- if (descriptor .getConfigurable () || (newEnumerable != currentEnumerable )) {
732- // ES2020 9.1.6.3, 4.a and 4.b
733- return DefinePropertyUtil .reject (doThrow , CANNOT_REDEFINE_PROPERTY_LENGTH );
734- }
735- if (currentWritable == newWritable && currentEnumerable == newEnumerable ) {
736- if (!descriptor .hasValue () || len == getLength (thisObj )) {
737- return true ; // nothing changed
738- }
739- }
740- if (!currentWritable ) {
741- return DefinePropertyUtil .reject (doThrow , LENGTH_PROPERTY_NOT_WRITABLE );
727+ if (newConfigurable || (newEnumerable != currentEnumerable )) {
728+ // ES2020 9.1.6.3, 4.a and 4.b
729+ return DefinePropertyUtil .reject (doThrow , CANNOT_REDEFINE_PROPERTY_LENGTH );
730+ }
731+ if (currentWritable == newWritable && currentEnumerable == newEnumerable ) {
732+ if (!descriptor .hasValue () || len == getLength (thisObj )) {
733+ return true ; // nothing changed
742734 }
743735 }
736+ if (!currentWritable ) {
737+ return DefinePropertyUtil .reject (doThrow , LENGTH_PROPERTY_NOT_WRITABLE );
738+ }
744739
745740 try {
746741 setLength (thisObj , len , doThrow );
@@ -749,6 +744,10 @@ private boolean definePropertyLength(DynamicObject thisObj, PropertyDescriptor d
749744 JSObjectUtil .changeFlags (thisObj , LENGTH , newAttr );
750745 }
751746
747+ if (!newWritable ) {
748+ setLengthNotWritable (thisObj );
749+ }
750+
752751 return true ;
753752 }
754753
0 commit comments