Skip to content

Commit 2df240e

Browse files
committed
In JavaScriptEngineSwitcher.ChakraCore fixed a errors that caused the crash of ReactJS.NET's benchmarks
1 parent 48c682a commit 2df240e

File tree

5 files changed

+115
-224
lines changed

5 files changed

+115
-224
lines changed

src/JavaScriptEngineSwitcher.ChakraCore/Helpers/EncodingHelpers.cs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,40 +22,48 @@ public static string UnicodeToAnsi(string value, out int byteCount)
2222
return value;
2323
}
2424

25+
string result;
2526
int valueLength = value.Length;
2627
Encoding utf8Encoding = Encoding.UTF8;
2728
Encoding ansiEncoding = Encoding.GetEncoding(0);
2829

2930
var byteArrayPool = ArrayPool<byte>.Shared;
3031
int bufferLength = utf8Encoding.GetByteCount(value);
3132
byte[] buffer = byteArrayPool.Rent(bufferLength + 1);
33+
buffer[bufferLength] = 0;
3234

33-
string result;
35+
try
36+
{
3437
#if NET471 || NETSTANDARD || NETCOREAPP2_1
35-
36-
unsafe
38+
result = ConvertStringInternal(utf8Encoding, ansiEncoding, value, valueLength, buffer, bufferLength);
39+
#else
40+
utf8Encoding.GetBytes(value, 0, valueLength, buffer, 0);
41+
result = ansiEncoding.GetString(buffer, 0, bufferLength);
42+
#endif
43+
}
44+
finally
3745
{
38-
fixed (char* pValue = value)
39-
fixed (byte* pBuffer = buffer)
40-
{
41-
utf8Encoding.GetBytes(pValue, valueLength, pBuffer, bufferLength);
42-
pBuffer[bufferLength] = 0;
43-
44-
result = ansiEncoding.GetString(pBuffer, bufferLength);
45-
}
46+
byteArrayPool.Return(buffer);
4647
}
4748

48-
#else
49-
utf8Encoding.GetBytes(value, 0, valueLength, buffer, 0);
50-
buffer[bufferLength] = 0;
49+
byteCount = bufferLength;
5150

52-
result = ansiEncoding.GetString(buffer, 0, bufferLength);
53-
#endif
54-
byteCount = ansiEncoding.GetByteCount(result);
51+
return result;
52+
}
53+
#if NET471 || NETSTANDARD || NETCOREAPP2_1
5554

56-
byteArrayPool.Return(buffer);
55+
private static unsafe string ConvertStringInternal(Encoding srcEncoding, Encoding dstEncoding, string s,
56+
int charCount, byte[] bytes, int byteCount)
57+
{
58+
fixed (char* pString = s)
59+
fixed (byte* pBytes = bytes)
60+
{
61+
srcEncoding.GetBytes(pString, charCount, pBytes, byteCount);
62+
string result = dstEncoding.GetString(pBytes, byteCount);
5763

58-
return result;
64+
return result;
65+
}
5966
}
67+
#endif
6068
}
6169
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Runtime.InteropServices;
2+
3+
namespace JavaScriptEngineSwitcher.ChakraCore.JsRt
4+
{
5+
/// <summary>
6+
/// Default callback for finalization of external buffer
7+
/// </summary>
8+
internal static class DefaultExternalBufferFinalizeCallback
9+
{
10+
/// <summary>
11+
/// Gets a instance of default callback for finalization of external buffer
12+
/// </summary>
13+
public static readonly JsObjectFinalizeCallback Instance = Marshal.FreeHGlobal;
14+
}
15+
}

src/JavaScriptEngineSwitcher.ChakraCore/JsRt/JsContext.cs

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Runtime.CompilerServices;
23
#if NET45 || NET471 || NETSTANDARD || NETCOREAPP2_1
34
using System.Runtime.InteropServices;
45
#endif
@@ -164,7 +165,8 @@ public static uint Idle()
164165
public static JsValue ParseScript(string script, JsSourceContext sourceContext, string sourceUrl,
165166
ref JsParseScriptAttributes parseAttributes)
166167
{
167-
JsExternalByteArrayBuffer scriptBuffer = CreateByteArrayBufferFromScriptCode(script, ref parseAttributes);
168+
JsValue scriptValue = CreateExternalArrayBufferFromScriptCode(script, ref parseAttributes);
169+
scriptValue.AddRef();
168170

169171
JsValue sourceUrlValue = JsValue.FromString(sourceUrl);
170172
sourceUrlValue.AddRef();
@@ -173,13 +175,13 @@ public static JsValue ParseScript(string script, JsSourceContext sourceContext,
173175

174176
try
175177
{
176-
JsErrorCode errorCode = NativeMethods.JsParse(scriptBuffer.Value, sourceContext, sourceUrlValue,
178+
JsErrorCode errorCode = NativeMethods.JsParse(scriptValue, sourceContext, sourceUrlValue,
177179
parseAttributes, out result);
178180
JsErrorHelpers.ThrowIfError(errorCode);
179181
}
180182
finally
181183
{
182-
scriptBuffer.Dispose();
184+
scriptValue.Release();
183185
sourceUrlValue.Release();
184186
}
185187

@@ -204,7 +206,8 @@ public static JsValue ParseScript(string script, JsSourceContext sourceContext,
204206
public static JsValue ParseSerializedScript(string script, byte[] buffer,
205207
JsSerializedLoadScriptCallback scriptLoadCallback, JsSourceContext sourceContext, string sourceUrl)
206208
{
207-
JsExternalByteArrayBuffer scriptBuffer = JsExternalByteArrayBuffer.FromBytes(buffer);
209+
JsValue bufferValue = JsValue.CreateExternalArrayBuffer(buffer);
210+
bufferValue.AddRef();
208211

209212
JsValue sourceUrlValue = JsValue.FromString(sourceUrl);
210213
sourceUrlValue.AddRef();
@@ -213,13 +216,13 @@ public static JsValue ParseSerializedScript(string script, byte[] buffer,
213216

214217
try
215218
{
216-
JsErrorCode errorCode = NativeMethods.JsParseSerialized(scriptBuffer.Value, scriptLoadCallback,
219+
JsErrorCode errorCode = NativeMethods.JsParseSerialized(bufferValue, scriptLoadCallback,
217220
sourceContext, sourceUrlValue, out result);
218221
JsErrorHelpers.ThrowIfError(errorCode);
219222
}
220223
finally
221224
{
222-
scriptBuffer.Dispose();
225+
bufferValue.Release();
223226
sourceUrlValue.Release();
224227
}
225228

@@ -241,7 +244,8 @@ public static JsValue ParseSerializedScript(string script, byte[] buffer,
241244
public static JsValue RunScript(string script, JsSourceContext sourceContext, string sourceUrl,
242245
ref JsParseScriptAttributes parseAttributes)
243246
{
244-
JsExternalByteArrayBuffer scriptBuffer = CreateByteArrayBufferFromScriptCode(script, ref parseAttributes);
247+
JsValue scriptValue = CreateExternalArrayBufferFromScriptCode(script, ref parseAttributes);
248+
scriptValue.AddRef();
245249

246250
JsValue sourceUrlValue = JsValue.FromString(sourceUrl);
247251
sourceUrlValue.AddRef();
@@ -250,13 +254,13 @@ public static JsValue RunScript(string script, JsSourceContext sourceContext, st
250254

251255
try
252256
{
253-
JsErrorCode errorCode = NativeMethods.JsRun(scriptBuffer.Value, sourceContext, sourceUrlValue,
257+
JsErrorCode errorCode = NativeMethods.JsRun(scriptValue, sourceContext, sourceUrlValue,
254258
parseAttributes, out result);
255259
JsErrorHelpers.ThrowIfError(errorCode);
256260
}
257261
finally
258262
{
259-
scriptBuffer.Dispose();
263+
scriptValue.Release();
260264
sourceUrlValue.Release();
261265
}
262266

@@ -281,7 +285,8 @@ public static JsValue RunScript(string script, JsSourceContext sourceContext, st
281285
public static JsValue RunSerializedScript(string script, byte[] buffer,
282286
JsSerializedLoadScriptCallback scriptLoadCallback, JsSourceContext sourceContext, string sourceUrl)
283287
{
284-
JsExternalByteArrayBuffer scriptBuffer = JsExternalByteArrayBuffer.FromBytes(buffer);
288+
JsValue bufferValue = JsValue.CreateExternalArrayBuffer(buffer);
289+
bufferValue.AddRef();
285290

286291
JsValue sourceUrlValue = JsValue.FromString(sourceUrl);
287292
sourceUrlValue.AddRef();
@@ -290,13 +295,13 @@ public static JsValue RunSerializedScript(string script, byte[] buffer,
290295

291296
try
292297
{
293-
JsErrorCode errorCode = NativeMethods.JsRunSerialized(scriptBuffer.Value, scriptLoadCallback,
298+
JsErrorCode errorCode = NativeMethods.JsRunSerialized(bufferValue, scriptLoadCallback,
294299
sourceContext, sourceUrlValue, out result);
295300
JsErrorHelpers.ThrowIfError(errorCode);
296301
}
297302
finally
298303
{
299-
scriptBuffer.Dispose();
304+
bufferValue.Release();
300305
sourceUrlValue.Release();
301306
}
302307

@@ -321,17 +326,19 @@ public static JsValue RunSerializedScript(string script, byte[] buffer,
321326
/// <returns>The buffer to put the serialized script into</returns>
322327
public static byte[] SerializeScript(string script, ref JsParseScriptAttributes parseAttributes)
323328
{
324-
JsExternalByteArrayBuffer scriptBuffer = CreateByteArrayBufferFromScriptCode(script, ref parseAttributes);
329+
JsValue scriptValue = CreateExternalArrayBufferFromScriptCode(script, ref parseAttributes);
330+
scriptValue.AddRef();
331+
325332
JsValue bufferValue;
326333

327334
try
328335
{
329-
JsErrorCode errorCode = NativeMethods.JsSerialize(scriptBuffer.Value, out bufferValue, parseAttributes);
336+
JsErrorCode errorCode = NativeMethods.JsSerialize(scriptValue, out bufferValue, parseAttributes);
330337
JsErrorHelpers.ThrowIfError(errorCode);
331338
}
332339
finally
333340
{
334-
scriptBuffer.Dispose();
341+
scriptValue.Release();
335342
}
336343

337344
byte[] buffer = bufferValue.ArrayBufferBytes;
@@ -340,12 +347,13 @@ public static byte[] SerializeScript(string script, ref JsParseScriptAttributes
340347
}
341348

342349
/// <summary>
343-
/// Creates a wrapper for the Javascript ArrayBuffer from script code
350+
/// Creates a Javascript <c>ArrayBuffer</c> object from script code
344351
/// </summary>
345352
/// <param name="script">Script code</param>
346353
/// <param name="parseAttributes">Attribute mask for parsing the script</param>
347-
/// <returns>Instance of wrapper for the Javascript ArrayBuffer</returns>
348-
private static JsExternalByteArrayBuffer CreateByteArrayBufferFromScriptCode(string script,
354+
/// <returns>The new <c>ArrayBuffer</c> object</returns>
355+
[MethodImpl((MethodImplOptions)256 /* AggressiveInlining */)]
356+
private static JsValue CreateExternalArrayBufferFromScriptCode(string script,
349357
ref JsParseScriptAttributes parseAttributes)
350358
{
351359
Encoding encoding;
@@ -360,9 +368,9 @@ private static JsExternalByteArrayBuffer CreateByteArrayBufferFromScriptCode(str
360368
encoding = Encoding.UTF8;
361369
}
362370

363-
JsExternalByteArrayBuffer scriptBuffer = JsExternalByteArrayBuffer.FromString(script, encoding);
371+
JsValue scriptValue = JsValue.CreateExternalArrayBuffer(script, encoding);
364372

365-
return scriptBuffer;
373+
return scriptValue;
366374
}
367375

368376
/// <summary>

0 commit comments

Comments
 (0)