Skip to content

Commit

Permalink
Added get,set,getPrototypeOf,setPrototypeOf of Reflect and Proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
ackava committed Jun 18, 2022
1 parent f641330 commit 4dbbc72
Show file tree
Hide file tree
Showing 14 changed files with 295 additions and 132 deletions.
32 changes: 32 additions & 0 deletions YantraJS.Core/Core/Array/Typed/TypedArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,38 @@ internal override bool SetValue(uint index, JSValue value, JSValue receiver, boo
return true;
}

public override JSValue GetOwnPropertyDescriptor(JSValue name)
{
var key = name.ToKey(false);
switch (key.Type)
{
case KeyType.String:
if (key.KeyString.Key == KeyStrings.length.Key)
{
var l = new JSObject();
l.FastAddValue(KeyStrings.value, new JSNumber(this.length), JSPropertyAttributes.ConfigurableValue);
l.FastAddValue(KeyStrings.writable, JSBoolean.False, JSPropertyAttributes.ConfigurableValue);
l.FastAddValue(KeyStrings.enumerable, JSBoolean.True, JSPropertyAttributes.ConfigurableValue);
return l;
}
break;
case KeyType.UInt:
if (key.Index < (uint)this.length)
{
var l = new JSObject();
var v = GetValue(key.Index, this, false);
l.FastAddValue(KeyStrings.value, v, JSPropertyAttributes.ConfigurableValue);
l.FastAddValue(KeyStrings.writable, JSBoolean.True, JSPropertyAttributes.ConfigurableValue);
l.FastAddValue(KeyStrings.enumerable, JSBoolean.True, JSPropertyAttributes.ConfigurableValue);
l.FastAddValue(KeyStrings.configurable, JSBoolean.False, JSPropertyAttributes.ConfigurableValue);
return l;

}
return JSUndefined.Value;
}
return base.GetOwnPropertyDescriptor(name);
}

//public override JSValue this[uint index]
//{
// get {
Expand Down
22 changes: 22 additions & 0 deletions YantraJS.Core/Core/JSValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,28 @@ protected JSValue(JSObject prototype)

internal abstract PropertyKey ToKey(bool create = true);

public virtual JSValue GetPrototypeOf()
{
return prototypeChain?.@object ?? JSNull.Value;
}

public virtual void SetPrototypeOf(JSValue target)
{
if (target == JSNull.Value)
{
BasePrototypeObject = null;
return;
}
if (!(target is JSObject proto))
throw JSContext.Current.NewTypeError($"Prototype must be an object or null");
BasePrototypeObject = proto;
}

public virtual JSValue GetOwnPropertyDescriptor(JSValue name)
{
throw new NotImplementedException();
}

public virtual JSValue GetOwnProperty(in KeyString name)
{
var pc = prototypeChain;
Expand Down
3 changes: 3 additions & 0 deletions YantraJS.Core/Core/KeyStrings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ public static class KeyStrings
public readonly static KeyString undefined;
public readonly static KeyString NaN;
public readonly static KeyString @null;
public readonly static KeyString getPrototypeOf;
public readonly static KeyString ownKeys;
public readonly static KeyString setPrototypeOf;

public readonly static KeyString @global;
public readonly static KeyString globalThis;
Expand Down
22 changes: 22 additions & 0 deletions YantraJS.Core/Core/Object/JSObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,28 @@ public ref PropertySequence GetOwnProperties(bool create = true)
return ref ownProperties;
}


public override JSValue GetOwnPropertyDescriptor(JSValue name)
{
var key = name.ToKey(false);
switch(key.Type)
{
case KeyType.String:
if(ownProperties.TryGetValue(key.KeyString.Key, out var p))
return p.ToJSValue();
return JSUndefined.Value;
case KeyType.UInt:
if (elements.TryGetValue(key.Index, out var p1))
return p1.ToJSValue();
return JSUndefined.Value;
case KeyType.Symbol:
if (symbols.TryGetValue(key.Symbol.Key, out var p3))
return p3.ToJSValue();
return JSUndefined.Value;
}
return JSUndefined.Value;
}

public override JSValue GetOwnProperty(in KeyString name)
{
ref var p = ref ownProperties.GetValue(name.Key);
Expand Down
59 changes: 25 additions & 34 deletions YantraJS.Core/Core/Object/JSObjectStatic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -276,12 +276,7 @@ internal static JSValue Seal(in Arguments a)
internal static JSValue SetPrototypeOf(in Arguments a)
{
var (first, second) = a.Get2();
if (!(first is JSObject @object))
return first;
if (!@object.IsExtensible())
throw JSContext.Current.NewTypeError("Object is not extensible");
if (second is JSObject proto)
first.BasePrototypeObject = proto;
first.SetPrototypeOf(second);
return first;
}

Expand Down Expand Up @@ -324,29 +319,29 @@ internal static JSValue GetOwnPropertyDescriptor(in Arguments a)
throw JSContext.Current.NewTypeError(JSTypeError.Cannot_convert_undefined_or_null_to_object);
if (!(first is JSObject jobj))
return JSUndefined.Value;
var key = name.ToKey(false);
JSProperty p;
if (key.IsUInt)
{
// check for typedArray..
if (first is TypedArray ta)
{
var v = ta[key.Index];
if (v.IsUndefined)
return JSUndefined.Value;

p = JSProperty.Property(v, JSPropertyAttributes.Enumerable | JSPropertyAttributes.Value);
}
else
{
p = jobj.GetInternalProperty(key.Index, false);
}
} else {
p = jobj.GetInternalProperty(key.KeyString, false);
}
if (!p.IsEmpty)
return p.ToJSValue();
return JSUndefined.Value;
//var key = name.ToKey(false);
//JSProperty p;
//if (key.IsUInt)
//{
// // check for typedArray..
// if (first is TypedArray ta)
// {
// var v = ta[key.Index];
// if (v.IsUndefined)
// return JSUndefined.Value;

// p = JSProperty.Property(v, JSPropertyAttributes.Enumerable | JSPropertyAttributes.Value);
// }
// else
// {
// p = jobj.GetInternalProperty(key.Index, false);
// }
//} else {
// p = jobj.GetInternalProperty(key.KeyString, false);
//}
//if (!p.IsEmpty)
// return p.ToJSValue();
return jobj.GetOwnPropertyDescriptor(name);
}

[Static("getOwnPropertyDescriptors")]
Expand Down Expand Up @@ -402,11 +397,7 @@ internal static JSValue GetOwnPropertySymbols(in Arguments a)
[Static("getPrototypeOf")]
internal static JSValue GetPrototypeOf(in Arguments a)
{
var target = a.Get1();
if (target is JSPrimitive primitive)
primitive.ResolvePrototype();
var p = target.prototypeChain?.@object ?? JSNull.Value;
return p;
return a.Get1().GetPrototypeOf();
}

}
Expand Down
6 changes: 6 additions & 0 deletions YantraJS.Core/Core/Primitive/JSPrimitive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,11 @@ internal override JSFunctionDelegate GetMethod(in KeyString key)
}
return prototypeChain?.GetMethod(key);
}

public override JSValue GetPrototypeOf()
{
ResolvePrototype();
return base.GetPrototypeOf();
}
}
}
32 changes: 32 additions & 0 deletions YantraJS.Core/Core/Proxy/JSProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,38 @@ internal override bool SetValue(uint name, JSValue value, JSValue receiver, bool
return target.SetValue(name, value, receiver, false);
}

public override JSValue GetPrototypeOf()
{
var fx = handler[KeyStrings.getPrototypeOf];
if (fx is JSFunction fxFunction)
{
return fxFunction.InvokeFunction(new Arguments(target));
}
return target.GetPrototypeOf();
}

public override void SetPrototypeOf(JSValue proto)
{
var fx = handler[KeyStrings.setPrototypeOf];
if (fx is JSFunction fxFunction)
{
fxFunction.InvokeFunction(new Arguments(this.target, proto));
return;
}
this.target.SetPrototypeOf(proto);
}

public override IElementEnumerator GetAllKeys(bool showEnumerableOnly = true, bool inherited = true)
{

var fx = handler[KeyStrings.ownKeys];
if (fx is JSFunction fxFunction)
{
return fxFunction.InvokeFunction(new Arguments(this.target)).GetElementEnumerator();
}
return target.GetAllKeys(showEnumerableOnly, inherited);
}

public override bool StrictEquals(JSValue value)
{
return target.StrictEquals(value);
Expand Down
19 changes: 4 additions & 15 deletions YantraJS.Core/Core/Reflect/JSReflect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,13 @@ public static JSValue GetOwnPropertyDescriptor(in Arguments a)
{
if (a[0] is not JSObject targetObject)
throw JSContext.Current.NewTypeError($"Object expected");
return targetObject.GetOwnProperty(a[1]);
return targetObject.GetOwnPropertyDescriptor(a[1]);
}

[Static("getPrototypeOf")]
public static JSValue GetPrototypeOf(in Arguments a)
{
if (a[0] is not JSObject targetObject)
throw JSContext.Current.NewTypeError($"Object expected");
return targetObject.prototypeChain?.@object ?? JSNull.Value;
return a.Get1().GetPrototypeOf();
}

[Static("has")]
Expand Down Expand Up @@ -134,17 +132,8 @@ public static JSValue Set(in Arguments a)
[Static("setPrototypeOf")]
public static JSValue SetPrototypeOf(in Arguments a)
{
if (a[0] is not JSObject targetObject)
throw JSContext.Current.NewTypeError($"Object expected");
var p = a[1];
if (p == JSNull.Value)
{
targetObject.BasePrototypeObject = null;
return JSBoolean.True;
}
if (p is not JSObject prototype )
throw JSContext.Current.NewTypeError($"Prototype must be an object or null");
targetObject.BasePrototypeObject = prototype;
var (target, proto) = a.Get2();
target.SetPrototypeOf(proto);
return JSBoolean.True;
}
}
Expand Down
13 changes: 11 additions & 2 deletions YantraJS.Core/LinqExpressions/GeneratorsV2/MethodRewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,17 @@ protected override Exp VisitCoalesceCall(YCoalesceCallExpression node)
{
var bb = new YBlockBuilder();
var target = bb.ConvertToVariable(Visit(node.Target));
var args = bb.ConvertToVariables(node.Arguments, this);
bb.AddExpression(YExpression.CoalesceCall(target, node.BooleanMember, node.Method, args));
var testArgs = bb.ConvertToVariables(node.TestArguments, this);
var trueArgs = bb.ConvertToVariables(node.TrueArguments, this);
var falseArgs = bb.ConvertToVariables(node.FalseArguments, this);
bb.AddExpression(YExpression.CoalesceCall(
target,
node.Test,
testArgs,
node.True,
trueArgs,
node.False,
falseArgs));
return bb.Build();
}
return base.VisitCoalesceCall(node);
Expand Down
Loading

0 comments on commit 4dbbc72

Please sign in to comment.