Skip to content

Commit 14bfc8b

Browse files
committed
.
1 parent 0313647 commit 14bfc8b

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

src/Asynkron.JsEngine/Runtime/JsOps.cs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,6 +1733,11 @@ private static bool TryAssignArrayLikeValue(object? target, object? propertyKey,
17331733

17341734
if (TryResolveArrayIndex(propertyKey, out var index, context))
17351735
{
1736+
if (propertyName is not null && TryHandleArrayIndexedAssignment(jsArray, propertyName, value, context))
1737+
{
1738+
return true;
1739+
}
1740+
17361741
jsArray.SetElement(index, value);
17371742
return true;
17381743
}
@@ -1747,6 +1752,75 @@ private static bool TryAssignArrayLikeValue(object? target, object? propertyKey,
17471752
return false;
17481753
}
17491754

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+
}
1766+
1767+
if (descriptor.IsAccessorDescriptor)
1768+
{
1769+
if (descriptor.Set is null)
1770+
{
1771+
if (context?.CurrentScope.IsStrict == true)
1772+
{
1773+
throw StandardLibrary.ThrowTypeError(
1774+
$"Cannot set property '{propertyName}' that has only a getter.",
1775+
context,
1776+
context.RealmState);
1777+
}
1778+
1779+
return true;
1780+
}
1781+
1782+
descriptor.Set.Invoke([value], array);
1783+
return true;
1784+
}
1785+
1786+
if (!descriptor.Writable)
1787+
{
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+
1796+
return true;
1797+
}
1798+
1799+
return false;
1800+
}
1801+
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+
17501824
public static bool DeletePropertyValue(object? target, object? propertyKey, EvaluationContext? context = null)
17511825
{
17521826
if (target is null || ReferenceEquals(target, Symbol.Undefined))

0 commit comments

Comments
 (0)