hakojs
Version:
A secure, embeddable JavaScript engine that runs untrusted code inside WebAssembly sandboxes with fine-grained permissions and resource limits
190 lines • 8.49 kB
TypeScript
/**
* callbacks.ts - Host/VM callback system for PrimJS wrapper
*
* This module provides the callback management system that enables bidirectional
* communication between the host JavaScript environment and the WebAssembly-based
* PrimJS virtual machine. It handles function calls, interrupts, module loading,
* and context/runtime registrations.
*/
import type { HakoExports } from "../etc/ffi";
import type { ClassConstructorHandler, ClassFinalizerHandler, HostCallbackFunction, InterruptHandler, JSContextPointer, JSRuntimePointer, JSValuePointer, JSVoid, ModuleInitFunction, ModuleLoaderFunction, ModuleNormalizerFunction, ModuleResolverFunction, ProfilerEventHandler } from "../etc/types";
import type { MemoryManager } from "../mem/memory";
import type { VMContext } from "../vm/context";
import { VMValue } from "../vm/value";
import type { HakoRuntime } from "./runtime";
/**
* Manages bidirectional callbacks between the host JavaScript environment and the PrimJS VM.
*
* CallbackManager serves as the bridge between JavaScript and WebAssembly, enabling:
* - Host JavaScript functions to be called from the PrimJS environment
* - Module loading and resolution for ES modules support
* - Interrupt handling for execution control
* - Context and runtime object tracking
*
* This class maintains registries of JavaScript objects and their corresponding
* WebAssembly pointers to enable seamless interoperability.
*/
export declare class CallbackManager {
private exports;
private memory;
private hostFunctions;
private moduleInitHandlers;
private classConstructors;
private classFinalizers;
/**
* Counter for generating unique function IDs.
* Starts at -32768 to avoid conflicts with any internal IDs.
*/
private nextFunctionId;
private moduleLoader;
private moduleNormalizer;
private moduleResolver;
private interruptHandler;
private profilerHandler;
private contextRegistry;
private runtimeRegistry;
constructor(memory: MemoryManager);
/**
* Sets the WebAssembly exports object after module instantiation.
* Must be called before using other methods.
*/
setExports(exports: HakoExports): void;
/**
* Returns the import object needed for WebAssembly module instantiation.
*
* This provides the callback functions that the WebAssembly module will call
* to communicate with the host JavaScript environment.
*/
getImports(): Record<string, unknown>;
/**
* Registers a VMContext object with its corresponding pointer.
*
* This associates a JavaScript VMContext object with its WebAssembly pointer
* to enable lookups in either direction.
*/
registerContext(ctxPtr: JSContextPointer, ctx: VMContext): void;
/**
* Unregisters a context from the registry.
* Call this when a context is disposed to prevent memory leaks.
*/
unregisterContext(ctxPtr: JSContextPointer): void;
unregisterClassConstructor(classId: number): void;
unregisterClassFinalizer(classId: number): void;
getContext(ctxPtr: JSContextPointer): VMContext | undefined;
/**
* Registers a HakoRuntime object with its corresponding pointer.
*
* This associates a JavaScript HakoRuntime object with its WebAssembly pointer
* to enable lookups in either direction.
*/
registerRuntime(rtPtr: JSRuntimePointer, runtime: HakoRuntime): void;
/**
* Unregisters a runtime from the registry.
* Call this when a runtime is disposed to prevent memory leaks.
*/
unregisterRuntime(rtPtr: JSRuntimePointer): void;
registerModuleInitHandler(moduleName: string, handler: ModuleInitFunction): void;
unregisterModuleInitHandler(moduleName: string): void;
registerClassConstructor(classId: number, handler: ClassConstructorHandler): void;
registerClassFinalizer(classId: number, handler: ClassFinalizerHandler): void;
getRuntime(rtPtr: JSRuntimePointer): HakoRuntime | undefined;
/**
* Registers a host JavaScript function that can be called from PrimJS.
*/
registerHostFunction(callback: HostCallbackFunction<VMValue>): number;
unregisterHostFunction(id: number): void;
/**
* Creates a new PrimJS function that calls a host JavaScript function.
*
* This creates a JavaScript function in the PrimJS environment that,
* when called, will execute the provided host callback function.
*/
newFunction(ctx: JSContextPointer, callback: HostCallbackFunction<VMValue>, name: string): JSValuePointer;
/**
* Sets the module loader function for ES modules support.
*
* The module loader is called when PrimJS needs to load a module by name.
* It should return the module's source code as a string, or null if not found.
*/
setModuleLoader(loader: ModuleLoaderFunction | null): void;
/**
* Sets the module normalizer function for ES modules support.
*
* The module normalizer is called to resolve relative module specifiers
* into absolute module names.
*/
setModuleNormalizer(normalizer: ModuleNormalizerFunction | null): void;
setModuleResolver(resolver: ModuleResolverFunction | null): void;
/**
* Sets the interrupt handler function for execution control.
*
* The interrupt handler is called periodically during PrimJS execution
* and can terminate execution by returning true.
*/
setInterruptHandler(handler: InterruptHandler | null): void;
/**
* Sets up runtime callbacks for a specific runtime instance.
*
* This registers the runtime object for later lookup and enables
* callback functionality for the runtime.
*/
setRuntimeCallbacks(rtPtr: JSRuntimePointer, runtime: HakoRuntime): void;
setProfilerHandler(handler: ProfilerEventHandler | null): void;
/**
* Handles a call from PrimJS to a host JavaScript function.
*
* This is called by the WebAssembly module when a host function
* registered with registerHostFunction is invoked from PrimJS.
*/
handleHostFunctionCall(ctxPtr: JSContextPointer, thisPtr: JSValuePointer, argc: number, argvPtr: number, funcId: number): number;
/**
* Creates a HakoModuleSource struct for source code
*/
private createModuleSourceString;
/**
* Creates a HakoModuleSource struct for precompiled module
*/
private createModuleSourcePrecompiled;
/**
* Creates a HakoModuleSource struct for error case
*/
private createModuleSourceError;
/**
* Handles a module load request from PrimJS.
*
* This is called by the WebAssembly module when PrimJS needs to load
* a module during import or dynamic import operations.
*/
handleModuleLoad(_rtPtr: JSRuntimePointer, ctxPtr: JSContextPointer, moduleNamePtr: number, attributesPtr: number): number;
handleModuleResolve(_rtPtr: JSRuntimePointer, _ctxPtr: JSContextPointer, moduleNamePtr: number, currentModulePtr: number, _opaque: JSVoid): number;
/**
* Handles a module normalization request from PrimJS.
*
* This is called by the WebAssembly module when PrimJS needs to
* resolve a relative module specifier against a base module.
*/
handleModuleNormalize(_rtPtr: JSRuntimePointer, _ctxPtr: JSContextPointer, baseNamePtr: number, moduleNamePtr: number): number;
/**
* Handles an interrupt request from PrimJS.
*
* This is called periodically during PrimJS execution to check
* if execution should be interrupted.
*/
handleInterrupt(rtPtr: JSRuntimePointer, ctxPtr: JSContextPointer, opaque: JSVoid): boolean;
handleProfileFunctionStart(ctxPtr: JSContextPointer, eventPtr: number, opaque: JSVoid): void;
handleProfileFunctionEnd(ctxPtr: JSContextPointer, eventPtr: number, opaque: JSVoid): void;
handleClassConstructor(ctxPtr: number, newTargetPtr: number, argc: number, argvPtr: number, classId: number): number;
handleClassFinalizer(rtPtr: number, opaque: number, classId: number): void;
/**
* Helper to get module name from module pointer
*/
private getModuleName;
/**
* Handles a C module initialization request from PrimJS.
*
* This is called by the WebAssembly module when a C module needs
* to be initialized.
*/
handleModuleInit(ctxPtr: JSContextPointer, modulePtr: number): number;
}
//# sourceMappingURL=callback.d.ts.map