Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions ClearScript/Util/MiscHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,11 @@ public static UIntPtr GetDigest(this string code)
return (UIntPtr.Size == 4) ? (UIntPtr)code.GetDigestAsUInt32() : (UIntPtr)code.GetDigestAsUInt64();
}

public static UIntPtr GetDigestFromUtf8(IntPtr pCode, int codeLength)
{
return (UIntPtr.Size == 4) ? (UIntPtr)GetDigestFromUtf8AsUInt32(pCode, codeLength) : (UIntPtr)GetDigestFromUtf8AsUInt64(pCode, codeLength);
}

public static uint GetDigestAsUInt32(this string code)
{
var digest = 2166136261U;
Expand Down Expand Up @@ -269,6 +274,72 @@ public static ulong GetDigestAsUInt64(this string code)
digest *= prime;
}

return digest;
}

public static uint GetDigestFromUtf8AsUInt32(IntPtr pCode, int codeLength)
{
uint digest = 2166136261U;
const uint prime = 16777619U;
const int bufferSize = 128;

Decoder decoder = Encoding.Unicode.GetDecoder();

unsafe
{
byte* utf8bytes = (byte*)pCode;
char* chars = stackalloc char[bufferSize];

while (codeLength > 0)
{
decoder.Convert(utf8bytes, codeLength, chars, bufferSize, false, out int bytesUsed, out int charsUsed, out bool completed);
utf8bytes += bytesUsed;
codeLength -= bytesUsed;

byte* utf16bytes = (byte*)chars;
int utf16byteCount = charsUsed * sizeof(char);

for (var index = 0; index < utf16byteCount; index++)
{
digest ^= utf16bytes[index];
digest *= prime;
}
}
}

return digest;
}

public static ulong GetDigestFromUtf8AsUInt64(IntPtr pCode, int codeLength)
{
ulong digest = 14695981039346656037UL;
const ulong prime = 1099511628211UL;
const int bufferSize = 128;

Decoder decoder = Encoding.Unicode.GetDecoder();

unsafe
{
byte* utf8bytes = (byte*)pCode;
char* chars = stackalloc char[bufferSize];

while (codeLength > 0)
{
decoder.Convert(utf8bytes, codeLength, chars, bufferSize, false, out int bytesUsed, out int charsUsed, out bool completed);
utf8bytes += bytesUsed;
codeLength -= bytesUsed;

byte* utf16bytes = (byte*)chars;
int utf16byteCount = charsUsed * sizeof(char);

for (var index = 0; index < utf16byteCount; index++)
{
digest ^= utf16bytes[index];
digest *= prime;
}
}
}

return digest;
}

Expand Down
2 changes: 2 additions & 0 deletions ClearScript/V8/SplitProxy/IV8SplitProxyNative.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ internal interface IV8SplitProxyNative
void V8Context_AwaitDebuggerAndPause(V8Context.Handle hContext);
void V8Context_CancelAwaitDebugger(V8Context.Handle hContext);
object V8Context_ExecuteCode(V8Context.Handle hContext, string resourceName, string sourceMapUrl, ulong uniqueId, DocumentKind documentKind, IntPtr pDocumentInfo, string code, bool evaluate);
object V8Context_ExecuteScriptFromUtf8(V8Context.Handle hContext, string resourceName, string sourceMapUrl, ulong uniqueId, DocumentKind documentKind, IntPtr pDocumentInfo, IntPtr pCode, int codeLength, UIntPtr codeDigest, bool evaluate);
V8Script.Handle V8Context_Compile(V8Context.Handle hContext, string resourceName, string sourceMapUrl, ulong uniqueId, DocumentKind documentKind, IntPtr pDocumentInfo, string code);
V8Script.Handle V8Context_CompileScriptFromUtf8(V8Context.Handle hContext, string resourceName, string sourceMapUrl, ulong uniqueId, DocumentKind documentKind, IntPtr pDocumentInfo, IntPtr pCode, int codeLength, UIntPtr codeDigest);
V8Script.Handle V8Context_CompileProducingCache(V8Context.Handle hContext, string resourceName, string sourceMapUrl, ulong uniqueId, DocumentKind documentKind, IntPtr pDocumentInfo, string code, V8CacheKind cacheKind, out byte[] cacheBytes);
V8Script.Handle V8Context_CompileConsumingCache(V8Context.Handle hContext, string resourceName, string sourceMapUrl, ulong uniqueId, DocumentKind documentKind, IntPtr pDocumentInfo, string code, V8CacheKind cacheKind, byte[] cacheBytes, out bool cacheAccepted);
V8Script.Handle V8Context_CompileUpdatingCache(V8Context.Handle hContext, string resourceName, string sourceMapUrl, ulong uniqueId, DocumentKind documentKind, IntPtr pDocumentInfo, string code, V8CacheKind cacheKind, ref byte[] cacheBytes, out V8CacheResult cacheResult);
Expand Down
41 changes: 41 additions & 0 deletions ClearScript/V8/SplitProxy/V8ContextProxyImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,27 @@ public override object Execute(UniqueDocumentInfo documentInfo, string code, boo
);
}

public override object ExecuteScriptFromUtf8(UniqueDocumentInfo documentInfo, IntPtr pCode, int codeLength, bool evaluate)
{
UIntPtr codeDigest = MiscHelpers.GetDigestFromUtf8(pCode, codeLength);

return V8SplitProxyNative.Invoke(
static (instance, ctx) => instance.V8Context_ExecuteScriptFromUtf8(
ctx.Handle,
MiscHelpers.GetUrlOrPath(ctx.documentInfo.Uri, ctx.documentInfo.UniqueName),
MiscHelpers.GetUrlOrPath(ctx.documentInfo.SourceMapUri, string.Empty),
ctx.documentInfo.UniqueId,
ctx.documentInfo.Category.Kind,
V8ProxyHelpers.AddRefHostObject(ctx.documentInfo),
ctx.pCode,
ctx.codeLength,
ctx.codeDigest,
ctx.evaluate
),
(Handle, documentInfo, pCode, codeLength, codeDigest, evaluate)
);
}

public override V8.V8Script Compile(UniqueDocumentInfo documentInfo, string code)
{
return new V8ScriptImpl(documentInfo, code.GetDigest(), V8SplitProxyNative.Invoke(
Expand All @@ -119,6 +140,26 @@ public override V8.V8Script Compile(UniqueDocumentInfo documentInfo, string code
));
}

public override V8.V8Script CompileScriptFromUtf8(UniqueDocumentInfo documentInfo, IntPtr pCode, int codeLength)
{
UIntPtr codeDigest = MiscHelpers.GetDigestFromUtf8(pCode, codeLength);

return new V8ScriptImpl(documentInfo, codeDigest, V8SplitProxyNative.Invoke(
static (instance, ctx) => instance.V8Context_CompileScriptFromUtf8(
ctx.Handle,
MiscHelpers.GetUrlOrPath(ctx.documentInfo.Uri, ctx.documentInfo.UniqueName),
MiscHelpers.GetUrlOrPath(ctx.documentInfo.SourceMapUri, string.Empty),
ctx.documentInfo.UniqueId,
ctx.documentInfo.Category.Kind,
V8ProxyHelpers.AddRefHostObject(ctx.documentInfo),
ctx.pCode,
ctx.codeLength,
ctx.codeDigest
),
(Handle, documentInfo, pCode, codeLength, codeDigest)
));
}

public override V8.V8Script Compile(UniqueDocumentInfo documentInfo, string code, V8CacheKind cacheKind, out byte[] cacheBytes)
{
if (cacheKind == V8CacheKind.None)
Expand Down
54 changes: 54 additions & 0 deletions ClearScript/V8/SplitProxy/V8SplitProxyNative.Common.tt
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,21 @@ namespace Microsoft.ClearScript.V8.SplitProxy
}
}

object IV8SplitProxyNative.V8Context_ExecuteScriptFromUtf8(V8Context.Handle hContext, string resourceName, string sourceMapUrl, ulong uniqueId, DocumentKind documentKind, IntPtr pDocumentInfo, IntPtr pCode, int codeLength, UIntPtr codeDigest, bool evaluate)
{
using (var resourceNameScope = StdString.CreateScope(resourceName))
{
using (var sourceMapUrlScope = StdString.CreateScope(sourceMapUrl))
{
using (var resultScope = V8Value.CreateScope())
{
V8Context_ExecuteScriptFromUtf8(hContext, resourceNameScope.Value, sourceMapUrlScope.Value, uniqueId, documentKind, pDocumentInfo, pCode, codeLength, codeDigest, evaluate, resultScope.Value);
return V8Value.Get(resultScope.Value);
}
}
}
}

V8Script.Handle IV8SplitProxyNative.V8Context_Compile(V8Context.Handle hContext, string resourceName, string sourceMapUrl, ulong uniqueId, DocumentKind documentKind, IntPtr pDocumentInfo, string code)
{
using (var resourceNameScope = StdString.CreateScope(resourceName))
Expand All @@ -782,6 +797,17 @@ namespace Microsoft.ClearScript.V8.SplitProxy
}
}

V8Script.Handle IV8SplitProxyNative.V8Context_CompileScriptFromUtf8(V8Context.Handle hContext, string resourceName, string sourceMapUrl, ulong uniqueId, DocumentKind documentKind, IntPtr pDocumentInfo, IntPtr pCode, int codeLength, UIntPtr codeDigest)
{
using (var resourceNameScope = StdString.CreateScope(resourceName))
{
using (var sourceMapUrlScope = StdString.CreateScope(sourceMapUrl))
{
return V8Context_CompileScriptFromUtf8(hContext, resourceNameScope.Value, sourceMapUrlScope.Value, uniqueId, documentKind, pDocumentInfo, pCode, codeLength, codeDigest);
}
}
}

V8Script.Handle IV8SplitProxyNative.V8Context_CompileProducingCache(V8Context.Handle hContext, string resourceName, string sourceMapUrl, ulong uniqueId, DocumentKind documentKind, IntPtr pDocumentInfo, string code, V8CacheKind cacheKind, out byte[] cacheBytes)
{
using (var resourceNameScope = StdString.CreateScope(resourceName))
Expand Down Expand Up @@ -1889,6 +1915,21 @@ namespace Microsoft.ClearScript.V8.SplitProxy
[In] V8Value.Ptr pResult
);

[DllImport("<#= fileName #>", CallingConvention = CallingConvention.StdCall)]
private static extern void V8Context_ExecuteScriptFromUtf8(
[In] V8Context.Handle hContext,
[In] StdString.Ptr pResourceName,
[In] StdString.Ptr pSourceMapUrl,
[In] ulong uniqueId,
[In] DocumentKind documentKind,
[In] IntPtr pDocumentInfo,
[In] IntPtr pCode,
[In] int codeLength,
[In] UIntPtr codeDigest,
[In] [MarshalAs(UnmanagedType.I1)] bool evaluate,
[In] V8Value.Ptr pResult
);

[DllImport("<#= fileName #>", CallingConvention = CallingConvention.StdCall)]
private static extern V8Script.Handle V8Context_Compile(
[In] V8Context.Handle hContext,
Expand All @@ -1900,6 +1941,19 @@ namespace Microsoft.ClearScript.V8.SplitProxy
[In] StdString.Ptr pCode
);

[DllImport("<#= fileName #>", CallingConvention = CallingConvention.StdCall)]
private static extern V8Script.Handle V8Context_CompileScriptFromUtf8(
[In] V8Context.Handle hContext,
[In] StdString.Ptr pResourceName,
[In] StdString.Ptr pSourceMapUrl,
[In] ulong uniqueId,
[In] DocumentKind documentKind,
[In] IntPtr pDocumentInfo,
[In] IntPtr pCode,
[In] int codeLength,
[In] UIntPtr codeDigest
);

[DllImport("<#= fileName #>", CallingConvention = CallingConvention.StdCall)]
private static extern V8Script.Handle V8Context_CompileProducingCache(
[In] V8Context.Handle hContext,
Expand Down
Loading