private unsafe static void InvokeInternal(ContextType *cxt, ulong nativeIdentifier, IScriptHost scriptHost) { cxt->nativeIdentifier = nativeIdentifier; unsafe { #if !USE_HYPERDRIVE scriptHost.InvokeNative(new IntPtr(cxt)); #else if (!ms_invokers.TryGetValue(nativeIdentifier, out CallFunc invoker)) { invoker = BuildFunction(nativeIdentifier, GetNative(nativeIdentifier)); ms_invokers.Add(nativeIdentifier, invoker); } cxt->functionDataPtr = &cxt->functionData[0]; cxt->retDataPtr = &cxt->functionData[0]; if (!invoker(cxt)) { throw new Exception("Native invocation failed."); } CopyReferencedParametersOut(cxt); #endif } }
private static unsafe void BrotliBuildHistogramsWithContext( Command *cmds, size_t num_commands, BlockSplit *literal_split, BlockSplit *insert_and_copy_split, BlockSplit *dist_split, byte *ringbuffer, size_t start_pos, size_t mask, byte prev_byte, byte prev_byte2, ContextType *context_modes, HistogramLiteral *literal_histograms, HistogramCommand *insert_and_copy_histograms, HistogramDistance *copy_dist_histograms) { size_t pos = start_pos; BlockSplitIterator literal_it; BlockSplitIterator insert_and_copy_it; BlockSplitIterator dist_it; size_t i; InitBlockSplitIterator(&literal_it, literal_split); InitBlockSplitIterator(&insert_and_copy_it, insert_and_copy_split); InitBlockSplitIterator(&dist_it, dist_split); for (i = 0; i < num_commands; ++i) { Command *cmd = &cmds[i]; size_t j; BlockSplitIteratorNext(&insert_and_copy_it); HistogramCommand.HistogramAdd(&insert_and_copy_histograms[insert_and_copy_it.type_], cmd->cmd_prefix_); for (j = cmd->insert_len_; j != 0; --j) { size_t context; BlockSplitIteratorNext(&literal_it); context = context_modes != null ? ((literal_it.type_ << BROTLI_LITERAL_CONTEXT_BITS) + Context(prev_byte, prev_byte2, context_modes[literal_it.type_])) : literal_it.type_; HistogramLiteral.HistogramAdd(&literal_histograms[context], ringbuffer[pos & mask]); prev_byte2 = prev_byte; prev_byte = ringbuffer[pos & mask]; ++pos; } pos += CommandCopyLen(cmd); if (CommandCopyLen(cmd) != 0) { prev_byte2 = ringbuffer[(pos - 2) & mask]; prev_byte = ringbuffer[(pos - 1) & mask]; if (cmd->cmd_prefix_ >= 128) { size_t context; BlockSplitIteratorNext(&dist_it); context = (dist_it.type_ << BROTLI_DISTANCE_CONTEXT_BITS) + CommandDistanceContext(cmd); HistogramDistance.HistogramAdd(©_dist_histograms[context], cmd->dist_prefix_); } } } }
private unsafe static void InvokeInternal(ulong nativeIdentifier, IScriptHost scriptHost) { var context = m_extContext; m_extContext = new ContextType(); ContextType *cxt = &context; InvokeInternal(cxt, nativeIdentifier, scriptHost); m_extContext = context; }
internal static unsafe void PushFast <T>(ContextType *cxt, T arg) where T : struct { var size = FastStructure <T> .Size; var numArgs = (size / 8); if ((size % 8) != 0) { *(long *)(&cxt->functionData[8 * cxt->numArguments]) = 0; numArgs++; } FastStructure <T> .StructureToPtr(ref arg, new IntPtr(&cxt->functionData[8 * cxt->numArguments])); cxt->numArguments += numArgs; }
internal unsafe static void CopyReferencedParametersOut(ContextType *cxt) { uint result = 0; long a1 = (long)cxt; for (; *(uint *)(a1 + 24) != 0; *(uint *)(*(ulong *)(a1 + 8 * *(int *)(a1 + 24) + 32) + 16) = result) { --*(uint *)(a1 + 24); * *(uint **)(a1 + 8 * *(int *)(a1 + 24) + 32) = *(uint *)(a1 + 16 * (*(int *)(a1 + 24) + 4)); *(uint *)(*(ulong *)(a1 + 8 * *(int *)(a1 + 24) + 32) + 8) = *(uint *)(a1 + 16 * *(int *)(a1 + 24) + 68); result = *(uint *)(a1 + 16 * *(int *)(a1 + 24) + 72); } --*(uint *)(a1 + 24); }
internal static unsafe void PushObject(ContextType *cxt, object arg) { var ptr = IntPtr.Zero; var b = MsgPackSerializer.Serialize(arg); ptr = Marshal.AllocHGlobal(b.Length); Marshal.Copy(b, 0, ptr, b.Length); ms_finalizers.Enqueue(() => Free(ptr)); unsafe { *(IntPtr *)(&cxt->functionData[8 * cxt->numArguments]) = ptr; *(long *)(&cxt->functionData[8 * (cxt->numArguments + 1)]) = b.Length; } cxt->numArguments += 2; }
private unsafe static void InvokeInternal(ContextType *cxt, ulong nativeIdentifier, IScriptHost scriptHost) { cxt->nativeIdentifier = nativeIdentifier; unsafe { #if !USE_HYPERDRIVE try { scriptHost.InvokeNative(new IntPtr(cxt)); } catch (ArgumentException e) { IntPtr errorString = scriptHost.GetLastErrorText(); byte * error = (byte *)errorString.ToPointer(); throw new InvalidOperationException(ErrorHandler(error)); } #else if (!ms_invokers.TryGetValue(nativeIdentifier, out CallFunc invoker)) { invoker = BuildFunction(nativeIdentifier, GetNative(nativeIdentifier)); ms_invokers.Add(nativeIdentifier, invoker); } cxt->functionDataPtr = &cxt->functionData[0]; cxt->retDataPtr = &cxt->functionData[0]; byte *error = null; if (!invoker(cxt, (void **)&error)) { throw new InvalidOperationException(ErrorHandler(error)); } CopyReferencedParametersOut(cxt); #endif } }
private unsafe static void InvokeInternal(ContextType *cxt, ulong nativeIdentifier, IScriptHost scriptHost) { cxt->nativeIdentifier = nativeIdentifier; unsafe { #if !USE_HYPERDRIVE scriptHost.InvokeNative(new IntPtr(cxt)); #else if (!ms_invokers.TryGetValue(nativeIdentifier, out CallFunc invoker)) { invoker = BuildFunction(GetNative(nativeIdentifier)); ms_invokers.Add(nativeIdentifier, invoker); } cxt->functionDataPtr = &cxt->functionData[0]; cxt->retDataPtr = &cxt->functionData[0]; invoker(cxt); #endif } }
internal unsafe static void PushString(ContextType *cxt, string str) { var ptr = IntPtr.Zero; if (str != null) { var len = str.Length; var sptr = ms_stringHeapPointer; // worst-case UTF8 length if ((len + sptr) < ((1024 * 64) - 1)) { var blen = Encoding.UTF8.GetBytes(str, 0, len, ms_stringHeap, sptr); ms_stringHeap[sptr + blen] = 0; ms_stringHeapPointer += blen + 1; ptr = ms_stringHeapHandlePtr + sptr; } else { // too long/doesn't fit, alloc traditionally var b = Encoding.UTF8.GetBytes(str); ptr = Marshal.AllocHGlobal(b.Length + 1); Marshal.Copy(b, 0, ptr, b.Length); Marshal.WriteByte(ptr, b.Length, 0); ms_finalizers.Enqueue(() => Free(ptr)); } } unsafe { *(IntPtr *)(&cxt->functionData[8 * cxt->numArguments]) = ptr; } cxt->numArguments++; }
internal unsafe static void Push(ContextType *context, object arg) { if (arg == null) { arg = 0; } if (arg.GetType().IsEnum) { arg = Convert.ChangeType(arg, arg.GetType().GetEnumUnderlyingType()); } if (arg is string) { var str = (string)Convert.ChangeType(arg, typeof(string)); PushString(context, str); return; } else if (arg is Vector3 v) { PushFast(context, v); return; } else if (arg is InputArgument ia) { Push(context, ia.Value); return; } else if (Marshal.SizeOf(arg.GetType()) <= 8) { PushUnsafe(context, arg); } context->numArguments++; }
internal unsafe static void PushString(ContextType *cxt, string str) { var ptr = IntPtr.Zero; if (str != null) { var b = Encoding.UTF8.GetBytes(str); ptr = Marshal.AllocHGlobal(b.Length + 1); Marshal.Copy(b, 0, ptr, b.Length); Marshal.WriteByte(ptr, b.Length, 0); ms_finalizers.Enqueue(() => Free(ptr)); } unsafe { *(IntPtr *)(&cxt->functionData[8 * cxt->numArguments]) = ptr; } cxt->numArguments++; }
private static unsafe void BrotliBuildMetaBlock(ref MemoryManager m, byte *ringbuffer, size_t pos, size_t mask, BrotliEncoderParams *params_, byte prev_byte, byte prev_byte2, Command *cmds, size_t num_commands, ContextType literal_context_mode, MetaBlockSplit *mb) { /* Histogram ids need to fit in one byte. */ size_t kMaxNumberOfHistograms = 256; HistogramDistance *distance_histograms; HistogramLiteral * literal_histograms; ContextType * literal_context_modes = null; size_t literal_histograms_size; size_t distance_histograms_size; size_t i; size_t literal_context_multiplier = 1; BrotliSplitBlock(ref m, cmds, num_commands, ringbuffer, pos, mask, params_, &mb->literal_split, &mb->command_split, &mb->distance_split); if (!params_->disable_literal_context_modeling) { literal_context_multiplier = 1 << BROTLI_LITERAL_CONTEXT_BITS; literal_context_modes = (ContextType *)BrotliAllocate(ref m, mb->literal_split.num_types * sizeof(ContextType)); for (i = 0; i < mb->literal_split.num_types; ++i) { literal_context_modes[i] = literal_context_mode; } } literal_histograms_size = mb->literal_split.num_types * literal_context_multiplier; literal_histograms = (HistogramLiteral *)BrotliAllocate(ref m, literal_histograms_size * sizeof(HistogramLiteral)); HistogramLiteral.ClearHistograms(literal_histograms, literal_histograms_size); distance_histograms_size = mb->distance_split.num_types << BROTLI_DISTANCE_CONTEXT_BITS; distance_histograms = (HistogramDistance *)BrotliAllocate(ref m, distance_histograms_size * sizeof(HistogramDistance)); HistogramDistance.ClearHistograms(distance_histograms, distance_histograms_size); mb->command_histograms_size = mb->command_split.num_types; mb->command_histograms = (HistogramCommand *)BrotliAllocate(ref m, mb->command_histograms_size * sizeof(HistogramCommand)); HistogramCommand.ClearHistograms(mb->command_histograms, mb->command_histograms_size); BrotliBuildHistogramsWithContext(cmds, num_commands, &mb->literal_split, &mb->command_split, &mb->distance_split, ringbuffer, pos, mask, prev_byte, prev_byte2, literal_context_modes, literal_histograms, mb->command_histograms, distance_histograms); BrotliFree(ref m, literal_context_modes); mb->literal_context_map_size = mb->literal_split.num_types << BROTLI_LITERAL_CONTEXT_BITS; mb->literal_context_map = (uint *)BrotliAllocate(ref m, mb->literal_context_map_size * sizeof(uint)); mb->literal_histograms_size = mb->literal_context_map_size; mb->literal_histograms = (HistogramLiteral *)BrotliAllocate(ref m, mb->literal_histograms_size * sizeof(HistogramLiteral)); ClusterLiteral.BrotliClusterHistograms(ref m, literal_histograms, literal_histograms_size, kMaxNumberOfHistograms, mb->literal_histograms, &mb->literal_histograms_size, mb->literal_context_map); BrotliFree(ref m, literal_histograms); if (params_->disable_literal_context_modeling) { /* Distribute assignment to all contexts. */ for (i = mb->literal_split.num_types; i != 0;) { size_t j = 0; i--; for (; j < (1 << BROTLI_LITERAL_CONTEXT_BITS); j++) { mb->literal_context_map[(i << BROTLI_LITERAL_CONTEXT_BITS) + j] = mb->literal_context_map[i]; } } } mb->distance_context_map_size = mb->distance_split.num_types << BROTLI_DISTANCE_CONTEXT_BITS; mb->distance_context_map = (uint *)BrotliAllocate(ref m, mb->distance_context_map_size * sizeof(uint)); mb->distance_histograms_size = mb->distance_context_map_size; mb->distance_histograms = (HistogramDistance *)BrotliAllocate(ref m, mb->distance_histograms_size * sizeof(HistogramDistance)); ClusterDistance.BrotliClusterHistograms(ref m, distance_histograms, mb->distance_context_map_size, kMaxNumberOfHistograms, mb->distance_histograms, &mb->distance_histograms_size, mb->distance_context_map); BrotliFree(ref m, distance_histograms); }
internal unsafe static void Invoke(ContextType *cxt, ulong nativeIdentifier) => InvokeInternal(cxt, nativeIdentifier, InternalManager.ScriptHost);
private static unsafe object GetResultHelper(ContextType *context, Type type) { return(GetResult(type, &context->functionData[0])); }
internal unsafe static object GetResult(ContextType *cxt, Type type) { return(GetResultHelper(cxt, type)); }
internal static unsafe T GetResultFast <T>(ContextType *cxt) where T : struct { return(FastStructure <T> .PtrToStructure(new IntPtr(&cxt->functionData))); }
internal static unsafe void PushUnsafe(ContextType *cxt, object arg) { *(long *)(&cxt->functionData[8 * cxt->numArguments]) = 0; Marshal.StructureToPtr(arg, new IntPtr(cxt->functionData + (8 * cxt->numArguments)), false); }