diff --git a/src/Microsoft.Blazor.Browser.JS/src/Rendering/RenderComponentArgs.ts b/src/Microsoft.Blazor.Browser.JS/src/Rendering/RenderComponentArgs.ts new file mode 100644 index 0000000000..5f5cea5485 --- /dev/null +++ b/src/Microsoft.Blazor.Browser.JS/src/Rendering/RenderComponentArgs.ts @@ -0,0 +1,14 @@ +import { Pointer, System_Array } from '../Platform/Platform'; +import { platform } from '../Environment'; + +// Keep in sync with the RenderComponentArgs struct in .NET code +export const renderComponentArgs = { + browserRendererId: (obj: RenderComponentArgsPointer) => platform.readInt32Field(obj, 0), + componentId: (obj: RenderComponentArgsPointer) => platform.readInt32Field(obj, 4), + renderTree: (obj: RenderComponentArgsPointer) => platform.readObjectField(obj, 8) as System_Array, + renderTreeLength: (obj: RenderComponentArgsPointer) => platform.readInt32Field(obj, 12), +} + +// Nominal type to ensure only valid pointers are passed to the renderComponentArgs functions. +// At runtime the values are just numbers. +export interface RenderComponentArgsPointer extends Pointer { RenderComponentArgsPointer__DO_NOT_IMPLEMENT: any } diff --git a/src/Microsoft.Blazor.Browser.JS/src/Rendering/Renderer.ts b/src/Microsoft.Blazor.Browser.JS/src/Rendering/Renderer.ts index 5d051bb9c0..6988731eed 100644 --- a/src/Microsoft.Blazor.Browser.JS/src/Rendering/Renderer.ts +++ b/src/Microsoft.Blazor.Browser.JS/src/Rendering/Renderer.ts @@ -1,6 +1,7 @@ import { System_Object, System_String, System_Array, MethodHandle, Pointer } from '../Platform/Platform'; import { platform } from '../Environment'; import { getTreeNodePtr, renderTreeNode, NodeType, RenderTreeNodePointer } from './RenderTreeNode'; +import { renderComponentArgs, RenderComponentArgsPointer } from './RenderComponentArgs'; let raiseEventMethod: MethodHandle; let renderComponentMethod: MethodHandle; @@ -24,14 +25,14 @@ export function attachComponentToElement(browserRendererId: number, elementSelec browserRenderers[browserRendererId][componentId] = element; } -export function renderRenderTree(renderComponentArgs: Pointer) { - const browserRendererId = platform.readInt32Field(renderComponentArgs, 0); +export function renderRenderTree(args: RenderComponentArgsPointer) { + const browserRendererId = renderComponentArgs.browserRendererId(args); const browserRenderer = browserRenderers[browserRendererId]; if (!browserRenderer) { throw new Error(`There is no browser renderer with ID ${browserRendererId}.`); } - const componentId = platform.readInt32Field(renderComponentArgs, 4); + const componentId = renderComponentArgs.componentId(args); const element = browserRenderer[componentId]; if (!element) { throw new Error(`No element is currently associated with component ${componentId}`); @@ -39,8 +40,8 @@ export function renderRenderTree(renderComponentArgs: Pointer) { clearElement(element); - const tree = platform.readObjectField(renderComponentArgs, 8) as System_Array; - const treeLength = platform.readInt32Field(renderComponentArgs, 12); + const tree = renderComponentArgs.renderTree(args); + const treeLength = renderComponentArgs.renderTreeLength(args); insertNodeRange(browserRendererId, componentId, element, tree, 0, treeLength - 1); }