@@ -1725,102 +1725,137 @@ private static bool TryAssignArrayLikeValue(object? target, object? propertyKey,
17251725 return true ;
17261726 }
17271727
1728+ if ( propertyName is null )
1729+ {
1730+ return true ;
1731+ }
1732+
17281733 if ( string . Equals ( propertyName , "length" , StringComparison . Ordinal ) )
17291734 {
17301735 jsArray . SetLength ( value , context ) ;
17311736 return true ;
17321737 }
17331738
1734- if ( TryResolveArrayIndex ( propertyKey , out var index , context ) )
1739+ var isArrayIndex = TryResolveArrayIndex ( propertyKey , out var index , context ) ;
1740+ var ownDescriptor = jsArray . GetOwnPropertyDescriptor ( propertyName ) ;
1741+
1742+ if ( isArrayIndex )
17351743 {
1736- if ( propertyName is not null && TryHandleArrayIndexedAssignment ( jsArray , propertyName , value , context ) )
1744+ if ( ownDescriptor is not null )
17371745 {
1738- return true ;
1739- }
1746+ if ( ownDescriptor . IsAccessorDescriptor )
1747+ {
1748+ if ( ownDescriptor . Set is null )
1749+ {
1750+ if ( context ? . CurrentScope . IsStrict == true )
1751+ {
1752+ throw StandardLibrary . ThrowTypeError (
1753+ $ "Cannot set property '{ propertyName } ' that has only a getter.",
1754+ context ,
1755+ context . RealmState ) ;
1756+ }
1757+
1758+ return true ;
1759+ }
17401760
1741- jsArray . SetElement ( index , value ) ;
1742- return true ;
1743- }
1744- }
1761+ TypedAstEvaluator . InvokeCallable ( ownDescriptor . Set , [ value ] , jsArray , context ) ;
1762+ return true ;
1763+ }
17451764
1746- if ( target is TypedArrayBase typedArray && TryResolveArrayIndex ( propertyKey , out var typedIndex , context ) )
1747- {
1748- typedArray . SetValue ( typedIndex , value ) ;
1749- return true ;
1750- }
1765+ if ( ! ownDescriptor . Writable )
1766+ {
1767+ if ( context ? . CurrentScope . IsStrict == true )
1768+ {
1769+ throw StandardLibrary . ThrowTypeError (
1770+ $ "Cannot assign to read only property '{ propertyName } '.",
1771+ context ,
1772+ context . RealmState ) ;
1773+ }
17511774
1752- return false ;
1753- }
1775+ return true ;
1776+ }
17541777
1755- private static bool TryHandleArrayIndexedAssignment (
1756- JsArray array ,
1757- string propertyName ,
1758- object ? value ,
1759- EvaluationContext ? context )
1760- {
1761- var descriptor = FindPropertyDescriptorInChain ( array , propertyName ) ;
1762- if ( descriptor is null )
1763- {
1764- return false ;
1765- }
1778+ jsArray . SetElement ( index , value ) ;
1779+ return true ;
1780+ }
17661781
1767- if ( descriptor . IsAccessorDescriptor )
1768- {
1769- if ( descriptor . Set is null )
1770- {
1771- if ( context ? . CurrentScope . IsStrict == true )
1782+ IJsPropertyAccessor ? current = jsArray . PrototypeAccessor ?? jsArray . Prototype ;
1783+ while ( current is not null )
17721784 {
1773- throw StandardLibrary . ThrowTypeError (
1774- $ "Cannot set property '{ propertyName } ' that has only a getter.",
1775- context ,
1776- context . RealmState ) ;
1785+ var inheritedDescriptor = current . GetOwnPropertyDescriptor ( propertyName ) ;
1786+ if ( inheritedDescriptor is not null )
1787+ {
1788+ if ( inheritedDescriptor . IsAccessorDescriptor )
1789+ {
1790+ if ( inheritedDescriptor . Set is null )
1791+ {
1792+ if ( context ? . CurrentScope . IsStrict == true )
1793+ {
1794+ throw StandardLibrary . ThrowTypeError (
1795+ $ "Cannot set property '{ propertyName } ' that has only a getter.",
1796+ context ,
1797+ context . RealmState ) ;
1798+ }
1799+
1800+ return true ;
1801+ }
1802+
1803+ TypedAstEvaluator . InvokeCallable ( inheritedDescriptor . Set , [ value ] , jsArray , context ) ;
1804+ return true ;
1805+ }
1806+
1807+ if ( ! inheritedDescriptor . Writable )
1808+ {
1809+ if ( context ? . CurrentScope . IsStrict == true )
1810+ {
1811+ throw StandardLibrary . ThrowTypeError (
1812+ $ "Cannot assign to read only property '{ propertyName } '.",
1813+ context ,
1814+ context . RealmState ) ;
1815+ }
1816+
1817+ return true ;
1818+ }
1819+
1820+ jsArray . DefineProperty ( propertyName , new PropertyDescriptor
1821+ {
1822+ Value = value ,
1823+ Writable = true ,
1824+ Enumerable = inheritedDescriptor . Enumerable ,
1825+ Configurable = inheritedDescriptor . Configurable ,
1826+ HasValue = true ,
1827+ HasWritable = true ,
1828+ HasEnumerable = inheritedDescriptor . HasEnumerable ,
1829+ HasConfigurable = inheritedDescriptor . HasConfigurable
1830+ } ) ;
1831+ return true ;
1832+ }
1833+
1834+ current = current switch
1835+ {
1836+ IJsObjectLike objectLike => objectLike . Prototype ,
1837+ IPrototypeAccessorProvider provider => provider . PrototypeAccessor ,
1838+ _ => null
1839+ } ;
17771840 }
17781841
1842+ jsArray . SetElement ( index , value ) ;
17791843 return true ;
17801844 }
17811845
1782- descriptor . Set . Invoke ( [ value ] , array ) ;
1846+ jsArray . SetProperty ( propertyName , value , jsArray ) ;
17831847 return true ;
17841848 }
17851849
1786- if ( ! descriptor . Writable )
1850+ if ( target is TypedArrayBase typedArray && TryResolveArrayIndex ( propertyKey , out var typedIndex , context ) )
17871851 {
1788- if ( context ? . CurrentScope . IsStrict == true )
1789- {
1790- throw StandardLibrary . ThrowTypeError (
1791- $ "Cannot assign to read only property '{ propertyName } '.",
1792- context ,
1793- context . RealmState ) ;
1794- }
1795-
1852+ typedArray . SetValue ( typedIndex , value ) ;
17961853 return true ;
17971854 }
17981855
17991856 return false ;
18001857 }
18011858
1802- private static PropertyDescriptor ? FindPropertyDescriptorInChain ( IJsPropertyAccessor start , string propertyName )
1803- {
1804- IJsPropertyAccessor ? current = start ;
1805- while ( current is not null )
1806- {
1807- var descriptor = current . GetOwnPropertyDescriptor ( propertyName ) ;
1808- if ( descriptor is not null )
1809- {
1810- return descriptor ;
1811- }
1812-
1813- current = current switch
1814- {
1815- IJsObjectLike objectLike => objectLike . Prototype ,
1816- IPrototypeAccessorProvider provider => provider . PrototypeAccessor ,
1817- _ => null
1818- } ;
1819- }
1820-
1821- return null ;
1822- }
1823-
18241859 public static bool DeletePropertyValue ( object ? target , object ? propertyKey , EvaluationContext ? context = null )
18251860 {
18261861 if ( target is null || ReferenceEquals ( target , Symbol . Undefined ) )
0 commit comments