Skip to content

Commit

Permalink
Fix #280
Browse files Browse the repository at this point in the history
  • Loading branch information
nilproject committed Sep 2, 2022
1 parent ab0da30 commit 7ec6d71
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 19 deletions.
53 changes: 41 additions & 12 deletions NiL.JS/Core/Functions/ConstructorProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using NiL.JS.Backward;
using NiL.JS.BaseLibrary;
using NiL.JS.Core.Interop;
using NiL.JS.Expressions;

namespace NiL.JS.Core.Functions
{
Expand All @@ -30,6 +31,8 @@ internal class ConstructorProxy : Function
private const int passesCount = 3;

private static readonly object[] _emptyObjectArray = new object[0];
private static readonly Arguments _emptyArguments = new Arguments();

internal readonly StaticProxy _staticProxy;
private readonly MethodProxy[] _constructors;

Expand Down Expand Up @@ -156,17 +159,36 @@ protected internal override bool DeleteProperty(JSValue name)
return _staticProxy.DeleteProperty(name) && __proto__.DeleteProperty(name);
}

protected internal override JSValue Invoke(bool construct, JSValue targetObject, Arguments arguments)
internal override JSValue InternalInvoke(JSValue targetObject, Expression[] arguments, Context initiator, bool withSpread, bool construct)
{
var objc = targetObject as ObjectWrapper;
if (construct) // new
if (_functionDefinition._body == null)
return NotExists;

var argumentsObject = arguments.Length == 0 ? _emptyArguments : Tools.CreateArguments(arguments, initiator);

initiator._objectSource = null;

if (construct)
{
if (targetObject == null || targetObject._valueType < JSValueType.Object)
return Construct(argumentsObject);

return Construct(targetObject, argumentsObject);
}
else
return Call(targetObject, argumentsObject);
}

public override JSValue Construct(Arguments arguments)
{
return Invoke(true, null, arguments);
}

protected internal override JSValue Invoke(bool construct, JSValue targetObject, Arguments arguments)
{
if (!construct && _staticProxy._hostedType == typeof(Date))
{
if (_staticProxy._hostedType == typeof(Date))
return new Date().ToString();
return new Date().ToString();
}

object obj;
Expand Down Expand Up @@ -243,14 +265,14 @@ protected internal override JSValue Invoke(bool construct, JSValue targetObject,
}

JSValue res = obj as JSValue;

if (construct)
{
if (res != null)
{
// Для Number, Boolean и String
if (res._valueType < JSValueType.Object)
{
var objc = (targetObject as ObjectWrapper ?? ConstructObject()) as ObjectWrapper;
objc.instance = obj;
if (objc._objectPrototype == null)
objc._objectPrototype = res.__proto__;
Expand All @@ -267,9 +289,8 @@ protected internal override JSValue Invoke(bool construct, JSValue targetObject,
}
else
{
objc.instance = obj;
var objc = wrapObject(targetObject, obj);

objc._attributes |= _staticProxy._hostedType.GetTypeInfo().IsDefined(typeof(ImmutableAttribute), false) ? JSValueAttributesInternal.Immutable : JSValueAttributesInternal.None;
if (obj.GetType() == typeof(Date))
objc._valueType = JSValueType.Date;
else if (res != null)
Expand All @@ -286,15 +307,23 @@ protected internal override JSValue Invoke(bool construct, JSValue targetObject,
return res._oValue as JSValue;
}

res = res ?? new ObjectWrapper(obj)
if (res == null)
{
_attributes = JSValueAttributesInternal.SystemObject | (_staticProxy._hostedType.GetTypeInfo().IsDefined(typeof(ImmutableAttribute), false) ? JSValueAttributesInternal.Immutable : JSValueAttributesInternal.None)
};
res = wrapObject(targetObject, obj);
}
}

return res;
}

private ObjectWrapper wrapObject(JSValue targetObject, object obj)
{
var objc = (targetObject as ObjectWrapper ?? ConstructObject()) as ObjectWrapper;
objc.instance = obj;
objc._attributes |= _staticProxy._hostedType.GetTypeInfo().IsDefined(typeof(ImmutableAttribute), false) ? JSValueAttributesInternal.Immutable : JSValueAttributesInternal.None;
return objc;
}

protected internal override JSValue ConstructObject()
{
return new ObjectWrapper(null)
Expand Down Expand Up @@ -328,7 +357,7 @@ private MethodProxy findConstructor(Arguments arguments, out object[] args)
args = _constructors[i].ConvertArguments(
arguments,
(pass >= 1 ? 0 : ConvertArgsOptions.StrictConversion)
| (pass >= 2 ? ConvertArgsOptions.DummyValues : 0));
| (pass >= 2 ? ConvertArgsOptions.AllowDefaultValues : 0));

if (args == null)
continue;
Expand Down
2 changes: 1 addition & 1 deletion NiL.JS/Core/Functions/MethodGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ protected internal override JSValue Invoke(bool construct, JSValue targetObject,
args = _methods[i].ConvertArguments(
arguments,
(pass >= 1 ? ConvertArgsOptions.Default : ConvertArgsOptions.StrictConversion)
| (pass >= 2 ? ConvertArgsOptions.DummyValues : ConvertArgsOptions.Default));
| (pass >= 2 ? ConvertArgsOptions.AllowDefaultValues : ConvertArgsOptions.Default));

if (args == null)
continue;
Expand Down
23 changes: 17 additions & 6 deletions NiL.JS/Core/Functions/MethodProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ internal enum ConvertArgsOptions
Default = 0,
ThrowOnError = 1,
StrictConversion = 2,
DummyValues = 4
AllowDefaultValues = 4
}

internal delegate object WrapperDelegate(object target, Context initiator, Expressions.Expression[] arguments, Arguments argumentsObject);
Expand Down Expand Up @@ -253,7 +253,7 @@ private WrapperDelegate makeFastWrapper(MethodInfo methodInfo)
}
else
{
if ((_parameters.Length == 1 || (_parameters.Length == 2 && _forceInstance))
if ((_parameters.Length == 1 || (_parameters.Length == 2 && _forceInstance))
&& _parameters[_parameters.Length - 1].ParameterType == typeof(Arguments))
{
var argumentsObject = Expression.Condition(
Expand Down Expand Up @@ -477,6 +477,13 @@ internal override JSValue InternalInvoke(JSValue targetValue, Expressions.Expres
}

object value = invokeMethod(targetValue, argumentsSource, null, initiator);

if (value is not null
&& targetValue is not null
&& (value is not JSValue jsval || jsval._valueType == targetValue._valueType)
&& value == targetValue.Value)
return targetValue;

return Context.GlobalContext.ProxyValue(value);
}

Expand Down Expand Up @@ -573,7 +580,7 @@ private object processArgument(Expressions.Expression[] arguments, Context initi
#endif
private object convertArgument(int index, JSValue value)
{
var cvtArgs = ConvertArgsOptions.ThrowOnError;
var cvtArgs = ConvertArgsOptions.ThrowOnError | ConvertArgsOptions.AllowDefaultValues;
if (_strictConversion)
cvtArgs |= ConvertArgsOptions.StrictConversion;

Expand Down Expand Up @@ -603,10 +610,10 @@ private object convertArgument(int index, JSValue value, ConvertArgsOptions opti
result = Tools.ConvertJStoObj(value, parameterType, !strictConversion);
if (strictConversion && result == null)
{
if (options.HasFlag(ConvertArgsOptions.ThrowOnError))
if ((options & ConvertArgsOptions.ThrowOnError) != 0)
ExceptionHelper.ThrowTypeError("Unable to convert " + value + " to type " + parameterType);

if (!options.HasFlag(ConvertArgsOptions.DummyValues))
if ((options & ConvertArgsOptions.AllowDefaultValues) == 0)
return null;
}
}
Expand All @@ -616,7 +623,11 @@ private object convertArgument(int index, JSValue value, ConvertArgsOptions opti
return value;
}

if (result == null && _restPrmsArrayCreator == null && (options.HasFlag(ConvertArgsOptions.DummyValues) || parameterInfo.Attributes.HasFlag(ParameterAttributes.HasDefault)))
if (result == null
&& _restPrmsArrayCreator == null
&& (options & ConvertArgsOptions.AllowDefaultValues) != 0
&& ((parameterInfo.Attributes & ParameterAttributes.HasDefault) != 0
|| parameterInfo.ParameterType.IsValueType))
{
result = parameterInfo.DefaultValue;

Expand Down

0 comments on commit 7ec6d71

Please sign in to comment.