hakojs
Version:
A secure, embeddable JavaScript engine that runs untrusted code inside WebAssembly sandboxes with fine-grained permissions and resource limits
294 lines • 12.7 kB
TypeScript
import { type ContextOptions, type ExecutePendingJobsResult, type InterruptHandler, type JSRuntimePointer, type JSVoid, type MemoryUsage, type ModuleLoaderFunction, type ModuleNormalizerFunction, type ModuleResolverFunction, type ProfilerEventHandler, type StripOptions } from "../etc/types";
import { CModuleBuilder, type CModuleInitializer } from "../vm/cmodule";
import { VMContext } from "../vm/context";
import type { Container } from "./container";
/**
* The HakoRuntime class represents a JavaScript execution environment.
*
* It manages the lifecycle of JS execution contexts, handles memory allocation
* and deallocation, provides module loading capabilities, and offers utilities
* for performance monitoring and control.
*
* @implements {Disposable} - Implements the Disposable interface for resource cleanup
*/
export declare class HakoRuntime implements Disposable {
/**
* The dependency injection container that provides access to core services and WebAssembly exports.
*/
private container;
/**
* An optional default context for this runtime.
*
* If this runtime was created as part of a context, points to the context
* associated with the runtime. If this runtime was created stand-alone, this may
* be lazily initialized when needed (e.g., for {@link computeMemoryUsage}).
*/
private context;
/**
* The pointer to the native runtime instance in WebAssembly memory.
*/
private rtPtr;
/**
* Flag indicating whether this runtime has been released.
*/
private isReleased;
/**
* Map of all contexts created within this runtime, keyed by their pointer values.
* Used for management and cleanup.
*/
private contextMap;
/**
* Reference to the current interrupt handler function.
* Stored to allow for proper cleanup when the runtime is disposed.
*/
private currentInterruptHandler;
/**
* Creates a new HakoRuntime instance.
*
* @param container - The dependency injection container that provides access to core services
* @param rtPtr - The pointer to the native runtime instance in WebAssembly memory
*/
constructor(container: Container, rtPtr: JSRuntimePointer);
/**
* Gets the native runtime pointer.
*
* @returns The pointer to the native runtime instance in WebAssembly memory
*/
get pointer(): JSRuntimePointer;
/**
* Creates a C module with inline handler registration
*/
createCModule(name: string, handler: (initializer: CModuleInitializer) => number | undefined, ctx?: VMContext | undefined): CModuleBuilder;
/**
* Creates a new JavaScript execution context within this runtime.
*
* Contexts isolate JavaScript execution environments, each with their own global object
* and set of available APIs based on the specified intrinsics.
*
* @param options - Configuration options for the new context
* @param options.contextPointer - Optional existing context pointer to wrap
* @param options.intrinsics - Optional set of intrinsics to include in the context
* @param options.maxStackSizeBytes - Optional maximum stack size for the context
*
* @returns A new VMContext instance
* @throws {Error} When context creation fails
*/
createContext(options?: ContextOptions): VMContext;
/**
* Sets the stripping options for the runtime
*
* @param options - Configuration options for code stripping
* @param options.stripSource - When true, source code will be stripped
* @param options.stripDebug - When true, all debug info will be stripped (including source)
*
* @example
* // Strip only source code
* runtime.setStripInfo({ stripSource: true });
*
* // Strip all debug info (including source)
* runtime.setStripInfo({ stripDebug: true });
*/
setStripInfo(options?: StripOptions): void;
/**
* Gets the current stripping configuration
*
* @returns The current stripping options
*
* @remarks
* Note that stripSource will be true if either source stripping or debug stripping
* is enabled, matching the behavior of the underlying C implementation.
*
* @example
* const options = runtime.getStripInfo();
* console.log(`Source stripping: ${options.stripSource}`);
* console.log(`Debug stripping: ${options.stripDebug}`);
*/
getStripInfo(): StripOptions;
/**
* Sets the memory usage limit for this runtime.
*
* This controls the maximum amount of memory the JavaScript engine can allocate.
* When the limit is reached, allocation attempts will fail with out-of-memory errors.
*
* @param limit - The memory limit in bytes, or -1 for no limit (default)
*/
setMemoryLimit(limit?: number): void;
/**
* Computes detailed memory usage statistics for this runtime.
*
* This method provides insights into how memory is being used by different
* components of the JavaScript engine.
*
* @param ctx - Optional context to use for creating the result object.
* If not provided, the system context will be used.
*
* @returns An object containing memory usage information
* @throws {Error} When memory usage computation fails
*/
computeMemoryUsage(ctx?: VMContext | undefined): MemoryUsage;
/**
* Generates a human-readable string representation of memory usage.
*
* This is useful for debugging memory issues or monitoring runtime memory consumption.
*
* @returns A formatted string containing memory usage information
*/
dumpMemoryUsage(): string;
/**
* Enables the module loader for this runtime to support ES modules.
*
* The module loader allows JavaScript code executed in this runtime to import
* modules using the standard ES module syntax (import/export).
*
* @param loader - Function to load module source code given a module specifier
* @param normalizer - Optional function to normalize module names (resolve relative paths, etc.)
* @param resolver - Optional function to handle import.meta.resolve calls
*/
enableModuleLoader(loader: ModuleLoaderFunction, normalizer?: ModuleNormalizerFunction, resolver?: ModuleResolverFunction): void;
/**
* Disables the module loader for this runtime.
*
* After calling this method, attempts to import modules will fail.
*/
disableModuleLoader(): void;
/**
* Enables the interrupt handler for this runtime.
*
* The interrupt handler allows controlled termination of long-running JavaScript
* operations to prevent infinite loops or excessive execution time.
*
* @param handler - Function called periodically during JavaScript execution to check
* if execution should be interrupted. Return true to interrupt.
* @param opaque - Optional user data passed to the handler
*/
enableInterruptHandler(handler: InterruptHandler, opaque?: number): void;
/**
* Enables profiling of JavaScript function calls.
* @param handler - The handlers for trace events
* @param sampling - Controls profiling frequency: only 1/sampling function calls are instrumented.
* Must be ≥ 1. Example: if sampling=4, only 25% of function calls will trigger the handlers.
* @param opaque - Optional user data passed to both handlers.
*/
enableProfileCalls(handler: ProfilerEventHandler, sampling?: number, opaque?: JSVoid): void;
/**
* Disables the interrupt handler for this runtime.
*
* After calling this method, JavaScript code can run without being interruptible,
* which may lead to infinite loops or excessive execution time.
*/
disableInterruptHandler(): void;
/**
* Gets or lazily creates the system context for this runtime.
*
* The system context is used for operations that need a context but don't
* specifically require a user-created one.
*
* @returns The system context instance
*/
getSystemContext(): VMContext;
/**
* Creates a time-based interrupt handler that terminates execution
* after a specified time has elapsed.
*
* This is useful for imposing time limits on JavaScript execution to prevent
* excessive CPU usage or hanging processes.
*
* @param deadlineMs - The time limit in milliseconds from now
* @returns An interrupt handler function that can be passed to enableInterruptHandler()
*
* @example
* ```typescript
* // Limit execution to 1 second
* const handler = runtime.createDeadlineInterruptHandler(1000);
* runtime.enableInterruptHandler(handler);
* context.evaluateScript("while(true) {}"); // Will be interrupted after ~1 second
* ```
*/
createDeadlineInterruptHandler(deadlineMs: number): InterruptHandler;
/**
* Creates a gas-based interrupt handler that terminates script execution
* after a specified number of JavaScript operations (gas units) have been performed.
*
* This handler provides a deterministic method for limiting the computational
* complexity of scripts by counting operations rather than relying on time-based limits.
*
* @param maxGas - The maximum number of operations (gas units) allowed before interruption.
* @returns An interrupt handler function that returns `true` when the gas limit is reached,
* which can be passed to `enableInterruptHandler()`.
*
* @example
* ```typescript
* // Limit execution to 1 million gas units (operations)
* const handler = runtime.createGasInterruptHandler(1_000_000);
* runtime.enableInterruptHandler(handler);
* context.evaluateScript("let i = 0; while(true) { i++; }"); // This script will be interrupted.
* ```
*/
createGasInterruptHandler(maxGas: number): InterruptHandler;
/**
* Checks if there are pending asynchronous jobs (Promises) in this runtime.
*
* @returns True if there are pending jobs, false otherwise
*/
isJobPending(): boolean;
/**
* Executes pending Promise jobs (microtasks) in the runtime.
*
* In JavaScript engines, promises and async functions create "jobs" that
* are executed after the current execution context completes. This method
* manually triggers the execution of these pending jobs.
*
* @param maxJobsToExecute - When negative (default), run all pending jobs.
* Otherwise, execute at most `maxJobsToExecute` jobs before returning.
*
* @returns On success, returns the number of executed jobs. On error, returns
* the exception that stopped execution and the context it occurred in.
*
* @remarks
* This method does not normally return errors thrown inside async functions or
* rejected promises. Those errors are available by calling
* {@link VMContext#resolvePromise} on the promise handle returned by the async function.
*/
executePendingJobs(maxJobsToExecute?: number): ExecutePendingJobsResult;
/**
* Performs a memory leak check if compiled with leak sanitizer.
*
* This is a development/debugging utility to detect memory leaks.
*
* @returns Leak check result code (non-zero indicates potential leaks)
*/
recoverableLeakCheck(): number;
dropContext(context: VMContext): void;
/**
* Releases all resources associated with this runtime.
*
* This includes all contexts, handlers, and the native runtime itself.
* After calling this method, the runtime instance should not be used.
*/
release(): void;
/**
* Allocates shared runtime memory.
* @param size - The size in bytes to allocate
* @returns The pointer to the allocated memory
*/
allocateMemory(size: number): number;
/**
* Frees previously allocated shared runtime memory.
* @param ptr - The pointer to the memory to free
*/
freeMemory(ptr: number): void;
/**
* Gets build information about the WebAssembly module.
*
* @returns Build metadata including version, build date, and configuration
*/
get build(): import("../etc/types").HakoBuildInfo;
/**
* Implements the Symbol.dispose method for the Disposable interface.
*
* This allows the runtime to be used with the using/with statements in
* environments that support the Disposable pattern.
*/
[Symbol.dispose](): void;
}
//# sourceMappingURL=runtime.d.ts.map