Skip to content

Commit

Permalink
Make StringMap thread safe
Browse files Browse the repository at this point in the history
  • Loading branch information
nilproject committed Mar 23, 2023
1 parent 5b8789f commit 946dd94
Show file tree
Hide file tree
Showing 4 changed files with 237 additions and 142 deletions.
25 changes: 12 additions & 13 deletions NiL.JS/Core/Functions/MethodProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using NiL.JS.Backward;
using NiL.JS.BaseLibrary;
using NiL.JS.Core.Interop;

Expand All @@ -28,8 +25,8 @@ internal sealed class MethodProxy : Function
{
private delegate object RestPrmsConverter(Context initiator, Expressions.Expression[] arguments, Arguments argumentsObject);

private static readonly Dictionary<MethodBase, WrapperDelegate> WrapperCache = new Dictionary<MethodBase, WrapperDelegate>();
private static readonly MethodInfo ArgumentsGetItemMethod = typeof(Arguments).GetMethod("get_Item", new[] { typeof(int) });
private static readonly Dictionary<MethodBase, WrapperDelegate> _wrapperCache = new Dictionary<MethodBase, WrapperDelegate>();
private static readonly MethodInfo _argumentsGetItemMethod = typeof(Arguments).GetMethod("get_Item", new[] { typeof(int) });

private readonly bool _forceInstance;
private readonly bool _strictConversion;
Expand Down Expand Up @@ -118,15 +115,17 @@ public MethodProxy(Context context, MethodBase methodBase, object hardTarget)
_restPrmsArrayCreator = makeRestPrmsArrayCreator();
}

if (!WrapperCache.TryGetValue(methodBase, out _fastWrapper))
WrapperCache[methodBase] = _fastWrapper = makeFastWrapper(methodInfo);
lock (_wrapperCache)
if (!_wrapperCache.TryGetValue(methodBase, out _fastWrapper))
_wrapperCache[methodBase] = _fastWrapper = makeFastWrapper(methodInfo);

RequireNewKeywordLevel = RequireNewKeywordLevel.WithoutNewOnly;
}
else if (methodBase is ConstructorInfo)
{
if (!WrapperCache.TryGetValue(methodBase, out _fastWrapper))
WrapperCache[methodBase] = _fastWrapper = makeFastWrapper(methodBase as ConstructorInfo);
lock (_wrapperCache)
if (!_wrapperCache.TryGetValue(methodBase, out _fastWrapper))
_wrapperCache[methodBase] = _fastWrapper = makeFastWrapper(methodBase as ConstructorInfo);

if (_parameters.Length > 0 && _parameters.Last().GetCustomAttribute(typeof(ParamArrayAttribute), false) != null)
{
Expand Down Expand Up @@ -166,7 +165,7 @@ private RestPrmsConverter makeRestPrmsArrayCreator()

var resultArrayCtor = resultArray.Type.GetConstructor(new[] { typeof(int) });

var convertedValueArgObj = Expression.Call(Expression.Constant(this), convertArg, argumentIndex, Expression.Call(argumentsObjectPrm, ArgumentsGetItemMethod, Expression.PostIncrementAssign(argumentIndex)));
var convertedValueArgObj = Expression.Call(Expression.Constant(this), convertArg, argumentIndex, Expression.Call(argumentsObjectPrm, _argumentsGetItemMethod, Expression.PostIncrementAssign(argumentIndex)));
var conditionArgObj = Expression.GreaterThanOrEqual(argumentIndex, Expression.PropertyOrField(argumentsObjectPrm, nameof(Arguments.Length)));
var arrayAssignArgObj = Expression.Assign(Expression.ArrayAccess(resultArray, Expression.PostIncrementAssign(resultArrayIndex)), Expression.Convert(convertedValueArgObj, restItemType));

Expand All @@ -191,7 +190,7 @@ private RestPrmsConverter makeRestPrmsArrayCreator()
Expression.Constant(_parameters.Length)),
Expression.Block(
Expression.Assign(tempValue,
Expression.Call(Expression.Constant(this), convertArg, argumentIndex, Expression.Call(argumentsObjectPrm, ArgumentsGetItemMethod, argumentIndex))),
Expression.Call(Expression.Constant(this), convertArg, argumentIndex, Expression.Call(argumentsObjectPrm, _argumentsGetItemMethod, argumentIndex))),
Expression.IfThen(Expression.NotEqual(tempValue, Expression.Constant(null)),
Expression.Return(returnLabel, tempValue)))),
Expression.Assign(resultArray,
Expand Down Expand Up @@ -335,7 +334,7 @@ private WrapperDelegate makeFastWrapper(MethodInfo methodInfo)
Expression.Constant(this),
convertArg,
Expression.Constant(i),
Expression.Call(argumentsObjectPrm, ArgumentsGetItemMethod, Expression.Constant(i))),
Expression.Call(argumentsObjectPrm, _argumentsGetItemMethod, Expression.Constant(i))),
_parameters[i].ParameterType);
}

Expand Down Expand Up @@ -424,7 +423,7 @@ private WrapperDelegate makeFastWrapper(ConstructorInfo constructorInfo)
Expression.Constant(this),
convertArg,
Expression.Constant(i),
Expression.Call(argumentsObject, ArgumentsGetItemMethod, Expression.Constant(i))),
Expression.Call(argumentsObject, _argumentsGetItemMethod, Expression.Constant(i))),
_parameters[i].ParameterType);
}

Expand Down
15 changes: 2 additions & 13 deletions NiL.JS/Core/Interop/Proxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -353,19 +353,8 @@ internal protected override JSValue GetProperty(JSValue key, bool forWrite, Prop
forWrite &= (_attributes & JSValueAttributesInternal.Immutable) == 0;

string name = key.ToString();
JSValue r = null;
if (_fields.TryGetValue(name, out r))
if (_fields.TryGetValue(name, out JSValue r) && r.Exists)
{
if (!r.Exists && !forWrite)
{
var t = base.GetProperty(key, false, memberScope);
if (t.Exists)
{
r.Assign(t);
r._valueType = t._valueType;
}
}

if (forWrite && r.NeedClone)
_fields[name] = r = r.CloneImpl(false);

Expand All @@ -391,7 +380,7 @@ internal protected override JSValue GetProperty(JSValue key, bool forWrite, Prop
{
if (forWrite)
{
if ((property._attributes & (JSValueAttributesInternal.SystemObject | JSValueAttributesInternal.ReadOnly))
if ((property._attributes & (JSValueAttributesInternal.SystemObject | JSValueAttributesInternal.ReadOnly))
== JSValueAttributesInternal.SystemObject)
{
if (protoInstanceAsJs != null)
Expand Down
Loading

0 comments on commit 946dd94

Please sign in to comment.