Skip to content

Commit 3a69a4d

Browse files
committed
Another attempt to prevent occurrence of the access violation exception in the CallFunction method
1 parent 47f20e7 commit 3a69a4d

File tree

2 files changed

+136
-10
lines changed

2 files changed

+136
-10
lines changed

src/MsieJavaScriptEngine/JsRt/Edge/ChakraEdgeJsRtJsEngine.cs

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ private EdgeJsValue MapToScriptType(object value)
172172
switch (typeCode)
173173
{
174174
case TypeCode.Boolean:
175-
return EdgeJsValue.FromBoolean((bool)value);
175+
return (bool)value ? EdgeJsValue.True : EdgeJsValue.False;
176176

177177
case TypeCode.SByte:
178178
case TypeCode.Byte:
@@ -282,6 +282,50 @@ private object[] MapToHostType(EdgeJsValue[] args)
282282
{
283283
return args.Select(MapToHostType).ToArray();
284284
}
285+
286+
/// <summary>
287+
/// Adds a reference to the value
288+
/// </summary>
289+
/// <param name="value">The value</param>
290+
private static void AddReferenceToValue(EdgeJsValue value)
291+
{
292+
if (CanHaveReferences(value))
293+
{
294+
value.AddRef();
295+
}
296+
}
297+
298+
/// <summary>
299+
/// Removes a reference to the value
300+
/// </summary>
301+
/// <param name="value">The value</param>
302+
private static void RemoveReferenceToValue(EdgeJsValue value)
303+
{
304+
if (CanHaveReferences(value))
305+
{
306+
value.Release();
307+
}
308+
}
309+
310+
/// <summary>
311+
/// Checks whether the value can have references
312+
/// </summary>
313+
/// <param name="value">The value</param>
314+
/// <returns>Result of check (true - may have; false - may not have)</returns>
315+
private static bool CanHaveReferences(EdgeJsValue value)
316+
{
317+
JsValueType valueType = value.ValueType;
318+
319+
switch (valueType)
320+
{
321+
case JsValueType.Null:
322+
case JsValueType.Undefined:
323+
case JsValueType.Boolean:
324+
return false;
325+
default:
326+
return true;
327+
}
328+
}
285329
#if NETSTANDARD1_3
286330

287331
private EdgeJsValue FromObject(object value)
@@ -945,11 +989,30 @@ public override object CallFunction(string functionName, params object[] args)
945989
string.Format(CommonStrings.Runtime_FunctionNotExist, functionName));
946990
}
947991

948-
var processedArgs = MapToScriptType(args);
949-
var allProcessedArgs = new[] { globalObj }.Concat(processedArgs).ToArray();
950-
992+
EdgeJsValue resultValue;
951993
EdgeJsValue functionValue = globalObj.GetProperty(functionId);
952-
EdgeJsValue resultValue = functionValue.CallFunction(allProcessedArgs);
994+
995+
if (args.Length > 0)
996+
{
997+
EdgeJsValue[] processedArgs = MapToScriptType(args);
998+
999+
foreach (EdgeJsValue processedArg in processedArgs)
1000+
{
1001+
AddReferenceToValue(processedArg);
1002+
}
1003+
1004+
EdgeJsValue[] allProcessedArgs = new[] { globalObj }.Concat(processedArgs).ToArray();
1005+
resultValue = functionValue.CallFunction(allProcessedArgs);
1006+
1007+
foreach (EdgeJsValue processedArg in processedArgs)
1008+
{
1009+
RemoveReferenceToValue(processedArg);
1010+
}
1011+
}
1012+
else
1013+
{
1014+
resultValue = functionValue.CallFunction(globalObj);
1015+
}
9531016

9541017
return MapToHostType(resultValue);
9551018
});

src/MsieJavaScriptEngine/JsRt/Ie/ChakraIeJsRtJsEngine.cs

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ private IeJsValue MapToScriptType(object value)
196196
switch (typeCode)
197197
{
198198
case TypeCode.Boolean:
199-
return IeJsValue.FromBoolean((bool)value);
199+
return (bool)value ? IeJsValue.True : IeJsValue.False;
200200

201201
case TypeCode.SByte:
202202
case TypeCode.Byte:
@@ -306,6 +306,50 @@ private object[] MapToHostType(IeJsValue[] args)
306306
{
307307
return args.Select(MapToHostType).ToArray();
308308
}
309+
310+
/// <summary>
311+
/// Adds a reference to the value
312+
/// </summary>
313+
/// <param name="value">The value</param>
314+
private static void AddReferenceToValue(IeJsValue value)
315+
{
316+
if (CanHaveReferences(value))
317+
{
318+
value.AddRef();
319+
}
320+
}
321+
322+
/// <summary>
323+
/// Removes a reference to the value
324+
/// </summary>
325+
/// <param name="value">The value</param>
326+
private static void RemoveReferenceToValue(IeJsValue value)
327+
{
328+
if (CanHaveReferences(value))
329+
{
330+
value.Release();
331+
}
332+
}
333+
334+
/// <summary>
335+
/// Checks whether the value can have references
336+
/// </summary>
337+
/// <param name="value">The value</param>
338+
/// <returns>Result of check (true - may have; false - may not have)</returns>
339+
private static bool CanHaveReferences(IeJsValue value)
340+
{
341+
JsValueType valueType = value.ValueType;
342+
343+
switch (valueType)
344+
{
345+
case JsValueType.Null:
346+
case JsValueType.Undefined:
347+
case JsValueType.Boolean:
348+
return false;
349+
default:
350+
return true;
351+
}
352+
}
309353
#if NETSTANDARD1_3
310354

311355
private IeJsValue FromObject(object value)
@@ -983,11 +1027,30 @@ public override object CallFunction(string functionName, params object[] args)
9831027
string.Format(CommonStrings.Runtime_FunctionNotExist, functionName));
9841028
}
9851029

986-
var processedArgs = MapToScriptType(args);
987-
var allProcessedArgs = new[] { globalObj }.Concat(processedArgs).ToArray();
988-
1030+
IeJsValue resultValue;
9891031
IeJsValue functionValue = globalObj.GetProperty(functionId);
990-
IeJsValue resultValue = functionValue.CallFunction(allProcessedArgs);
1032+
1033+
if (args.Length > 0)
1034+
{
1035+
IeJsValue[] processedArgs = MapToScriptType(args);
1036+
1037+
foreach (IeJsValue processedArg in processedArgs)
1038+
{
1039+
AddReferenceToValue(processedArg);
1040+
}
1041+
1042+
IeJsValue[] allProcessedArgs = new[] { globalObj }.Concat(processedArgs).ToArray();
1043+
resultValue = functionValue.CallFunction(allProcessedArgs);
1044+
1045+
foreach (IeJsValue processedArg in processedArgs)
1046+
{
1047+
RemoveReferenceToValue(processedArg);
1048+
}
1049+
}
1050+
else
1051+
{
1052+
resultValue = functionValue.CallFunction(globalObj);
1053+
}
9911054

9921055
return MapToHostType(resultValue);
9931056
});

0 commit comments

Comments
 (0)