@al8b/vm 0.1.12 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/l8bvm.js.map +1 -1
- package/dist/l8bvm.mjs.map +1 -1
- package/package.json +35 -36
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/context.ts","../src/extensions.ts","../src/l8bvm.ts"],"sourcesContent":["// VM public surface — StorageService is intentionally NOT re-exported here.\n// Import it directly from \"@al8b/io\" if you need it.\nexport { createMetaFunctions, createVMContext } from \"./context\";\nexport { setupArrayExtensions } from \"./extensions\";\nexport { L8BVM } from \"./l8bvm\";\nexport type {\n\tErrorInfo,\n\tGlobalAPI,\n\tMetaFunctions,\n\tPlayerAPI,\n\tSystemAPI,\n\tVMContext,\n\tVMWarnings,\n\tWarningInfo,\n} from \"./types\";\n\n// Re-export language primitives that runtime and host code legitimately need.\n// This keeps runtime from bypassing the vm layer and importing lootiscript directly.\nexport { Random, Routine } from \"@al8b/lootiscript\";\n","/**\n * VM Context creation utilities\n */\n\nimport { Random } from \"@al8b/lootiscript\";\nimport type { GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n// Shared math lambdas — allocated once, reused across all VM instances\nconst _baseMeta = {\n\tround: (x: number) => Math.round(x),\n\tfloor: (x: number) => Math.floor(x),\n\tceil: (x: number) => Math.ceil(x),\n\tabs: (x: number) => Math.abs(x),\n\tmin: (x: number, y: number) => Math.min(x, y),\n\tmax: (x: number, y: number) => Math.max(x, y),\n\tsqrt: (x: number) => Math.sqrt(x),\n\tpow: (x: number, y: number) => x ** y,\n\tsin: (x: number) => Math.sin(x),\n\tcos: (x: number) => Math.cos(x),\n\ttan: (x: number) => Math.tan(x),\n\tasin: (x: number) => Math.asin(x),\n\tacos: (x: number) => Math.acos(x),\n\tatan: (x: number) => Math.atan(x),\n\tatan2: (y: number, x: number) => Math.atan2(y, x),\n\tsind: (x: number) => Math.sin((x / 180) * Math.PI),\n\tcosd: (x: number) => Math.cos((x / 180) * Math.PI),\n\ttand: (x: number) => Math.tan((x / 180) * Math.PI),\n\tasind: (x: number) => (Math.asin(x) * 180) / Math.PI,\n\tacosd: (x: number) => (Math.acos(x) * 180) / Math.PI,\n\tatand: (x: number) => (Math.atan(x) * 180) / Math.PI,\n\tatan2d: (y: number, x: number) => (Math.atan2(y, x) * 180) / Math.PI,\n\tlog: (x: number) => Math.log(x),\n\texp: (x: number) => Math.exp(x),\n\trandom: new Random(0),\n\tPI: Math.PI,\n\ttrue: 1 as const,\n\tfalse: 0 as const,\n};\n\nconst _defaultPrint = (text: any) => console.log(text);\n\n/**\n * Create meta functions (built-in functions)\n */\nexport function createMetaFunctions(customPrint?: (text: any) => void): MetaFunctions {\n\treturn {\n\t\t..._baseMeta,\n\t\tprint: customPrint ?? _defaultPrint,\n\t};\n}\n\n/**\n * Create VM context\n */\nexport function createVMContext(meta: Partial<MetaFunctions>, global: Partial<GlobalAPI>): VMContext {\n\tconst fullMeta: MetaFunctions = {\n\t\t..._baseMeta,\n\t\tprint: meta.print ?? _defaultPrint,\n\t\t...meta,\n\t};\n\n\treturn {\n\t\tmeta: fullMeta as MetaFunctions,\n\t\tglobal: global as GlobalAPI,\n\t\tlocal: global,\n\t\tobject: global,\n\t\tbreakable: 0,\n\t\tcontinuable: 0,\n\t\treturnable: 0,\n\t\tstack_size: 0,\n\t\ttimeout: Date.now() + 3000,\n\t\twarnings: {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t},\n\t};\n}\n","/**\n * Array extensions\n */\n\n/**\n * Setup array extensions\n */\nexport function setupArrayExtensions(): void {\n\t// Insert element at beginning of array (returns the inserted element)\n\tif (!Array.prototype.insert) {\n\t\tArray.prototype.insert = function (element: any) {\n\t\t\tthis.splice(0, 0, element);\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Insert element at specific index (returns the inserted element)\n\tif (!Array.prototype.insertAt) {\n\t\tArray.prototype.insertAt = function (element: any, index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\tthis.splice(index, 0, element);\n\t\t\t} else {\n\t\t\t\tthis.push(element);\n\t\t\t}\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Remove element at index (returns removed element or 0 if out of bounds)\n\tif (!Array.prototype.remove) {\n\t\tArray.prototype.remove = function (index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Remove first occurrence of element (returns removed element or 0 if not found)\n\tif (!Array.prototype.removeElement) {\n\t\tArray.prototype.removeElement = function (element: any) {\n\t\t\tconst index = this.indexOf(element);\n\t\t\tif (index >= 0) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Check if array contains element (returns 1 if found, 0 if not found)\n\tif (!Array.prototype.contains) {\n\t\tArray.prototype.contains = function (element: any) {\n\t\t\treturn this.indexOf(element) >= 0 ? 1 : 0;\n\t\t};\n\t}\n\n\t// Sort array with optional comparator function\n\tif (!Array.prototype.sortList) {\n\t\tArray.prototype.sortList = function (fn?: (a: any, b: any) => number) {\n\t\t\tif (fn) {\n\t\t\t\treturn this.sort(fn);\n\t\t\t}\n\t\t\treturn this.sort();\n\t\t};\n\t}\n}\n\n// TypeScript type declarations for Array prototype extensions\ndeclare global {\n\tinterface Array<T> {\n\t\tinsert(element: T): T;\n\t\tinsertAt(element: T, index: number): T;\n\t\tremove(index: number): T | 0;\n\t\tremoveElement(element: T): T | 0;\n\t\tcontains(element: T): 0 | 1;\n\t\tsortList(fn?: (a: T, b: T) => number): T[];\n\t}\n}\n","/**\n * L8BVM - Virtual Machine wrapper for lootiscript\n *\n * High-level interface for the LootiScript virtual machine.\n * Wraps the core Compiler, Processor, and Runner into a usable engine component.\n * Handles context creation, storage persistence, and error formatting.\n *\n * Responsibilities:\n * - Create and manage VM execution context\n * - Provide clean API for running code and calling functions\n * - Handle storage persistence\n * - Format and normalize runtime errors\n *\n * @module vm\n */\n\nimport type { CompiledModuleArtifact, SerializedRoutineData } from \"@al8b/framework-shared\";\nimport { StorageService } from \"@al8b/io\";\nimport { Routine, Runner } from \"@al8b/lootiscript\";\nimport { createVMContext } from \"./context\";\nimport { setupArrayExtensions } from \"./extensions\";\nimport type { ErrorInfo, GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n/**\n * Extract normalized ErrorInfo from a caught exception.\n * Centralizes the error-parsing logic shared across run(), call(), and loadRoutine().\n */\nfunction extractErrorInfo(err: any, fallbackFile: string, fallbackType: string, runner?: Runner): ErrorInfo {\n\tconst errorMessage =\n\t\ttypeof err === \"object\" && err !== null && \"error\" in err && typeof err.error === \"string\"\n\t\t\t? err.error\n\t\t\t: err?.message ?? String(err);\n\n\tlet stackTrace = err?.stackTrace;\n\tif (!stackTrace && (runner as any)?.main_thread?.processor?.generateStackTrace) {\n\t\tstackTrace = (runner as any).main_thread.processor.generateStackTrace();\n\t}\n\n\treturn {\n\t\terror: errorMessage,\n\t\ttype: err?.type ?? fallbackType,\n\t\tline: err?.line,\n\t\tcolumn: err?.column,\n\t\tfile: err?.file ?? fallbackFile,\n\t\tstack: err?.stack,\n\t\tstackTrace,\n\t};\n}\n\nexport class L8BVM {\n\tpublic context: VMContext;\n\tpublic runner: Runner;\n\tpublic storage_service: StorageService;\n\tpublic error_info: ErrorInfo | null = null;\n\n\tconstructor(\n\t\tmeta: Partial<MetaFunctions> = {},\n\t\tglobal: Partial<GlobalAPI> = {},\n\t\tnamespace = \"/l8b\",\n\t\tpreserve_ls = false,\n\t) {\n\t\t// Initialize VM execution context with meta functions and global API\n\t\tthis.context = createVMContext(meta, global);\n\n\t\t// Initialize storage service for persistent data (localStorage/sessionStorage)\n\t\tthis.storage_service = new StorageService(namespace, preserve_ls);\n\n\t\t// Inject storage API into global scope for LootiScript access\n\t\tthis.context.global.storage = this.storage_service.getInterface();\n\n\t\t// Create Runner instance with reference to this VM for bidirectional communication\n\t\tthis.runner = new Runner(this as any);\n\n\t\t// Initialize Runner and create main execution thread\n\t\tthis.runner.init();\n\n\t\t// Add custom array methods to Array.prototype for LootiScript\n\t\tsetupArrayExtensions();\n\t}\n\n\t/**\n\t * Run source code\n\t *\n\t * Compiles and executes a string of LootiScript code.\n\t *\n\t * @param {string} source - The source code to execute\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @param {string} [filename=\"\"] - Filename for error reporting\n\t * @returns {any} The result of the last statement execution\n\t * @throws {ErrorInfo} If compilation or execution fails\n\t */\n\trun(source: string, timeout = 3000, filename = \"\"): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.run(source, filename);\n\t\t\tthis.storage_service.check();\n\n\t\t\tif (result !== null && result !== undefined) {\n\t\t\t\treturn this.runner.toString(result);\n\t\t\t}\n\t\t\treturn null;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"runtime\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Call a global function\n\t *\n\t * Executes a specific function defined in the global scope.\n\t * Useful for game loop hooks (update, draw) or event handlers.\n\t *\n\t * @param {string} name - Name of the function to call\n\t * @param {any[]} [args=[]] - Arguments to pass to the function\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @returns {any} The return value of the function\n\t * @throws {ErrorInfo} If the function doesn't exist or execution fails\n\t */\n\tcall(name: string, args: any[] = [], timeout = 3000): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.call(name, ...args);\n\t\t\tthis.storage_service.check();\n\t\t\treturn result;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, name, \"call\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Load a pre-compiled routine (for production builds)\n\t *\n\t * Loads bytecode directly into the VM, bypassing the compilation step.\n\t * Used in production to improve startup time and obfuscate source.\n\t *\n\t * @param {any} routineData - Either a Routine instance or serialized JSON\n\t * @param {string} [filename=\"\"] - Name of the file for error reporting\n\t * @throws {ErrorInfo} If loading fails\n\t */\n\tloadRoutine(routineData: any, filename: string = \"\"): void {\n\t\tthis.error_info = null;\n\n\t\ttry {\n\t\t\tlet routine: Routine;\n\n\t\t\t// Handle both Routine instances and serialized routine data\n\t\t\t// Serialized data needs to be imported first\n\t\t\tif (routineData instanceof Routine) {\n\t\t\t\troutine = routineData;\n\t\t\t} else {\n\t\t\t\troutine = new Routine(0).import(normalizeSerializedRoutine(routineData));\n\t\t\t}\n\n\t\t\t// Add to main thread for execution\n\t\t\tthis.runner.main_thread.addCall(routine);\n\t\t\tthis.runner.tick();\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"compile\");\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Clear warnings\n\t */\n\tclearWarnings(): void {\n\t\tthis.context.warnings = {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t};\n\t}\n\n\t/**\n\t * Get warnings\n\t */\n\tgetWarnings(): Record<string, any> {\n\t\treturn this.context.warnings || {};\n\t}\n\n\t/**\n\t * Convert value to string (for printing)\n\t */\n\ttoString(value: any): string {\n\t\treturn this.runner.toString(value);\n\t}\n}\n\nfunction normalizeSerializedRoutine(routineData: CompiledModuleArtifact | SerializedRoutineData): SerializedRoutineData {\n\tif (isCompiledModuleArtifact(routineData)) {\n\t\treturn routineData.routine;\n\t}\n\n\treturn routineData;\n}\n\nfunction isCompiledModuleArtifact(value: unknown): value is CompiledModuleArtifact {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"format\" in value &&\n\t\t(value as { format?: unknown }).format === \"l8b-compiled-routine\" &&\n\t\t\"routine\" in value\n\t);\n}\n"],"mappings":"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","names":["_baseMeta","round","x","Math","floor","ceil","abs","min","y","max","sqrt","pow","sin","cos","tan","asin","acos","atan","atan2","sind","PI","cosd","tand","asind","acosd","atand","atan2d","log","exp","random","Random","true","false","_defaultPrint","text","console","createMetaFunctions","customPrint","print","createVMContext","meta","global","fullMeta","local","object","breakable","continuable","returnable","stack_size","timeout","Date","now","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","setupArrayExtensions","Array","prototype","insert","element","splice","insertAt","index","length","push","remove","removeElement","indexOf","contains","sortList","fn","sort","import_lootiscript","extractErrorInfo","err","fallbackFile","fallbackType","runner","errorMessage","error","message","String","stackTrace","main_thread","processor","generateStackTrace","type","line","column","file","stack","L8BVM","context","storage_service","error_info","meta","global","namespace","preserve_ls","createVMContext","StorageService","storage","getInterface","Runner","init","setupArrayExtensions","run","source","timeout","filename","Date","now","stack_size","result","check","undefined","toString","call","name","args","loadRoutine","routineData","routine","Routine","import","normalizeSerializedRoutine","addCall","tick","clearWarnings","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","getWarnings","value","isCompiledModuleArtifact","format","import_lootiscript"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/context.ts","../src/extensions.ts","../src/l8bvm.ts"],"sourcesContent":["// VM public surface — StorageService is intentionally NOT re-exported here.\n// Import it directly from \"@al8b/io\" if you need it.\nexport { createMetaFunctions, createVMContext } from \"./context\";\nexport { setupArrayExtensions } from \"./extensions\";\nexport { L8BVM } from \"./l8bvm\";\nexport type {\n\tErrorInfo,\n\tGlobalAPI,\n\tMetaFunctions,\n\tPlayerAPI,\n\tSystemAPI,\n\tVMContext,\n\tVMWarnings,\n\tWarningInfo,\n} from \"./types\";\n\n// Re-export language primitives that runtime and host code legitimately need.\n// This keeps runtime from bypassing the vm layer and importing lootiscript directly.\nexport { Random, Routine } from \"@al8b/lootiscript\";\n","/**\n * VM Context creation utilities\n */\n\nimport { Random } from \"@al8b/lootiscript\";\nimport type { GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n// Shared math lambdas — allocated once, reused across all VM instances\nconst _baseMeta = {\n\tround: (x: number) => Math.round(x),\n\tfloor: (x: number) => Math.floor(x),\n\tceil: (x: number) => Math.ceil(x),\n\tabs: (x: number) => Math.abs(x),\n\tmin: (x: number, y: number) => Math.min(x, y),\n\tmax: (x: number, y: number) => Math.max(x, y),\n\tsqrt: (x: number) => Math.sqrt(x),\n\tpow: (x: number, y: number) => x ** y,\n\tsin: (x: number) => Math.sin(x),\n\tcos: (x: number) => Math.cos(x),\n\ttan: (x: number) => Math.tan(x),\n\tasin: (x: number) => Math.asin(x),\n\tacos: (x: number) => Math.acos(x),\n\tatan: (x: number) => Math.atan(x),\n\tatan2: (y: number, x: number) => Math.atan2(y, x),\n\tsind: (x: number) => Math.sin((x / 180) * Math.PI),\n\tcosd: (x: number) => Math.cos((x / 180) * Math.PI),\n\ttand: (x: number) => Math.tan((x / 180) * Math.PI),\n\tasind: (x: number) => (Math.asin(x) * 180) / Math.PI,\n\tacosd: (x: number) => (Math.acos(x) * 180) / Math.PI,\n\tatand: (x: number) => (Math.atan(x) * 180) / Math.PI,\n\tatan2d: (y: number, x: number) => (Math.atan2(y, x) * 180) / Math.PI,\n\tlog: (x: number) => Math.log(x),\n\texp: (x: number) => Math.exp(x),\n\trandom: new Random(0),\n\tPI: Math.PI,\n\ttrue: 1 as const,\n\tfalse: 0 as const,\n};\n\nconst _defaultPrint = (text: any) => console.log(text);\n\n/**\n * Create meta functions (built-in functions)\n */\nexport function createMetaFunctions(customPrint?: (text: any) => void): MetaFunctions {\n\treturn {\n\t\t..._baseMeta,\n\t\tprint: customPrint ?? _defaultPrint,\n\t};\n}\n\n/**\n * Create VM context\n */\nexport function createVMContext(meta: Partial<MetaFunctions>, global: Partial<GlobalAPI>): VMContext {\n\tconst fullMeta: MetaFunctions = {\n\t\t..._baseMeta,\n\t\tprint: meta.print ?? _defaultPrint,\n\t\t...meta,\n\t};\n\n\treturn {\n\t\tmeta: fullMeta as MetaFunctions,\n\t\tglobal: global as GlobalAPI,\n\t\tlocal: global,\n\t\tobject: global,\n\t\tbreakable: 0,\n\t\tcontinuable: 0,\n\t\treturnable: 0,\n\t\tstack_size: 0,\n\t\ttimeout: Date.now() + 3000,\n\t\twarnings: {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t},\n\t};\n}\n","/**\n * Array extensions\n */\n\n/**\n * Setup array extensions\n */\nexport function setupArrayExtensions(): void {\n\t// Insert element at beginning of array (returns the inserted element)\n\tif (!Array.prototype.insert) {\n\t\tArray.prototype.insert = function (element: any) {\n\t\t\tthis.splice(0, 0, element);\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Insert element at specific index (returns the inserted element)\n\tif (!Array.prototype.insertAt) {\n\t\tArray.prototype.insertAt = function (element: any, index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\tthis.splice(index, 0, element);\n\t\t\t} else {\n\t\t\t\tthis.push(element);\n\t\t\t}\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Remove element at index (returns removed element or 0 if out of bounds)\n\tif (!Array.prototype.remove) {\n\t\tArray.prototype.remove = function (index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Remove first occurrence of element (returns removed element or 0 if not found)\n\tif (!Array.prototype.removeElement) {\n\t\tArray.prototype.removeElement = function (element: any) {\n\t\t\tconst index = this.indexOf(element);\n\t\t\tif (index >= 0) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Check if array contains element (returns 1 if found, 0 if not found)\n\tif (!Array.prototype.contains) {\n\t\tArray.prototype.contains = function (element: any) {\n\t\t\treturn this.indexOf(element) >= 0 ? 1 : 0;\n\t\t};\n\t}\n\n\t// Sort array with optional comparator function\n\tif (!Array.prototype.sortList) {\n\t\tArray.prototype.sortList = function (fn?: (a: any, b: any) => number) {\n\t\t\tif (fn) {\n\t\t\t\treturn this.sort(fn);\n\t\t\t}\n\t\t\treturn this.sort();\n\t\t};\n\t}\n}\n\n// TypeScript type declarations for Array prototype extensions\ndeclare global {\n\tinterface Array<T> {\n\t\tinsert(element: T): T;\n\t\tinsertAt(element: T, index: number): T;\n\t\tremove(index: number): T | 0;\n\t\tremoveElement(element: T): T | 0;\n\t\tcontains(element: T): 0 | 1;\n\t\tsortList(fn?: (a: T, b: T) => number): T[];\n\t}\n}\n","/**\n * L8BVM - Virtual Machine wrapper for lootiscript\n *\n * High-level interface for the LootiScript virtual machine.\n * Wraps the core Compiler, Processor, and Runner into a usable engine component.\n * Handles context creation, storage persistence, and error formatting.\n *\n * Responsibilities:\n * - Create and manage VM execution context\n * - Provide clean API for running code and calling functions\n * - Handle storage persistence\n * - Format and normalize runtime errors\n *\n * @module vm\n */\n\nimport { StorageService } from \"@al8b/io\";\nimport { Routine, Runner } from \"@al8b/lootiscript\";\nimport { createVMContext } from \"./context\";\nimport { setupArrayExtensions } from \"./extensions\";\nimport type { ErrorInfo, GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n/**\n * Extract normalized ErrorInfo from a caught exception.\n * Centralizes the error-parsing logic shared across run(), call(), and loadRoutine().\n */\nfunction extractErrorInfo(err: any, fallbackFile: string, fallbackType: string, runner?: Runner): ErrorInfo {\n\tconst errorMessage =\n\t\ttypeof err === \"object\" && err !== null && \"error\" in err && typeof err.error === \"string\"\n\t\t\t? err.error\n\t\t\t: err?.message ?? String(err);\n\n\tlet stackTrace = err?.stackTrace;\n\tif (!stackTrace && (runner as any)?.main_thread?.processor?.generateStackTrace) {\n\t\tstackTrace = (runner as any).main_thread.processor.generateStackTrace();\n\t}\n\n\treturn {\n\t\terror: errorMessage,\n\t\ttype: err?.type ?? fallbackType,\n\t\tline: err?.line,\n\t\tcolumn: err?.column,\n\t\tfile: err?.file ?? fallbackFile,\n\t\tstack: err?.stack,\n\t\tstackTrace,\n\t};\n}\n\nexport class L8BVM {\n\tpublic context: VMContext;\n\tpublic runner: Runner;\n\tpublic storage_service: StorageService;\n\tpublic error_info: ErrorInfo | null = null;\n\n\tconstructor(\n\t\tmeta: Partial<MetaFunctions> = {},\n\t\tglobal: Partial<GlobalAPI> = {},\n\t\tnamespace = \"/l8b\",\n\t\tpreserve_ls = false,\n\t) {\n\t\t// Initialize VM execution context with meta functions and global API\n\t\tthis.context = createVMContext(meta, global);\n\n\t\t// Initialize storage service for persistent data (localStorage/sessionStorage)\n\t\tthis.storage_service = new StorageService(namespace, preserve_ls);\n\n\t\t// Inject storage API into global scope for LootiScript access\n\t\tthis.context.global.storage = this.storage_service.getInterface();\n\n\t\t// Create Runner instance with reference to this VM for bidirectional communication\n\t\tthis.runner = new Runner(this as any);\n\n\t\t// Initialize Runner and create main execution thread\n\t\tthis.runner.init();\n\n\t\t// Add custom array methods to Array.prototype for LootiScript\n\t\tsetupArrayExtensions();\n\t}\n\n\t/**\n\t * Run source code\n\t *\n\t * Compiles and executes a string of LootiScript code.\n\t *\n\t * @param {string} source - The source code to execute\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @param {string} [filename=\"\"] - Filename for error reporting\n\t * @returns {any} The result of the last statement execution\n\t * @throws {ErrorInfo} If compilation or execution fails\n\t */\n\trun(source: string, timeout = 3000, filename = \"\"): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.run(source, filename);\n\t\t\tthis.storage_service.check();\n\n\t\t\tif (result !== null && result !== undefined) {\n\t\t\t\treturn this.runner.toString(result);\n\t\t\t}\n\t\t\treturn null;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"runtime\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Call a global function\n\t *\n\t * Executes a specific function defined in the global scope.\n\t * Useful for game loop hooks (update, draw) or event handlers.\n\t *\n\t * @param {string} name - Name of the function to call\n\t * @param {any[]} [args=[]] - Arguments to pass to the function\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @returns {any} The return value of the function\n\t * @throws {ErrorInfo} If the function doesn't exist or execution fails\n\t */\n\tcall(name: string, args: any[] = [], timeout = 3000): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.call(name, ...args);\n\t\t\tthis.storage_service.check();\n\t\t\treturn result;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, name, \"call\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Load a pre-compiled routine (for production builds)\n\t *\n\t * Loads bytecode directly into the VM, bypassing the compilation step.\n\t * Used in production to improve startup time and obfuscate source.\n\t *\n\t * @param {any} routineData - Either a Routine instance or serialized JSON\n\t * @param {string} [filename=\"\"] - Name of the file for error reporting\n\t * @throws {ErrorInfo} If loading fails\n\t */\n\tloadRoutine(routineData: any, filename: string = \"\"): void {\n\t\tthis.error_info = null;\n\n\t\ttry {\n\t\t\tlet routine: Routine;\n\n\t\t\t// Handle both Routine instances and serialized routine data\n\t\t\t// Serialized data needs to be imported first\n\t\t\tif (routineData instanceof Routine) {\n\t\t\t\troutine = routineData;\n\t\t\t} else {\n\t\t\t\troutine = new Routine(0).import(normalizeSerializedRoutine(routineData));\n\t\t\t}\n\n\t\t\t// Add to main thread for execution\n\t\t\tthis.runner.main_thread.addCall(routine);\n\t\t\tthis.runner.tick();\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"compile\");\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Clear warnings\n\t */\n\tclearWarnings(): void {\n\t\tthis.context.warnings = {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t};\n\t}\n\n\t/**\n\t * Get warnings\n\t */\n\tgetWarnings(): Record<string, any> {\n\t\treturn this.context.warnings || {};\n\t}\n\n\t/**\n\t * Convert value to string (for printing)\n\t */\n\ttoString(value: any): string {\n\t\treturn this.runner.toString(value);\n\t}\n}\n\n// Inline types stub for @al8b/framework-shared\ninterface CompiledModuleArtifact {\n\tformat: \"l8b-compiled-routine\";\n\troutine: SerializedRoutineData;\n}\ntype SerializedRoutineData = {\n\tnum_args: number;\n\tops: number[];\n\targs: any[];\n\timport_refs: any[];\n\timport_values: any[];\n\timport_self: number;\n\tlocals_size?: number;\n};\n\nfunction normalizeSerializedRoutine(routineData: CompiledModuleArtifact | SerializedRoutineData): SerializedRoutineData {\n\tif (isCompiledModuleArtifact(routineData)) {\n\t\treturn routineData.routine;\n\t}\n\n\treturn routineData;\n}\n\nfunction isCompiledModuleArtifact(value: unknown): value is CompiledModuleArtifact {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"format\" in value &&\n\t\t(value as { format?: unknown }).format === \"l8b-compiled-routine\" &&\n\t\t\"routine\" in value\n\t);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;ACIA,yBAAuB;AAIvB,IAAMA,YAAY;EACjBC,OAAO,wBAACC,MAAcC,KAAKF,MAAMC,CAAAA,GAA1B;EACPE,OAAO,wBAACF,MAAcC,KAAKC,MAAMF,CAAAA,GAA1B;EACPG,MAAM,wBAACH,MAAcC,KAAKE,KAAKH,CAAAA,GAAzB;EACNI,KAAK,wBAACJ,MAAcC,KAAKG,IAAIJ,CAAAA,GAAxB;EACLK,KAAK,wBAACL,GAAWM,MAAcL,KAAKI,IAAIL,GAAGM,CAAAA,GAAtC;EACLC,KAAK,wBAACP,GAAWM,MAAcL,KAAKM,IAAIP,GAAGM,CAAAA,GAAtC;EACLE,MAAM,wBAACR,MAAcC,KAAKO,KAAKR,CAAAA,GAAzB;EACNS,KAAK,wBAACT,GAAWM,MAAcN,KAAKM,GAA/B;EACLI,KAAK,wBAACV,MAAcC,KAAKS,IAAIV,CAAAA,GAAxB;EACLW,KAAK,wBAACX,MAAcC,KAAKU,IAAIX,CAAAA,GAAxB;EACLY,KAAK,wBAACZ,MAAcC,KAAKW,IAAIZ,CAAAA,GAAxB;EACLa,MAAM,wBAACb,MAAcC,KAAKY,KAAKb,CAAAA,GAAzB;EACNc,MAAM,wBAACd,MAAcC,KAAKa,KAAKd,CAAAA,GAAzB;EACNe,MAAM,wBAACf,MAAcC,KAAKc,KAAKf,CAAAA,GAAzB;EACNgB,OAAO,wBAACV,GAAWN,MAAcC,KAAKe,MAAMV,GAAGN,CAAAA,GAAxC;EACPiB,MAAM,wBAACjB,MAAcC,KAAKS,IAAKV,IAAI,MAAOC,KAAKiB,EAAE,GAA3C;EACNC,MAAM,wBAACnB,MAAcC,KAAKU,IAAKX,IAAI,MAAOC,KAAKiB,EAAE,GAA3C;EACNE,MAAM,wBAACpB,MAAcC,KAAKW,IAAKZ,IAAI,MAAOC,KAAKiB,EAAE,GAA3C;EACNG,OAAO,wBAACrB,MAAeC,KAAKY,KAAKb,CAAAA,IAAK,MAAOC,KAAKiB,IAA3C;EACPI,OAAO,wBAACtB,MAAeC,KAAKa,KAAKd,CAAAA,IAAK,MAAOC,KAAKiB,IAA3C;EACPK,OAAO,wBAACvB,MAAeC,KAAKc,KAAKf,CAAAA,IAAK,MAAOC,KAAKiB,IAA3C;EACPM,QAAQ,wBAAClB,GAAWN,MAAeC,KAAKe,MAAMV,GAAGN,CAAAA,IAAK,MAAOC,KAAKiB,IAA1D;EACRO,KAAK,wBAACzB,MAAcC,KAAKwB,IAAIzB,CAAAA,GAAxB;EACL0B,KAAK,wBAAC1B,MAAcC,KAAKyB,IAAI1B,CAAAA,GAAxB;EACL2B,QAAQ,IAAIC,0BAAO,CAAA;EACnBV,IAAIjB,KAAKiB;EACTW,MAAM;EACNC,OAAO;AACR;AAEA,IAAMC,gBAAgB,wBAACC,SAAcC,QAAQR,IAAIO,IAAAA,GAA3B;AAKf,SAASE,oBAAoBC,aAAiC;AACpE,SAAO;IACN,GAAGrC;IACHsC,OAAOD,eAAeJ;EACvB;AACD;AALgBG;AAUT,SAASG,gBAAgBC,MAA8BC,QAA0B;AACvF,QAAMC,WAA0B;IAC/B,GAAG1C;IACHsC,OAAOE,KAAKF,SAASL;IACrB,GAAGO;EACJ;AAEA,SAAO;IACNA,MAAME;IACND;IACAE,OAAOF;IACPG,QAAQH;IACRI,WAAW;IACXC,aAAa;IACbC,YAAY;IACZC,YAAY;IACZC,SAASC,KAAKC,IAAG,IAAK;IACtBC,UAAU;MACTC,0BAA0B,CAAC;MAC3BC,8BAA8B,CAAC;MAC/BC,uBAAuB,CAAC;MACxBC,wBAAwB,CAAC;MACzBC,yBAAyB,CAAC;IAC3B;EACD;AACD;AAzBgBlB;;;AC/CT,SAASmB,uBAAAA;AAEf,MAAI,CAACC,MAAMC,UAAUC,QAAQ;AAC5BF,UAAMC,UAAUC,SAAS,SAAUC,SAAY;AAC9C,WAAKC,OAAO,GAAG,GAAGD,OAAAA;AAClB,aAAOA;IACR;EACD;AAGA,MAAI,CAACH,MAAMC,UAAUI,UAAU;AAC9BL,UAAMC,UAAUI,WAAW,SAAUF,SAAcG,OAAa;AAC/D,UAAIA,SAAS,KAAKA,QAAQ,KAAKC,QAAQ;AACtC,aAAKH,OAAOE,OAAO,GAAGH,OAAAA;MACvB,OAAO;AACN,aAAKK,KAAKL,OAAAA;MACX;AACA,aAAOA;IACR;EACD;AAGA,MAAI,CAACH,MAAMC,UAAUQ,QAAQ;AAC5BT,UAAMC,UAAUQ,SAAS,SAAUH,OAAa;AAC/C,UAAIA,SAAS,KAAKA,QAAQ,KAAKC,QAAQ;AACtC,eAAO,KAAKH,OAAOE,OAAO,CAAA,EAAG,CAAA;MAC9B;AACA,aAAO;IACR;EACD;AAGA,MAAI,CAACN,MAAMC,UAAUS,eAAe;AACnCV,UAAMC,UAAUS,gBAAgB,SAAUP,SAAY;AACrD,YAAMG,QAAQ,KAAKK,QAAQR,OAAAA;AAC3B,UAAIG,SAAS,GAAG;AACf,eAAO,KAAKF,OAAOE,OAAO,CAAA,EAAG,CAAA;MAC9B;AACA,aAAO;IACR;EACD;AAGA,MAAI,CAACN,MAAMC,UAAUW,UAAU;AAC9BZ,UAAMC,UAAUW,WAAW,SAAUT,SAAY;AAChD,aAAO,KAAKQ,QAAQR,OAAAA,KAAY,IAAI,IAAI;IACzC;EACD;AAGA,MAAI,CAACH,MAAMC,UAAUY,UAAU;AAC9Bb,UAAMC,UAAUY,WAAW,SAAUC,IAA+B;AACnE,UAAIA,IAAI;AACP,eAAO,KAAKC,KAAKD,EAAAA;MAClB;AACA,aAAO,KAAKC,KAAI;IACjB;EACD;AACD;AA1DgBhB;;;ACShB,gBAA+B;AAC/B,IAAAiB,sBAAgC;AAShC,SAASC,iBAAiBC,KAAUC,cAAsBC,cAAsBC,QAAe;AAC9F,QAAMC,eACL,OAAOJ,QAAQ,YAAYA,QAAQ,QAAQ,WAAWA,OAAO,OAAOA,IAAIK,UAAU,WAC/EL,IAAIK,QACJL,KAAKM,WAAWC,OAAOP,GAAAA;AAE3B,MAAIQ,aAAaR,KAAKQ;AACtB,MAAI,CAACA,cAAeL,QAAgBM,aAAaC,WAAWC,oBAAoB;AAC/EH,iBAAcL,OAAeM,YAAYC,UAAUC,mBAAkB;EACtE;AAEA,SAAO;IACNN,OAAOD;IACPQ,MAAMZ,KAAKY,QAAQV;IACnBW,MAAMb,KAAKa;IACXC,QAAQd,KAAKc;IACbC,MAAMf,KAAKe,QAAQd;IACnBe,OAAOhB,KAAKgB;IACZR;EACD;AACD;AApBST;AAsBF,IAAMkB,QAAN,MAAMA;EAhDb,OAgDaA;;;EACLC;EACAf;EACAgB;EACAC,aAA+B;EAEtC,YACCC,OAA+B,CAAC,GAChCC,SAA6B,CAAC,GAC9BC,YAAY,QACZC,cAAc,OACb;AAED,SAAKN,UAAUO,gBAAgBJ,MAAMC,MAAAA;AAGrC,SAAKH,kBAAkB,IAAIO,yBAAeH,WAAWC,WAAAA;AAGrD,SAAKN,QAAQI,OAAOK,UAAU,KAAKR,gBAAgBS,aAAY;AAG/D,SAAKzB,SAAS,IAAI0B,2BAAO,IAAI;AAG7B,SAAK1B,OAAO2B,KAAI;AAGhBC,yBAAAA;EACD;;;;;;;;;;;;EAaAC,IAAIC,QAAgBC,UAAU,KAAMC,WAAW,IAAS;AACvD,SAAKf,aAAa;AAClB,SAAKF,QAAQgB,UAAUE,KAAKC,IAAG,IAAKH;AACpC,SAAKhB,QAAQoB,aAAa;AAE1B,QAAI;AACH,YAAMC,SAAS,KAAKpC,OAAO6B,IAAIC,QAAQE,QAAAA;AACvC,WAAKhB,gBAAgBqB,MAAK;AAE1B,UAAID,WAAW,QAAQA,WAAWE,QAAW;AAC5C,eAAO,KAAKtC,OAAOuC,SAASH,MAAAA;MAC7B;AACA,aAAO;IACR,SAASvC,KAAU;AAClB,WAAKoB,aAAarB,iBAAiBC,KAAKmC,UAAU,WAAW,KAAKhC,MAAM;AACxE,YAAMH;IACP;EACD;;;;;;;;;;;;;EAcA2C,KAAKC,MAAcC,OAAc,CAAA,GAAIX,UAAU,KAAW;AACzD,SAAKd,aAAa;AAClB,SAAKF,QAAQgB,UAAUE,KAAKC,IAAG,IAAKH;AACpC,SAAKhB,QAAQoB,aAAa;AAE1B,QAAI;AACH,YAAMC,SAAS,KAAKpC,OAAOwC,KAAKC,MAAAA,GAASC,IAAAA;AACzC,WAAK1B,gBAAgBqB,MAAK;AAC1B,aAAOD;IACR,SAASvC,KAAU;AAClB,WAAKoB,aAAarB,iBAAiBC,KAAK4C,MAAM,QAAQ,KAAKzC,MAAM;AACjE,YAAMH;IACP;EACD;;;;;;;;;;;EAYA8C,YAAYC,aAAkBZ,WAAmB,IAAU;AAC1D,SAAKf,aAAa;AAElB,QAAI;AACH,UAAI4B;AAIJ,UAAID,uBAAuBE,6BAAS;AACnCD,kBAAUD;MACX,OAAO;AACNC,kBAAU,IAAIC,4BAAQ,CAAA,EAAGC,OAAOC,2BAA2BJ,WAAAA,CAAAA;MAC5D;AAGA,WAAK5C,OAAOM,YAAY2C,QAAQJ,OAAAA;AAChC,WAAK7C,OAAOkD,KAAI;IACjB,SAASrD,KAAU;AAClB,WAAKoB,aAAarB,iBAAiBC,KAAKmC,UAAU,SAAA;AAClD,YAAMnC;IACP;EACD;;;;EAKAsD,gBAAsB;AACrB,SAAKpC,QAAQqC,WAAW;MACvBC,0BAA0B,CAAC;MAC3BC,8BAA8B,CAAC;MAC/BC,uBAAuB,CAAC;MACxBC,wBAAwB,CAAC;MACzBC,yBAAyB,CAAC;IAC3B;EACD;;;;EAKAC,cAAmC;AAClC,WAAO,KAAK3C,QAAQqC,YAAY,CAAC;EAClC;;;;EAKAb,SAASoB,OAAoB;AAC5B,WAAO,KAAK3D,OAAOuC,SAASoB,KAAAA;EAC7B;AACD;AAiBA,SAASX,2BAA2BJ,aAA2D;AAC9F,MAAIgB,yBAAyBhB,WAAAA,GAAc;AAC1C,WAAOA,YAAYC;EACpB;AAEA,SAAOD;AACR;AANSI;AAQT,SAASY,yBAAyBD,OAAc;AAC/C,SACC,OAAOA,UAAU,YACjBA,UAAU,QACV,YAAYA,SACXA,MAA+BE,WAAW,0BAC3C,aAAaF;AAEf;AARSC;;;AH1MT,IAAAE,sBAAgC;","names":["_baseMeta","round","x","Math","floor","ceil","abs","min","y","max","sqrt","pow","sin","cos","tan","asin","acos","atan","atan2","sind","PI","cosd","tand","asind","acosd","atand","atan2d","log","exp","random","Random","true","false","_defaultPrint","text","console","createMetaFunctions","customPrint","print","createVMContext","meta","global","fullMeta","local","object","breakable","continuable","returnable","stack_size","timeout","Date","now","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","setupArrayExtensions","Array","prototype","insert","element","splice","insertAt","index","length","push","remove","removeElement","indexOf","contains","sortList","fn","sort","import_lootiscript","extractErrorInfo","err","fallbackFile","fallbackType","runner","errorMessage","error","message","String","stackTrace","main_thread","processor","generateStackTrace","type","line","column","file","stack","L8BVM","context","storage_service","error_info","meta","global","namespace","preserve_ls","createVMContext","StorageService","storage","getInterface","Runner","init","setupArrayExtensions","run","source","timeout","filename","Date","now","stack_size","result","check","undefined","toString","call","name","args","loadRoutine","routineData","routine","Routine","import","normalizeSerializedRoutine","addCall","tick","clearWarnings","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","getWarnings","value","isCompiledModuleArtifact","format","import_lootiscript"]}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context.ts","../src/extensions.ts","../src/l8bvm.ts","../src/index.ts"],"sourcesContent":["/**\n * VM Context creation utilities\n */\n\nimport { Random } from \"@al8b/lootiscript\";\nimport type { GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n// Shared math lambdas — allocated once, reused across all VM instances\nconst _baseMeta = {\n\tround: (x: number) => Math.round(x),\n\tfloor: (x: number) => Math.floor(x),\n\tceil: (x: number) => Math.ceil(x),\n\tabs: (x: number) => Math.abs(x),\n\tmin: (x: number, y: number) => Math.min(x, y),\n\tmax: (x: number, y: number) => Math.max(x, y),\n\tsqrt: (x: number) => Math.sqrt(x),\n\tpow: (x: number, y: number) => x ** y,\n\tsin: (x: number) => Math.sin(x),\n\tcos: (x: number) => Math.cos(x),\n\ttan: (x: number) => Math.tan(x),\n\tasin: (x: number) => Math.asin(x),\n\tacos: (x: number) => Math.acos(x),\n\tatan: (x: number) => Math.atan(x),\n\tatan2: (y: number, x: number) => Math.atan2(y, x),\n\tsind: (x: number) => Math.sin((x / 180) * Math.PI),\n\tcosd: (x: number) => Math.cos((x / 180) * Math.PI),\n\ttand: (x: number) => Math.tan((x / 180) * Math.PI),\n\tasind: (x: number) => (Math.asin(x) * 180) / Math.PI,\n\tacosd: (x: number) => (Math.acos(x) * 180) / Math.PI,\n\tatand: (x: number) => (Math.atan(x) * 180) / Math.PI,\n\tatan2d: (y: number, x: number) => (Math.atan2(y, x) * 180) / Math.PI,\n\tlog: (x: number) => Math.log(x),\n\texp: (x: number) => Math.exp(x),\n\trandom: new Random(0),\n\tPI: Math.PI,\n\ttrue: 1 as const,\n\tfalse: 0 as const,\n};\n\nconst _defaultPrint = (text: any) => console.log(text);\n\n/**\n * Create meta functions (built-in functions)\n */\nexport function createMetaFunctions(customPrint?: (text: any) => void): MetaFunctions {\n\treturn {\n\t\t..._baseMeta,\n\t\tprint: customPrint ?? _defaultPrint,\n\t};\n}\n\n/**\n * Create VM context\n */\nexport function createVMContext(meta: Partial<MetaFunctions>, global: Partial<GlobalAPI>): VMContext {\n\tconst fullMeta: MetaFunctions = {\n\t\t..._baseMeta,\n\t\tprint: meta.print ?? _defaultPrint,\n\t\t...meta,\n\t};\n\n\treturn {\n\t\tmeta: fullMeta as MetaFunctions,\n\t\tglobal: global as GlobalAPI,\n\t\tlocal: global,\n\t\tobject: global,\n\t\tbreakable: 0,\n\t\tcontinuable: 0,\n\t\treturnable: 0,\n\t\tstack_size: 0,\n\t\ttimeout: Date.now() + 3000,\n\t\twarnings: {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t},\n\t};\n}\n","/**\n * Array extensions\n */\n\n/**\n * Setup array extensions\n */\nexport function setupArrayExtensions(): void {\n\t// Insert element at beginning of array (returns the inserted element)\n\tif (!Array.prototype.insert) {\n\t\tArray.prototype.insert = function (element: any) {\n\t\t\tthis.splice(0, 0, element);\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Insert element at specific index (returns the inserted element)\n\tif (!Array.prototype.insertAt) {\n\t\tArray.prototype.insertAt = function (element: any, index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\tthis.splice(index, 0, element);\n\t\t\t} else {\n\t\t\t\tthis.push(element);\n\t\t\t}\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Remove element at index (returns removed element or 0 if out of bounds)\n\tif (!Array.prototype.remove) {\n\t\tArray.prototype.remove = function (index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Remove first occurrence of element (returns removed element or 0 if not found)\n\tif (!Array.prototype.removeElement) {\n\t\tArray.prototype.removeElement = function (element: any) {\n\t\t\tconst index = this.indexOf(element);\n\t\t\tif (index >= 0) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Check if array contains element (returns 1 if found, 0 if not found)\n\tif (!Array.prototype.contains) {\n\t\tArray.prototype.contains = function (element: any) {\n\t\t\treturn this.indexOf(element) >= 0 ? 1 : 0;\n\t\t};\n\t}\n\n\t// Sort array with optional comparator function\n\tif (!Array.prototype.sortList) {\n\t\tArray.prototype.sortList = function (fn?: (a: any, b: any) => number) {\n\t\t\tif (fn) {\n\t\t\t\treturn this.sort(fn);\n\t\t\t}\n\t\t\treturn this.sort();\n\t\t};\n\t}\n}\n\n// TypeScript type declarations for Array prototype extensions\ndeclare global {\n\tinterface Array<T> {\n\t\tinsert(element: T): T;\n\t\tinsertAt(element: T, index: number): T;\n\t\tremove(index: number): T | 0;\n\t\tremoveElement(element: T): T | 0;\n\t\tcontains(element: T): 0 | 1;\n\t\tsortList(fn?: (a: T, b: T) => number): T[];\n\t}\n}\n","/**\n * L8BVM - Virtual Machine wrapper for lootiscript\n *\n * High-level interface for the LootiScript virtual machine.\n * Wraps the core Compiler, Processor, and Runner into a usable engine component.\n * Handles context creation, storage persistence, and error formatting.\n *\n * Responsibilities:\n * - Create and manage VM execution context\n * - Provide clean API for running code and calling functions\n * - Handle storage persistence\n * - Format and normalize runtime errors\n *\n * @module vm\n */\n\nimport type { CompiledModuleArtifact, SerializedRoutineData } from \"@al8b/framework-shared\";\nimport { StorageService } from \"@al8b/io\";\nimport { Routine, Runner } from \"@al8b/lootiscript\";\nimport { createVMContext } from \"./context\";\nimport { setupArrayExtensions } from \"./extensions\";\nimport type { ErrorInfo, GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n/**\n * Extract normalized ErrorInfo from a caught exception.\n * Centralizes the error-parsing logic shared across run(), call(), and loadRoutine().\n */\nfunction extractErrorInfo(err: any, fallbackFile: string, fallbackType: string, runner?: Runner): ErrorInfo {\n\tconst errorMessage =\n\t\ttypeof err === \"object\" && err !== null && \"error\" in err && typeof err.error === \"string\"\n\t\t\t? err.error\n\t\t\t: err?.message ?? String(err);\n\n\tlet stackTrace = err?.stackTrace;\n\tif (!stackTrace && (runner as any)?.main_thread?.processor?.generateStackTrace) {\n\t\tstackTrace = (runner as any).main_thread.processor.generateStackTrace();\n\t}\n\n\treturn {\n\t\terror: errorMessage,\n\t\ttype: err?.type ?? fallbackType,\n\t\tline: err?.line,\n\t\tcolumn: err?.column,\n\t\tfile: err?.file ?? fallbackFile,\n\t\tstack: err?.stack,\n\t\tstackTrace,\n\t};\n}\n\nexport class L8BVM {\n\tpublic context: VMContext;\n\tpublic runner: Runner;\n\tpublic storage_service: StorageService;\n\tpublic error_info: ErrorInfo | null = null;\n\n\tconstructor(\n\t\tmeta: Partial<MetaFunctions> = {},\n\t\tglobal: Partial<GlobalAPI> = {},\n\t\tnamespace = \"/l8b\",\n\t\tpreserve_ls = false,\n\t) {\n\t\t// Initialize VM execution context with meta functions and global API\n\t\tthis.context = createVMContext(meta, global);\n\n\t\t// Initialize storage service for persistent data (localStorage/sessionStorage)\n\t\tthis.storage_service = new StorageService(namespace, preserve_ls);\n\n\t\t// Inject storage API into global scope for LootiScript access\n\t\tthis.context.global.storage = this.storage_service.getInterface();\n\n\t\t// Create Runner instance with reference to this VM for bidirectional communication\n\t\tthis.runner = new Runner(this as any);\n\n\t\t// Initialize Runner and create main execution thread\n\t\tthis.runner.init();\n\n\t\t// Add custom array methods to Array.prototype for LootiScript\n\t\tsetupArrayExtensions();\n\t}\n\n\t/**\n\t * Run source code\n\t *\n\t * Compiles and executes a string of LootiScript code.\n\t *\n\t * @param {string} source - The source code to execute\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @param {string} [filename=\"\"] - Filename for error reporting\n\t * @returns {any} The result of the last statement execution\n\t * @throws {ErrorInfo} If compilation or execution fails\n\t */\n\trun(source: string, timeout = 3000, filename = \"\"): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.run(source, filename);\n\t\t\tthis.storage_service.check();\n\n\t\t\tif (result !== null && result !== undefined) {\n\t\t\t\treturn this.runner.toString(result);\n\t\t\t}\n\t\t\treturn null;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"runtime\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Call a global function\n\t *\n\t * Executes a specific function defined in the global scope.\n\t * Useful for game loop hooks (update, draw) or event handlers.\n\t *\n\t * @param {string} name - Name of the function to call\n\t * @param {any[]} [args=[]] - Arguments to pass to the function\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @returns {any} The return value of the function\n\t * @throws {ErrorInfo} If the function doesn't exist or execution fails\n\t */\n\tcall(name: string, args: any[] = [], timeout = 3000): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.call(name, ...args);\n\t\t\tthis.storage_service.check();\n\t\t\treturn result;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, name, \"call\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Load a pre-compiled routine (for production builds)\n\t *\n\t * Loads bytecode directly into the VM, bypassing the compilation step.\n\t * Used in production to improve startup time and obfuscate source.\n\t *\n\t * @param {any} routineData - Either a Routine instance or serialized JSON\n\t * @param {string} [filename=\"\"] - Name of the file for error reporting\n\t * @throws {ErrorInfo} If loading fails\n\t */\n\tloadRoutine(routineData: any, filename: string = \"\"): void {\n\t\tthis.error_info = null;\n\n\t\ttry {\n\t\t\tlet routine: Routine;\n\n\t\t\t// Handle both Routine instances and serialized routine data\n\t\t\t// Serialized data needs to be imported first\n\t\t\tif (routineData instanceof Routine) {\n\t\t\t\troutine = routineData;\n\t\t\t} else {\n\t\t\t\troutine = new Routine(0).import(normalizeSerializedRoutine(routineData));\n\t\t\t}\n\n\t\t\t// Add to main thread for execution\n\t\t\tthis.runner.main_thread.addCall(routine);\n\t\t\tthis.runner.tick();\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"compile\");\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Clear warnings\n\t */\n\tclearWarnings(): void {\n\t\tthis.context.warnings = {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t};\n\t}\n\n\t/**\n\t * Get warnings\n\t */\n\tgetWarnings(): Record<string, any> {\n\t\treturn this.context.warnings || {};\n\t}\n\n\t/**\n\t * Convert value to string (for printing)\n\t */\n\ttoString(value: any): string {\n\t\treturn this.runner.toString(value);\n\t}\n}\n\nfunction normalizeSerializedRoutine(routineData: CompiledModuleArtifact | SerializedRoutineData): SerializedRoutineData {\n\tif (isCompiledModuleArtifact(routineData)) {\n\t\treturn routineData.routine;\n\t}\n\n\treturn routineData;\n}\n\nfunction isCompiledModuleArtifact(value: unknown): value is CompiledModuleArtifact {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"format\" in value &&\n\t\t(value as { format?: unknown }).format === \"l8b-compiled-routine\" &&\n\t\t\"routine\" in value\n\t);\n}\n","// VM public surface — StorageService is intentionally NOT re-exported here.\n// Import it directly from \"@al8b/io\" if you need it.\nexport { createMetaFunctions, createVMContext } from \"./context\";\nexport { setupArrayExtensions } from \"./extensions\";\nexport { L8BVM } from \"./l8bvm\";\nexport type {\n\tErrorInfo,\n\tGlobalAPI,\n\tMetaFunctions,\n\tPlayerAPI,\n\tSystemAPI,\n\tVMContext,\n\tVMWarnings,\n\tWarningInfo,\n} from \"./types\";\n\n// Re-export language primitives that runtime and host code legitimately need.\n// This keeps runtime from bypassing the vm layer and importing lootiscript directly.\nexport { Random, Routine } from \"@al8b/lootiscript\";\n"],"mappings":"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","names":["Random","_baseMeta","round","x","Math","floor","ceil","abs","min","y","max","sqrt","pow","sin","cos","tan","asin","acos","atan","atan2","sind","PI","cosd","tand","asind","acosd","atand","atan2d","log","exp","random","Random","true","false","_defaultPrint","text","console","createMetaFunctions","customPrint","print","createVMContext","meta","global","fullMeta","local","object","breakable","continuable","returnable","stack_size","timeout","Date","now","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","setupArrayExtensions","Array","prototype","insert","element","splice","insertAt","index","length","push","remove","removeElement","indexOf","contains","sortList","fn","sort","StorageService","Routine","Runner","extractErrorInfo","err","fallbackFile","fallbackType","runner","errorMessage","error","message","String","stackTrace","main_thread","processor","generateStackTrace","type","line","column","file","stack","L8BVM","context","storage_service","error_info","meta","global","namespace","preserve_ls","createVMContext","StorageService","storage","getInterface","Runner","init","setupArrayExtensions","run","source","timeout","filename","Date","now","stack_size","result","check","undefined","toString","call","name","args","loadRoutine","routineData","routine","Routine","import","normalizeSerializedRoutine","addCall","tick","clearWarnings","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","getWarnings","value","isCompiledModuleArtifact","format","Random","Routine"]}
|
|
1
|
+
{"version":3,"sources":["../src/context.ts","../src/extensions.ts","../src/l8bvm.ts","../src/index.ts"],"sourcesContent":["/**\n * VM Context creation utilities\n */\n\nimport { Random } from \"@al8b/lootiscript\";\nimport type { GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n// Shared math lambdas — allocated once, reused across all VM instances\nconst _baseMeta = {\n\tround: (x: number) => Math.round(x),\n\tfloor: (x: number) => Math.floor(x),\n\tceil: (x: number) => Math.ceil(x),\n\tabs: (x: number) => Math.abs(x),\n\tmin: (x: number, y: number) => Math.min(x, y),\n\tmax: (x: number, y: number) => Math.max(x, y),\n\tsqrt: (x: number) => Math.sqrt(x),\n\tpow: (x: number, y: number) => x ** y,\n\tsin: (x: number) => Math.sin(x),\n\tcos: (x: number) => Math.cos(x),\n\ttan: (x: number) => Math.tan(x),\n\tasin: (x: number) => Math.asin(x),\n\tacos: (x: number) => Math.acos(x),\n\tatan: (x: number) => Math.atan(x),\n\tatan2: (y: number, x: number) => Math.atan2(y, x),\n\tsind: (x: number) => Math.sin((x / 180) * Math.PI),\n\tcosd: (x: number) => Math.cos((x / 180) * Math.PI),\n\ttand: (x: number) => Math.tan((x / 180) * Math.PI),\n\tasind: (x: number) => (Math.asin(x) * 180) / Math.PI,\n\tacosd: (x: number) => (Math.acos(x) * 180) / Math.PI,\n\tatand: (x: number) => (Math.atan(x) * 180) / Math.PI,\n\tatan2d: (y: number, x: number) => (Math.atan2(y, x) * 180) / Math.PI,\n\tlog: (x: number) => Math.log(x),\n\texp: (x: number) => Math.exp(x),\n\trandom: new Random(0),\n\tPI: Math.PI,\n\ttrue: 1 as const,\n\tfalse: 0 as const,\n};\n\nconst _defaultPrint = (text: any) => console.log(text);\n\n/**\n * Create meta functions (built-in functions)\n */\nexport function createMetaFunctions(customPrint?: (text: any) => void): MetaFunctions {\n\treturn {\n\t\t..._baseMeta,\n\t\tprint: customPrint ?? _defaultPrint,\n\t};\n}\n\n/**\n * Create VM context\n */\nexport function createVMContext(meta: Partial<MetaFunctions>, global: Partial<GlobalAPI>): VMContext {\n\tconst fullMeta: MetaFunctions = {\n\t\t..._baseMeta,\n\t\tprint: meta.print ?? _defaultPrint,\n\t\t...meta,\n\t};\n\n\treturn {\n\t\tmeta: fullMeta as MetaFunctions,\n\t\tglobal: global as GlobalAPI,\n\t\tlocal: global,\n\t\tobject: global,\n\t\tbreakable: 0,\n\t\tcontinuable: 0,\n\t\treturnable: 0,\n\t\tstack_size: 0,\n\t\ttimeout: Date.now() + 3000,\n\t\twarnings: {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t},\n\t};\n}\n","/**\n * Array extensions\n */\n\n/**\n * Setup array extensions\n */\nexport function setupArrayExtensions(): void {\n\t// Insert element at beginning of array (returns the inserted element)\n\tif (!Array.prototype.insert) {\n\t\tArray.prototype.insert = function (element: any) {\n\t\t\tthis.splice(0, 0, element);\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Insert element at specific index (returns the inserted element)\n\tif (!Array.prototype.insertAt) {\n\t\tArray.prototype.insertAt = function (element: any, index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\tthis.splice(index, 0, element);\n\t\t\t} else {\n\t\t\t\tthis.push(element);\n\t\t\t}\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Remove element at index (returns removed element or 0 if out of bounds)\n\tif (!Array.prototype.remove) {\n\t\tArray.prototype.remove = function (index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Remove first occurrence of element (returns removed element or 0 if not found)\n\tif (!Array.prototype.removeElement) {\n\t\tArray.prototype.removeElement = function (element: any) {\n\t\t\tconst index = this.indexOf(element);\n\t\t\tif (index >= 0) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Check if array contains element (returns 1 if found, 0 if not found)\n\tif (!Array.prototype.contains) {\n\t\tArray.prototype.contains = function (element: any) {\n\t\t\treturn this.indexOf(element) >= 0 ? 1 : 0;\n\t\t};\n\t}\n\n\t// Sort array with optional comparator function\n\tif (!Array.prototype.sortList) {\n\t\tArray.prototype.sortList = function (fn?: (a: any, b: any) => number) {\n\t\t\tif (fn) {\n\t\t\t\treturn this.sort(fn);\n\t\t\t}\n\t\t\treturn this.sort();\n\t\t};\n\t}\n}\n\n// TypeScript type declarations for Array prototype extensions\ndeclare global {\n\tinterface Array<T> {\n\t\tinsert(element: T): T;\n\t\tinsertAt(element: T, index: number): T;\n\t\tremove(index: number): T | 0;\n\t\tremoveElement(element: T): T | 0;\n\t\tcontains(element: T): 0 | 1;\n\t\tsortList(fn?: (a: T, b: T) => number): T[];\n\t}\n}\n","/**\n * L8BVM - Virtual Machine wrapper for lootiscript\n *\n * High-level interface for the LootiScript virtual machine.\n * Wraps the core Compiler, Processor, and Runner into a usable engine component.\n * Handles context creation, storage persistence, and error formatting.\n *\n * Responsibilities:\n * - Create and manage VM execution context\n * - Provide clean API for running code and calling functions\n * - Handle storage persistence\n * - Format and normalize runtime errors\n *\n * @module vm\n */\n\nimport { StorageService } from \"@al8b/io\";\nimport { Routine, Runner } from \"@al8b/lootiscript\";\nimport { createVMContext } from \"./context\";\nimport { setupArrayExtensions } from \"./extensions\";\nimport type { ErrorInfo, GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n/**\n * Extract normalized ErrorInfo from a caught exception.\n * Centralizes the error-parsing logic shared across run(), call(), and loadRoutine().\n */\nfunction extractErrorInfo(err: any, fallbackFile: string, fallbackType: string, runner?: Runner): ErrorInfo {\n\tconst errorMessage =\n\t\ttypeof err === \"object\" && err !== null && \"error\" in err && typeof err.error === \"string\"\n\t\t\t? err.error\n\t\t\t: err?.message ?? String(err);\n\n\tlet stackTrace = err?.stackTrace;\n\tif (!stackTrace && (runner as any)?.main_thread?.processor?.generateStackTrace) {\n\t\tstackTrace = (runner as any).main_thread.processor.generateStackTrace();\n\t}\n\n\treturn {\n\t\terror: errorMessage,\n\t\ttype: err?.type ?? fallbackType,\n\t\tline: err?.line,\n\t\tcolumn: err?.column,\n\t\tfile: err?.file ?? fallbackFile,\n\t\tstack: err?.stack,\n\t\tstackTrace,\n\t};\n}\n\nexport class L8BVM {\n\tpublic context: VMContext;\n\tpublic runner: Runner;\n\tpublic storage_service: StorageService;\n\tpublic error_info: ErrorInfo | null = null;\n\n\tconstructor(\n\t\tmeta: Partial<MetaFunctions> = {},\n\t\tglobal: Partial<GlobalAPI> = {},\n\t\tnamespace = \"/l8b\",\n\t\tpreserve_ls = false,\n\t) {\n\t\t// Initialize VM execution context with meta functions and global API\n\t\tthis.context = createVMContext(meta, global);\n\n\t\t// Initialize storage service for persistent data (localStorage/sessionStorage)\n\t\tthis.storage_service = new StorageService(namespace, preserve_ls);\n\n\t\t// Inject storage API into global scope for LootiScript access\n\t\tthis.context.global.storage = this.storage_service.getInterface();\n\n\t\t// Create Runner instance with reference to this VM for bidirectional communication\n\t\tthis.runner = new Runner(this as any);\n\n\t\t// Initialize Runner and create main execution thread\n\t\tthis.runner.init();\n\n\t\t// Add custom array methods to Array.prototype for LootiScript\n\t\tsetupArrayExtensions();\n\t}\n\n\t/**\n\t * Run source code\n\t *\n\t * Compiles and executes a string of LootiScript code.\n\t *\n\t * @param {string} source - The source code to execute\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @param {string} [filename=\"\"] - Filename for error reporting\n\t * @returns {any} The result of the last statement execution\n\t * @throws {ErrorInfo} If compilation or execution fails\n\t */\n\trun(source: string, timeout = 3000, filename = \"\"): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.run(source, filename);\n\t\t\tthis.storage_service.check();\n\n\t\t\tif (result !== null && result !== undefined) {\n\t\t\t\treturn this.runner.toString(result);\n\t\t\t}\n\t\t\treturn null;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"runtime\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Call a global function\n\t *\n\t * Executes a specific function defined in the global scope.\n\t * Useful for game loop hooks (update, draw) or event handlers.\n\t *\n\t * @param {string} name - Name of the function to call\n\t * @param {any[]} [args=[]] - Arguments to pass to the function\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @returns {any} The return value of the function\n\t * @throws {ErrorInfo} If the function doesn't exist or execution fails\n\t */\n\tcall(name: string, args: any[] = [], timeout = 3000): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.call(name, ...args);\n\t\t\tthis.storage_service.check();\n\t\t\treturn result;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, name, \"call\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Load a pre-compiled routine (for production builds)\n\t *\n\t * Loads bytecode directly into the VM, bypassing the compilation step.\n\t * Used in production to improve startup time and obfuscate source.\n\t *\n\t * @param {any} routineData - Either a Routine instance or serialized JSON\n\t * @param {string} [filename=\"\"] - Name of the file for error reporting\n\t * @throws {ErrorInfo} If loading fails\n\t */\n\tloadRoutine(routineData: any, filename: string = \"\"): void {\n\t\tthis.error_info = null;\n\n\t\ttry {\n\t\t\tlet routine: Routine;\n\n\t\t\t// Handle both Routine instances and serialized routine data\n\t\t\t// Serialized data needs to be imported first\n\t\t\tif (routineData instanceof Routine) {\n\t\t\t\troutine = routineData;\n\t\t\t} else {\n\t\t\t\troutine = new Routine(0).import(normalizeSerializedRoutine(routineData));\n\t\t\t}\n\n\t\t\t// Add to main thread for execution\n\t\t\tthis.runner.main_thread.addCall(routine);\n\t\t\tthis.runner.tick();\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"compile\");\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Clear warnings\n\t */\n\tclearWarnings(): void {\n\t\tthis.context.warnings = {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t};\n\t}\n\n\t/**\n\t * Get warnings\n\t */\n\tgetWarnings(): Record<string, any> {\n\t\treturn this.context.warnings || {};\n\t}\n\n\t/**\n\t * Convert value to string (for printing)\n\t */\n\ttoString(value: any): string {\n\t\treturn this.runner.toString(value);\n\t}\n}\n\n// Inline types stub for @al8b/framework-shared\ninterface CompiledModuleArtifact {\n\tformat: \"l8b-compiled-routine\";\n\troutine: SerializedRoutineData;\n}\ntype SerializedRoutineData = {\n\tnum_args: number;\n\tops: number[];\n\targs: any[];\n\timport_refs: any[];\n\timport_values: any[];\n\timport_self: number;\n\tlocals_size?: number;\n};\n\nfunction normalizeSerializedRoutine(routineData: CompiledModuleArtifact | SerializedRoutineData): SerializedRoutineData {\n\tif (isCompiledModuleArtifact(routineData)) {\n\t\treturn routineData.routine;\n\t}\n\n\treturn routineData;\n}\n\nfunction isCompiledModuleArtifact(value: unknown): value is CompiledModuleArtifact {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"format\" in value &&\n\t\t(value as { format?: unknown }).format === \"l8b-compiled-routine\" &&\n\t\t\"routine\" in value\n\t);\n}\n","// VM public surface — StorageService is intentionally NOT re-exported here.\n// Import it directly from \"@al8b/io\" if you need it.\nexport { createMetaFunctions, createVMContext } from \"./context\";\nexport { setupArrayExtensions } from \"./extensions\";\nexport { L8BVM } from \"./l8bvm\";\nexport type {\n\tErrorInfo,\n\tGlobalAPI,\n\tMetaFunctions,\n\tPlayerAPI,\n\tSystemAPI,\n\tVMContext,\n\tVMWarnings,\n\tWarningInfo,\n} from \"./types\";\n\n// Re-export language primitives that runtime and host code legitimately need.\n// This keeps runtime from bypassing the vm layer and importing lootiscript directly.\nexport { Random, Routine } from \"@al8b/lootiscript\";\n"],"mappings":"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","names":["Random","_baseMeta","round","x","Math","floor","ceil","abs","min","y","max","sqrt","pow","sin","cos","tan","asin","acos","atan","atan2","sind","PI","cosd","tand","asind","acosd","atand","atan2d","log","exp","random","Random","true","false","_defaultPrint","text","console","createMetaFunctions","customPrint","print","createVMContext","meta","global","fullMeta","local","object","breakable","continuable","returnable","stack_size","timeout","Date","now","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","setupArrayExtensions","Array","prototype","insert","element","splice","insertAt","index","length","push","remove","removeElement","indexOf","contains","sortList","fn","sort","StorageService","Routine","Runner","extractErrorInfo","err","fallbackFile","fallbackType","runner","errorMessage","error","message","String","stackTrace","main_thread","processor","generateStackTrace","type","line","column","file","stack","L8BVM","context","storage_service","error_info","meta","global","namespace","preserve_ls","createVMContext","StorageService","storage","getInterface","Runner","init","setupArrayExtensions","run","source","timeout","filename","Date","now","stack_size","result","check","undefined","toString","call","name","args","loadRoutine","routineData","routine","Routine","import","normalizeSerializedRoutine","addCall","tick","clearWarnings","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","getWarnings","value","isCompiledModuleArtifact","format","Random","Routine"]}
|
package/dist/l8bvm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/l8bvm.ts","../src/context.ts","../src/extensions.ts"],"sourcesContent":["/**\n * L8BVM - Virtual Machine wrapper for lootiscript\n *\n * High-level interface for the LootiScript virtual machine.\n * Wraps the core Compiler, Processor, and Runner into a usable engine component.\n * Handles context creation, storage persistence, and error formatting.\n *\n * Responsibilities:\n * - Create and manage VM execution context\n * - Provide clean API for running code and calling functions\n * - Handle storage persistence\n * - Format and normalize runtime errors\n *\n * @module vm\n */\n\nimport type { CompiledModuleArtifact, SerializedRoutineData } from \"@al8b/framework-shared\";\nimport { StorageService } from \"@al8b/io\";\nimport { Routine, Runner } from \"@al8b/lootiscript\";\nimport { createVMContext } from \"./context\";\nimport { setupArrayExtensions } from \"./extensions\";\nimport type { ErrorInfo, GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n/**\n * Extract normalized ErrorInfo from a caught exception.\n * Centralizes the error-parsing logic shared across run(), call(), and loadRoutine().\n */\nfunction extractErrorInfo(err: any, fallbackFile: string, fallbackType: string, runner?: Runner): ErrorInfo {\n\tconst errorMessage =\n\t\ttypeof err === \"object\" && err !== null && \"error\" in err && typeof err.error === \"string\"\n\t\t\t? err.error\n\t\t\t: err?.message ?? String(err);\n\n\tlet stackTrace = err?.stackTrace;\n\tif (!stackTrace && (runner as any)?.main_thread?.processor?.generateStackTrace) {\n\t\tstackTrace = (runner as any).main_thread.processor.generateStackTrace();\n\t}\n\n\treturn {\n\t\terror: errorMessage,\n\t\ttype: err?.type ?? fallbackType,\n\t\tline: err?.line,\n\t\tcolumn: err?.column,\n\t\tfile: err?.file ?? fallbackFile,\n\t\tstack: err?.stack,\n\t\tstackTrace,\n\t};\n}\n\nexport class L8BVM {\n\tpublic context: VMContext;\n\tpublic runner: Runner;\n\tpublic storage_service: StorageService;\n\tpublic error_info: ErrorInfo | null = null;\n\n\tconstructor(\n\t\tmeta: Partial<MetaFunctions> = {},\n\t\tglobal: Partial<GlobalAPI> = {},\n\t\tnamespace = \"/l8b\",\n\t\tpreserve_ls = false,\n\t) {\n\t\t// Initialize VM execution context with meta functions and global API\n\t\tthis.context = createVMContext(meta, global);\n\n\t\t// Initialize storage service for persistent data (localStorage/sessionStorage)\n\t\tthis.storage_service = new StorageService(namespace, preserve_ls);\n\n\t\t// Inject storage API into global scope for LootiScript access\n\t\tthis.context.global.storage = this.storage_service.getInterface();\n\n\t\t// Create Runner instance with reference to this VM for bidirectional communication\n\t\tthis.runner = new Runner(this as any);\n\n\t\t// Initialize Runner and create main execution thread\n\t\tthis.runner.init();\n\n\t\t// Add custom array methods to Array.prototype for LootiScript\n\t\tsetupArrayExtensions();\n\t}\n\n\t/**\n\t * Run source code\n\t *\n\t * Compiles and executes a string of LootiScript code.\n\t *\n\t * @param {string} source - The source code to execute\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @param {string} [filename=\"\"] - Filename for error reporting\n\t * @returns {any} The result of the last statement execution\n\t * @throws {ErrorInfo} If compilation or execution fails\n\t */\n\trun(source: string, timeout = 3000, filename = \"\"): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.run(source, filename);\n\t\t\tthis.storage_service.check();\n\n\t\t\tif (result !== null && result !== undefined) {\n\t\t\t\treturn this.runner.toString(result);\n\t\t\t}\n\t\t\treturn null;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"runtime\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Call a global function\n\t *\n\t * Executes a specific function defined in the global scope.\n\t * Useful for game loop hooks (update, draw) or event handlers.\n\t *\n\t * @param {string} name - Name of the function to call\n\t * @param {any[]} [args=[]] - Arguments to pass to the function\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @returns {any} The return value of the function\n\t * @throws {ErrorInfo} If the function doesn't exist or execution fails\n\t */\n\tcall(name: string, args: any[] = [], timeout = 3000): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.call(name, ...args);\n\t\t\tthis.storage_service.check();\n\t\t\treturn result;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, name, \"call\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Load a pre-compiled routine (for production builds)\n\t *\n\t * Loads bytecode directly into the VM, bypassing the compilation step.\n\t * Used in production to improve startup time and obfuscate source.\n\t *\n\t * @param {any} routineData - Either a Routine instance or serialized JSON\n\t * @param {string} [filename=\"\"] - Name of the file for error reporting\n\t * @throws {ErrorInfo} If loading fails\n\t */\n\tloadRoutine(routineData: any, filename: string = \"\"): void {\n\t\tthis.error_info = null;\n\n\t\ttry {\n\t\t\tlet routine: Routine;\n\n\t\t\t// Handle both Routine instances and serialized routine data\n\t\t\t// Serialized data needs to be imported first\n\t\t\tif (routineData instanceof Routine) {\n\t\t\t\troutine = routineData;\n\t\t\t} else {\n\t\t\t\troutine = new Routine(0).import(normalizeSerializedRoutine(routineData));\n\t\t\t}\n\n\t\t\t// Add to main thread for execution\n\t\t\tthis.runner.main_thread.addCall(routine);\n\t\t\tthis.runner.tick();\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"compile\");\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Clear warnings\n\t */\n\tclearWarnings(): void {\n\t\tthis.context.warnings = {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t};\n\t}\n\n\t/**\n\t * Get warnings\n\t */\n\tgetWarnings(): Record<string, any> {\n\t\treturn this.context.warnings || {};\n\t}\n\n\t/**\n\t * Convert value to string (for printing)\n\t */\n\ttoString(value: any): string {\n\t\treturn this.runner.toString(value);\n\t}\n}\n\nfunction normalizeSerializedRoutine(routineData: CompiledModuleArtifact | SerializedRoutineData): SerializedRoutineData {\n\tif (isCompiledModuleArtifact(routineData)) {\n\t\treturn routineData.routine;\n\t}\n\n\treturn routineData;\n}\n\nfunction isCompiledModuleArtifact(value: unknown): value is CompiledModuleArtifact {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"format\" in value &&\n\t\t(value as { format?: unknown }).format === \"l8b-compiled-routine\" &&\n\t\t\"routine\" in value\n\t);\n}\n","/**\n * VM Context creation utilities\n */\n\nimport { Random } from \"@al8b/lootiscript\";\nimport type { GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n// Shared math lambdas — allocated once, reused across all VM instances\nconst _baseMeta = {\n\tround: (x: number) => Math.round(x),\n\tfloor: (x: number) => Math.floor(x),\n\tceil: (x: number) => Math.ceil(x),\n\tabs: (x: number) => Math.abs(x),\n\tmin: (x: number, y: number) => Math.min(x, y),\n\tmax: (x: number, y: number) => Math.max(x, y),\n\tsqrt: (x: number) => Math.sqrt(x),\n\tpow: (x: number, y: number) => x ** y,\n\tsin: (x: number) => Math.sin(x),\n\tcos: (x: number) => Math.cos(x),\n\ttan: (x: number) => Math.tan(x),\n\tasin: (x: number) => Math.asin(x),\n\tacos: (x: number) => Math.acos(x),\n\tatan: (x: number) => Math.atan(x),\n\tatan2: (y: number, x: number) => Math.atan2(y, x),\n\tsind: (x: number) => Math.sin((x / 180) * Math.PI),\n\tcosd: (x: number) => Math.cos((x / 180) * Math.PI),\n\ttand: (x: number) => Math.tan((x / 180) * Math.PI),\n\tasind: (x: number) => (Math.asin(x) * 180) / Math.PI,\n\tacosd: (x: number) => (Math.acos(x) * 180) / Math.PI,\n\tatand: (x: number) => (Math.atan(x) * 180) / Math.PI,\n\tatan2d: (y: number, x: number) => (Math.atan2(y, x) * 180) / Math.PI,\n\tlog: (x: number) => Math.log(x),\n\texp: (x: number) => Math.exp(x),\n\trandom: new Random(0),\n\tPI: Math.PI,\n\ttrue: 1 as const,\n\tfalse: 0 as const,\n};\n\nconst _defaultPrint = (text: any) => console.log(text);\n\n/**\n * Create meta functions (built-in functions)\n */\nexport function createMetaFunctions(customPrint?: (text: any) => void): MetaFunctions {\n\treturn {\n\t\t..._baseMeta,\n\t\tprint: customPrint ?? _defaultPrint,\n\t};\n}\n\n/**\n * Create VM context\n */\nexport function createVMContext(meta: Partial<MetaFunctions>, global: Partial<GlobalAPI>): VMContext {\n\tconst fullMeta: MetaFunctions = {\n\t\t..._baseMeta,\n\t\tprint: meta.print ?? _defaultPrint,\n\t\t...meta,\n\t};\n\n\treturn {\n\t\tmeta: fullMeta as MetaFunctions,\n\t\tglobal: global as GlobalAPI,\n\t\tlocal: global,\n\t\tobject: global,\n\t\tbreakable: 0,\n\t\tcontinuable: 0,\n\t\treturnable: 0,\n\t\tstack_size: 0,\n\t\ttimeout: Date.now() + 3000,\n\t\twarnings: {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t},\n\t};\n}\n","/**\n * Array extensions\n */\n\n/**\n * Setup array extensions\n */\nexport function setupArrayExtensions(): void {\n\t// Insert element at beginning of array (returns the inserted element)\n\tif (!Array.prototype.insert) {\n\t\tArray.prototype.insert = function (element: any) {\n\t\t\tthis.splice(0, 0, element);\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Insert element at specific index (returns the inserted element)\n\tif (!Array.prototype.insertAt) {\n\t\tArray.prototype.insertAt = function (element: any, index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\tthis.splice(index, 0, element);\n\t\t\t} else {\n\t\t\t\tthis.push(element);\n\t\t\t}\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Remove element at index (returns removed element or 0 if out of bounds)\n\tif (!Array.prototype.remove) {\n\t\tArray.prototype.remove = function (index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Remove first occurrence of element (returns removed element or 0 if not found)\n\tif (!Array.prototype.removeElement) {\n\t\tArray.prototype.removeElement = function (element: any) {\n\t\t\tconst index = this.indexOf(element);\n\t\t\tif (index >= 0) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Check if array contains element (returns 1 if found, 0 if not found)\n\tif (!Array.prototype.contains) {\n\t\tArray.prototype.contains = function (element: any) {\n\t\t\treturn this.indexOf(element) >= 0 ? 1 : 0;\n\t\t};\n\t}\n\n\t// Sort array with optional comparator function\n\tif (!Array.prototype.sortList) {\n\t\tArray.prototype.sortList = function (fn?: (a: any, b: any) => number) {\n\t\t\tif (fn) {\n\t\t\t\treturn this.sort(fn);\n\t\t\t}\n\t\t\treturn this.sort();\n\t\t};\n\t}\n}\n\n// TypeScript type declarations for Array prototype extensions\ndeclare global {\n\tinterface Array<T> {\n\t\tinsert(element: T): T;\n\t\tinsertAt(element: T, index: number): T;\n\t\tremove(index: number): T | 0;\n\t\tremoveElement(element: T): T | 0;\n\t\tcontains(element: T): 0 | 1;\n\t\tsortList(fn?: (a: T, b: T) => number): T[];\n\t}\n}\n"],"mappings":"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","names":["import_lootiscript","_baseMeta","round","x","Math","floor","ceil","abs","min","y","max","sqrt","pow","sin","cos","tan","asin","acos","atan","atan2","sind","PI","cosd","tand","asind","acosd","atand","atan2d","log","exp","random","Random","true","false","_defaultPrint","text","console","createVMContext","meta","global","fullMeta","_baseMeta","print","_defaultPrint","local","object","breakable","continuable","returnable","stack_size","timeout","Date","now","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","setupArrayExtensions","Array","prototype","insert","element","splice","insertAt","index","length","push","remove","removeElement","indexOf","contains","sortList","fn","sort","extractErrorInfo","err","fallbackFile","fallbackType","runner","errorMessage","error","message","String","stackTrace","main_thread","processor","generateStackTrace","type","line","column","file","stack","L8BVM","context","storage_service","error_info","meta","global","namespace","preserve_ls","createVMContext","StorageService","storage","getInterface","Runner","init","setupArrayExtensions","run","source","timeout","filename","Date","now","stack_size","result","check","undefined","toString","call","name","args","loadRoutine","routineData","routine","Routine","import","normalizeSerializedRoutine","addCall","tick","clearWarnings","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","getWarnings","value","isCompiledModuleArtifact","format"]}
|
|
1
|
+
{"version":3,"sources":["../src/l8bvm.ts","../src/context.ts","../src/extensions.ts"],"sourcesContent":["/**\n * L8BVM - Virtual Machine wrapper for lootiscript\n *\n * High-level interface for the LootiScript virtual machine.\n * Wraps the core Compiler, Processor, and Runner into a usable engine component.\n * Handles context creation, storage persistence, and error formatting.\n *\n * Responsibilities:\n * - Create and manage VM execution context\n * - Provide clean API for running code and calling functions\n * - Handle storage persistence\n * - Format and normalize runtime errors\n *\n * @module vm\n */\n\nimport { StorageService } from \"@al8b/io\";\nimport { Routine, Runner } from \"@al8b/lootiscript\";\nimport { createVMContext } from \"./context\";\nimport { setupArrayExtensions } from \"./extensions\";\nimport type { ErrorInfo, GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n/**\n * Extract normalized ErrorInfo from a caught exception.\n * Centralizes the error-parsing logic shared across run(), call(), and loadRoutine().\n */\nfunction extractErrorInfo(err: any, fallbackFile: string, fallbackType: string, runner?: Runner): ErrorInfo {\n\tconst errorMessage =\n\t\ttypeof err === \"object\" && err !== null && \"error\" in err && typeof err.error === \"string\"\n\t\t\t? err.error\n\t\t\t: err?.message ?? String(err);\n\n\tlet stackTrace = err?.stackTrace;\n\tif (!stackTrace && (runner as any)?.main_thread?.processor?.generateStackTrace) {\n\t\tstackTrace = (runner as any).main_thread.processor.generateStackTrace();\n\t}\n\n\treturn {\n\t\terror: errorMessage,\n\t\ttype: err?.type ?? fallbackType,\n\t\tline: err?.line,\n\t\tcolumn: err?.column,\n\t\tfile: err?.file ?? fallbackFile,\n\t\tstack: err?.stack,\n\t\tstackTrace,\n\t};\n}\n\nexport class L8BVM {\n\tpublic context: VMContext;\n\tpublic runner: Runner;\n\tpublic storage_service: StorageService;\n\tpublic error_info: ErrorInfo | null = null;\n\n\tconstructor(\n\t\tmeta: Partial<MetaFunctions> = {},\n\t\tglobal: Partial<GlobalAPI> = {},\n\t\tnamespace = \"/l8b\",\n\t\tpreserve_ls = false,\n\t) {\n\t\t// Initialize VM execution context with meta functions and global API\n\t\tthis.context = createVMContext(meta, global);\n\n\t\t// Initialize storage service for persistent data (localStorage/sessionStorage)\n\t\tthis.storage_service = new StorageService(namespace, preserve_ls);\n\n\t\t// Inject storage API into global scope for LootiScript access\n\t\tthis.context.global.storage = this.storage_service.getInterface();\n\n\t\t// Create Runner instance with reference to this VM for bidirectional communication\n\t\tthis.runner = new Runner(this as any);\n\n\t\t// Initialize Runner and create main execution thread\n\t\tthis.runner.init();\n\n\t\t// Add custom array methods to Array.prototype for LootiScript\n\t\tsetupArrayExtensions();\n\t}\n\n\t/**\n\t * Run source code\n\t *\n\t * Compiles and executes a string of LootiScript code.\n\t *\n\t * @param {string} source - The source code to execute\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @param {string} [filename=\"\"] - Filename for error reporting\n\t * @returns {any} The result of the last statement execution\n\t * @throws {ErrorInfo} If compilation or execution fails\n\t */\n\trun(source: string, timeout = 3000, filename = \"\"): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.run(source, filename);\n\t\t\tthis.storage_service.check();\n\n\t\t\tif (result !== null && result !== undefined) {\n\t\t\t\treturn this.runner.toString(result);\n\t\t\t}\n\t\t\treturn null;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"runtime\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Call a global function\n\t *\n\t * Executes a specific function defined in the global scope.\n\t * Useful for game loop hooks (update, draw) or event handlers.\n\t *\n\t * @param {string} name - Name of the function to call\n\t * @param {any[]} [args=[]] - Arguments to pass to the function\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @returns {any} The return value of the function\n\t * @throws {ErrorInfo} If the function doesn't exist or execution fails\n\t */\n\tcall(name: string, args: any[] = [], timeout = 3000): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.call(name, ...args);\n\t\t\tthis.storage_service.check();\n\t\t\treturn result;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, name, \"call\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Load a pre-compiled routine (for production builds)\n\t *\n\t * Loads bytecode directly into the VM, bypassing the compilation step.\n\t * Used in production to improve startup time and obfuscate source.\n\t *\n\t * @param {any} routineData - Either a Routine instance or serialized JSON\n\t * @param {string} [filename=\"\"] - Name of the file for error reporting\n\t * @throws {ErrorInfo} If loading fails\n\t */\n\tloadRoutine(routineData: any, filename: string = \"\"): void {\n\t\tthis.error_info = null;\n\n\t\ttry {\n\t\t\tlet routine: Routine;\n\n\t\t\t// Handle both Routine instances and serialized routine data\n\t\t\t// Serialized data needs to be imported first\n\t\t\tif (routineData instanceof Routine) {\n\t\t\t\troutine = routineData;\n\t\t\t} else {\n\t\t\t\troutine = new Routine(0).import(normalizeSerializedRoutine(routineData));\n\t\t\t}\n\n\t\t\t// Add to main thread for execution\n\t\t\tthis.runner.main_thread.addCall(routine);\n\t\t\tthis.runner.tick();\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"compile\");\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Clear warnings\n\t */\n\tclearWarnings(): void {\n\t\tthis.context.warnings = {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t};\n\t}\n\n\t/**\n\t * Get warnings\n\t */\n\tgetWarnings(): Record<string, any> {\n\t\treturn this.context.warnings || {};\n\t}\n\n\t/**\n\t * Convert value to string (for printing)\n\t */\n\ttoString(value: any): string {\n\t\treturn this.runner.toString(value);\n\t}\n}\n\n// Inline types stub for @al8b/framework-shared\ninterface CompiledModuleArtifact {\n\tformat: \"l8b-compiled-routine\";\n\troutine: SerializedRoutineData;\n}\ntype SerializedRoutineData = {\n\tnum_args: number;\n\tops: number[];\n\targs: any[];\n\timport_refs: any[];\n\timport_values: any[];\n\timport_self: number;\n\tlocals_size?: number;\n};\n\nfunction normalizeSerializedRoutine(routineData: CompiledModuleArtifact | SerializedRoutineData): SerializedRoutineData {\n\tif (isCompiledModuleArtifact(routineData)) {\n\t\treturn routineData.routine;\n\t}\n\n\treturn routineData;\n}\n\nfunction isCompiledModuleArtifact(value: unknown): value is CompiledModuleArtifact {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"format\" in value &&\n\t\t(value as { format?: unknown }).format === \"l8b-compiled-routine\" &&\n\t\t\"routine\" in value\n\t);\n}\n","/**\n * VM Context creation utilities\n */\n\nimport { Random } from \"@al8b/lootiscript\";\nimport type { GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n// Shared math lambdas — allocated once, reused across all VM instances\nconst _baseMeta = {\n\tround: (x: number) => Math.round(x),\n\tfloor: (x: number) => Math.floor(x),\n\tceil: (x: number) => Math.ceil(x),\n\tabs: (x: number) => Math.abs(x),\n\tmin: (x: number, y: number) => Math.min(x, y),\n\tmax: (x: number, y: number) => Math.max(x, y),\n\tsqrt: (x: number) => Math.sqrt(x),\n\tpow: (x: number, y: number) => x ** y,\n\tsin: (x: number) => Math.sin(x),\n\tcos: (x: number) => Math.cos(x),\n\ttan: (x: number) => Math.tan(x),\n\tasin: (x: number) => Math.asin(x),\n\tacos: (x: number) => Math.acos(x),\n\tatan: (x: number) => Math.atan(x),\n\tatan2: (y: number, x: number) => Math.atan2(y, x),\n\tsind: (x: number) => Math.sin((x / 180) * Math.PI),\n\tcosd: (x: number) => Math.cos((x / 180) * Math.PI),\n\ttand: (x: number) => Math.tan((x / 180) * Math.PI),\n\tasind: (x: number) => (Math.asin(x) * 180) / Math.PI,\n\tacosd: (x: number) => (Math.acos(x) * 180) / Math.PI,\n\tatand: (x: number) => (Math.atan(x) * 180) / Math.PI,\n\tatan2d: (y: number, x: number) => (Math.atan2(y, x) * 180) / Math.PI,\n\tlog: (x: number) => Math.log(x),\n\texp: (x: number) => Math.exp(x),\n\trandom: new Random(0),\n\tPI: Math.PI,\n\ttrue: 1 as const,\n\tfalse: 0 as const,\n};\n\nconst _defaultPrint = (text: any) => console.log(text);\n\n/**\n * Create meta functions (built-in functions)\n */\nexport function createMetaFunctions(customPrint?: (text: any) => void): MetaFunctions {\n\treturn {\n\t\t..._baseMeta,\n\t\tprint: customPrint ?? _defaultPrint,\n\t};\n}\n\n/**\n * Create VM context\n */\nexport function createVMContext(meta: Partial<MetaFunctions>, global: Partial<GlobalAPI>): VMContext {\n\tconst fullMeta: MetaFunctions = {\n\t\t..._baseMeta,\n\t\tprint: meta.print ?? _defaultPrint,\n\t\t...meta,\n\t};\n\n\treturn {\n\t\tmeta: fullMeta as MetaFunctions,\n\t\tglobal: global as GlobalAPI,\n\t\tlocal: global,\n\t\tobject: global,\n\t\tbreakable: 0,\n\t\tcontinuable: 0,\n\t\treturnable: 0,\n\t\tstack_size: 0,\n\t\ttimeout: Date.now() + 3000,\n\t\twarnings: {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t},\n\t};\n}\n","/**\n * Array extensions\n */\n\n/**\n * Setup array extensions\n */\nexport function setupArrayExtensions(): void {\n\t// Insert element at beginning of array (returns the inserted element)\n\tif (!Array.prototype.insert) {\n\t\tArray.prototype.insert = function (element: any) {\n\t\t\tthis.splice(0, 0, element);\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Insert element at specific index (returns the inserted element)\n\tif (!Array.prototype.insertAt) {\n\t\tArray.prototype.insertAt = function (element: any, index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\tthis.splice(index, 0, element);\n\t\t\t} else {\n\t\t\t\tthis.push(element);\n\t\t\t}\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Remove element at index (returns removed element or 0 if out of bounds)\n\tif (!Array.prototype.remove) {\n\t\tArray.prototype.remove = function (index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Remove first occurrence of element (returns removed element or 0 if not found)\n\tif (!Array.prototype.removeElement) {\n\t\tArray.prototype.removeElement = function (element: any) {\n\t\t\tconst index = this.indexOf(element);\n\t\t\tif (index >= 0) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Check if array contains element (returns 1 if found, 0 if not found)\n\tif (!Array.prototype.contains) {\n\t\tArray.prototype.contains = function (element: any) {\n\t\t\treturn this.indexOf(element) >= 0 ? 1 : 0;\n\t\t};\n\t}\n\n\t// Sort array with optional comparator function\n\tif (!Array.prototype.sortList) {\n\t\tArray.prototype.sortList = function (fn?: (a: any, b: any) => number) {\n\t\t\tif (fn) {\n\t\t\t\treturn this.sort(fn);\n\t\t\t}\n\t\t\treturn this.sort();\n\t\t};\n\t}\n}\n\n// TypeScript type declarations for Array prototype extensions\ndeclare global {\n\tinterface Array<T> {\n\t\tinsert(element: T): T;\n\t\tinsertAt(element: T, index: number): T;\n\t\tremove(index: number): T | 0;\n\t\tremoveElement(element: T): T | 0;\n\t\tcontains(element: T): 0 | 1;\n\t\tsortList(fn?: (a: T, b: T) => number): T[];\n\t}\n}\n"],"mappings":"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","names":["import_lootiscript","_baseMeta","round","x","Math","floor","ceil","abs","min","y","max","sqrt","pow","sin","cos","tan","asin","acos","atan","atan2","sind","PI","cosd","tand","asind","acosd","atand","atan2d","log","exp","random","Random","true","false","_defaultPrint","text","console","createVMContext","meta","global","fullMeta","_baseMeta","print","_defaultPrint","local","object","breakable","continuable","returnable","stack_size","timeout","Date","now","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","setupArrayExtensions","Array","prototype","insert","element","splice","insertAt","index","length","push","remove","removeElement","indexOf","contains","sortList","fn","sort","extractErrorInfo","err","fallbackFile","fallbackType","runner","errorMessage","error","message","String","stackTrace","main_thread","processor","generateStackTrace","type","line","column","file","stack","L8BVM","context","storage_service","error_info","meta","global","namespace","preserve_ls","createVMContext","StorageService","storage","getInterface","Runner","init","setupArrayExtensions","run","source","timeout","filename","Date","now","stack_size","result","check","undefined","toString","call","name","args","loadRoutine","routineData","routine","Routine","import","normalizeSerializedRoutine","addCall","tick","clearWarnings","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","getWarnings","value","isCompiledModuleArtifact","format"]}
|
package/dist/l8bvm.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/l8bvm.ts","../src/context.ts","../src/extensions.ts"],"sourcesContent":["/**\n * L8BVM - Virtual Machine wrapper for lootiscript\n *\n * High-level interface for the LootiScript virtual machine.\n * Wraps the core Compiler, Processor, and Runner into a usable engine component.\n * Handles context creation, storage persistence, and error formatting.\n *\n * Responsibilities:\n * - Create and manage VM execution context\n * - Provide clean API for running code and calling functions\n * - Handle storage persistence\n * - Format and normalize runtime errors\n *\n * @module vm\n */\n\nimport type { CompiledModuleArtifact, SerializedRoutineData } from \"@al8b/framework-shared\";\nimport { StorageService } from \"@al8b/io\";\nimport { Routine, Runner } from \"@al8b/lootiscript\";\nimport { createVMContext } from \"./context\";\nimport { setupArrayExtensions } from \"./extensions\";\nimport type { ErrorInfo, GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n/**\n * Extract normalized ErrorInfo from a caught exception.\n * Centralizes the error-parsing logic shared across run(), call(), and loadRoutine().\n */\nfunction extractErrorInfo(err: any, fallbackFile: string, fallbackType: string, runner?: Runner): ErrorInfo {\n\tconst errorMessage =\n\t\ttypeof err === \"object\" && err !== null && \"error\" in err && typeof err.error === \"string\"\n\t\t\t? err.error\n\t\t\t: err?.message ?? String(err);\n\n\tlet stackTrace = err?.stackTrace;\n\tif (!stackTrace && (runner as any)?.main_thread?.processor?.generateStackTrace) {\n\t\tstackTrace = (runner as any).main_thread.processor.generateStackTrace();\n\t}\n\n\treturn {\n\t\terror: errorMessage,\n\t\ttype: err?.type ?? fallbackType,\n\t\tline: err?.line,\n\t\tcolumn: err?.column,\n\t\tfile: err?.file ?? fallbackFile,\n\t\tstack: err?.stack,\n\t\tstackTrace,\n\t};\n}\n\nexport class L8BVM {\n\tpublic context: VMContext;\n\tpublic runner: Runner;\n\tpublic storage_service: StorageService;\n\tpublic error_info: ErrorInfo | null = null;\n\n\tconstructor(\n\t\tmeta: Partial<MetaFunctions> = {},\n\t\tglobal: Partial<GlobalAPI> = {},\n\t\tnamespace = \"/l8b\",\n\t\tpreserve_ls = false,\n\t) {\n\t\t// Initialize VM execution context with meta functions and global API\n\t\tthis.context = createVMContext(meta, global);\n\n\t\t// Initialize storage service for persistent data (localStorage/sessionStorage)\n\t\tthis.storage_service = new StorageService(namespace, preserve_ls);\n\n\t\t// Inject storage API into global scope for LootiScript access\n\t\tthis.context.global.storage = this.storage_service.getInterface();\n\n\t\t// Create Runner instance with reference to this VM for bidirectional communication\n\t\tthis.runner = new Runner(this as any);\n\n\t\t// Initialize Runner and create main execution thread\n\t\tthis.runner.init();\n\n\t\t// Add custom array methods to Array.prototype for LootiScript\n\t\tsetupArrayExtensions();\n\t}\n\n\t/**\n\t * Run source code\n\t *\n\t * Compiles and executes a string of LootiScript code.\n\t *\n\t * @param {string} source - The source code to execute\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @param {string} [filename=\"\"] - Filename for error reporting\n\t * @returns {any} The result of the last statement execution\n\t * @throws {ErrorInfo} If compilation or execution fails\n\t */\n\trun(source: string, timeout = 3000, filename = \"\"): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.run(source, filename);\n\t\t\tthis.storage_service.check();\n\n\t\t\tif (result !== null && result !== undefined) {\n\t\t\t\treturn this.runner.toString(result);\n\t\t\t}\n\t\t\treturn null;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"runtime\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Call a global function\n\t *\n\t * Executes a specific function defined in the global scope.\n\t * Useful for game loop hooks (update, draw) or event handlers.\n\t *\n\t * @param {string} name - Name of the function to call\n\t * @param {any[]} [args=[]] - Arguments to pass to the function\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @returns {any} The return value of the function\n\t * @throws {ErrorInfo} If the function doesn't exist or execution fails\n\t */\n\tcall(name: string, args: any[] = [], timeout = 3000): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.call(name, ...args);\n\t\t\tthis.storage_service.check();\n\t\t\treturn result;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, name, \"call\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Load a pre-compiled routine (for production builds)\n\t *\n\t * Loads bytecode directly into the VM, bypassing the compilation step.\n\t * Used in production to improve startup time and obfuscate source.\n\t *\n\t * @param {any} routineData - Either a Routine instance or serialized JSON\n\t * @param {string} [filename=\"\"] - Name of the file for error reporting\n\t * @throws {ErrorInfo} If loading fails\n\t */\n\tloadRoutine(routineData: any, filename: string = \"\"): void {\n\t\tthis.error_info = null;\n\n\t\ttry {\n\t\t\tlet routine: Routine;\n\n\t\t\t// Handle both Routine instances and serialized routine data\n\t\t\t// Serialized data needs to be imported first\n\t\t\tif (routineData instanceof Routine) {\n\t\t\t\troutine = routineData;\n\t\t\t} else {\n\t\t\t\troutine = new Routine(0).import(normalizeSerializedRoutine(routineData));\n\t\t\t}\n\n\t\t\t// Add to main thread for execution\n\t\t\tthis.runner.main_thread.addCall(routine);\n\t\t\tthis.runner.tick();\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"compile\");\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Clear warnings\n\t */\n\tclearWarnings(): void {\n\t\tthis.context.warnings = {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t};\n\t}\n\n\t/**\n\t * Get warnings\n\t */\n\tgetWarnings(): Record<string, any> {\n\t\treturn this.context.warnings || {};\n\t}\n\n\t/**\n\t * Convert value to string (for printing)\n\t */\n\ttoString(value: any): string {\n\t\treturn this.runner.toString(value);\n\t}\n}\n\nfunction normalizeSerializedRoutine(routineData: CompiledModuleArtifact | SerializedRoutineData): SerializedRoutineData {\n\tif (isCompiledModuleArtifact(routineData)) {\n\t\treturn routineData.routine;\n\t}\n\n\treturn routineData;\n}\n\nfunction isCompiledModuleArtifact(value: unknown): value is CompiledModuleArtifact {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"format\" in value &&\n\t\t(value as { format?: unknown }).format === \"l8b-compiled-routine\" &&\n\t\t\"routine\" in value\n\t);\n}\n","/**\n * VM Context creation utilities\n */\n\nimport { Random } from \"@al8b/lootiscript\";\nimport type { GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n// Shared math lambdas — allocated once, reused across all VM instances\nconst _baseMeta = {\n\tround: (x: number) => Math.round(x),\n\tfloor: (x: number) => Math.floor(x),\n\tceil: (x: number) => Math.ceil(x),\n\tabs: (x: number) => Math.abs(x),\n\tmin: (x: number, y: number) => Math.min(x, y),\n\tmax: (x: number, y: number) => Math.max(x, y),\n\tsqrt: (x: number) => Math.sqrt(x),\n\tpow: (x: number, y: number) => x ** y,\n\tsin: (x: number) => Math.sin(x),\n\tcos: (x: number) => Math.cos(x),\n\ttan: (x: number) => Math.tan(x),\n\tasin: (x: number) => Math.asin(x),\n\tacos: (x: number) => Math.acos(x),\n\tatan: (x: number) => Math.atan(x),\n\tatan2: (y: number, x: number) => Math.atan2(y, x),\n\tsind: (x: number) => Math.sin((x / 180) * Math.PI),\n\tcosd: (x: number) => Math.cos((x / 180) * Math.PI),\n\ttand: (x: number) => Math.tan((x / 180) * Math.PI),\n\tasind: (x: number) => (Math.asin(x) * 180) / Math.PI,\n\tacosd: (x: number) => (Math.acos(x) * 180) / Math.PI,\n\tatand: (x: number) => (Math.atan(x) * 180) / Math.PI,\n\tatan2d: (y: number, x: number) => (Math.atan2(y, x) * 180) / Math.PI,\n\tlog: (x: number) => Math.log(x),\n\texp: (x: number) => Math.exp(x),\n\trandom: new Random(0),\n\tPI: Math.PI,\n\ttrue: 1 as const,\n\tfalse: 0 as const,\n};\n\nconst _defaultPrint = (text: any) => console.log(text);\n\n/**\n * Create meta functions (built-in functions)\n */\nexport function createMetaFunctions(customPrint?: (text: any) => void): MetaFunctions {\n\treturn {\n\t\t..._baseMeta,\n\t\tprint: customPrint ?? _defaultPrint,\n\t};\n}\n\n/**\n * Create VM context\n */\nexport function createVMContext(meta: Partial<MetaFunctions>, global: Partial<GlobalAPI>): VMContext {\n\tconst fullMeta: MetaFunctions = {\n\t\t..._baseMeta,\n\t\tprint: meta.print ?? _defaultPrint,\n\t\t...meta,\n\t};\n\n\treturn {\n\t\tmeta: fullMeta as MetaFunctions,\n\t\tglobal: global as GlobalAPI,\n\t\tlocal: global,\n\t\tobject: global,\n\t\tbreakable: 0,\n\t\tcontinuable: 0,\n\t\treturnable: 0,\n\t\tstack_size: 0,\n\t\ttimeout: Date.now() + 3000,\n\t\twarnings: {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t},\n\t};\n}\n","/**\n * Array extensions\n */\n\n/**\n * Setup array extensions\n */\nexport function setupArrayExtensions(): void {\n\t// Insert element at beginning of array (returns the inserted element)\n\tif (!Array.prototype.insert) {\n\t\tArray.prototype.insert = function (element: any) {\n\t\t\tthis.splice(0, 0, element);\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Insert element at specific index (returns the inserted element)\n\tif (!Array.prototype.insertAt) {\n\t\tArray.prototype.insertAt = function (element: any, index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\tthis.splice(index, 0, element);\n\t\t\t} else {\n\t\t\t\tthis.push(element);\n\t\t\t}\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Remove element at index (returns removed element or 0 if out of bounds)\n\tif (!Array.prototype.remove) {\n\t\tArray.prototype.remove = function (index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Remove first occurrence of element (returns removed element or 0 if not found)\n\tif (!Array.prototype.removeElement) {\n\t\tArray.prototype.removeElement = function (element: any) {\n\t\t\tconst index = this.indexOf(element);\n\t\t\tif (index >= 0) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Check if array contains element (returns 1 if found, 0 if not found)\n\tif (!Array.prototype.contains) {\n\t\tArray.prototype.contains = function (element: any) {\n\t\t\treturn this.indexOf(element) >= 0 ? 1 : 0;\n\t\t};\n\t}\n\n\t// Sort array with optional comparator function\n\tif (!Array.prototype.sortList) {\n\t\tArray.prototype.sortList = function (fn?: (a: any, b: any) => number) {\n\t\t\tif (fn) {\n\t\t\t\treturn this.sort(fn);\n\t\t\t}\n\t\t\treturn this.sort();\n\t\t};\n\t}\n}\n\n// TypeScript type declarations for Array prototype extensions\ndeclare global {\n\tinterface Array<T> {\n\t\tinsert(element: T): T;\n\t\tinsertAt(element: T, index: number): T;\n\t\tremove(index: number): T | 0;\n\t\tremoveElement(element: T): T | 0;\n\t\tcontains(element: T): 0 | 1;\n\t\tsortList(fn?: (a: T, b: T) => number): T[];\n\t}\n}\n"],"mappings":"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","names":["StorageService","Routine","Runner","Random","_baseMeta","round","x","Math","floor","ceil","abs","min","y","max","sqrt","pow","sin","cos","tan","asin","acos","atan","atan2","sind","PI","cosd","tand","asind","acosd","atand","atan2d","log","exp","random","Random","true","false","_defaultPrint","text","console","createVMContext","meta","global","fullMeta","_baseMeta","print","_defaultPrint","local","object","breakable","continuable","returnable","stack_size","timeout","Date","now","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","setupArrayExtensions","Array","prototype","insert","element","splice","insertAt","index","length","push","remove","removeElement","indexOf","contains","sortList","fn","sort","extractErrorInfo","err","fallbackFile","fallbackType","runner","errorMessage","error","message","String","stackTrace","main_thread","processor","generateStackTrace","type","line","column","file","stack","L8BVM","context","storage_service","error_info","meta","global","namespace","preserve_ls","createVMContext","StorageService","storage","getInterface","Runner","init","setupArrayExtensions","run","source","timeout","filename","Date","now","stack_size","result","check","undefined","toString","call","name","args","loadRoutine","routineData","routine","Routine","import","normalizeSerializedRoutine","addCall","tick","clearWarnings","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","getWarnings","value","isCompiledModuleArtifact","format"]}
|
|
1
|
+
{"version":3,"sources":["../src/l8bvm.ts","../src/context.ts","../src/extensions.ts"],"sourcesContent":["/**\n * L8BVM - Virtual Machine wrapper for lootiscript\n *\n * High-level interface for the LootiScript virtual machine.\n * Wraps the core Compiler, Processor, and Runner into a usable engine component.\n * Handles context creation, storage persistence, and error formatting.\n *\n * Responsibilities:\n * - Create and manage VM execution context\n * - Provide clean API for running code and calling functions\n * - Handle storage persistence\n * - Format and normalize runtime errors\n *\n * @module vm\n */\n\nimport { StorageService } from \"@al8b/io\";\nimport { Routine, Runner } from \"@al8b/lootiscript\";\nimport { createVMContext } from \"./context\";\nimport { setupArrayExtensions } from \"./extensions\";\nimport type { ErrorInfo, GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n/**\n * Extract normalized ErrorInfo from a caught exception.\n * Centralizes the error-parsing logic shared across run(), call(), and loadRoutine().\n */\nfunction extractErrorInfo(err: any, fallbackFile: string, fallbackType: string, runner?: Runner): ErrorInfo {\n\tconst errorMessage =\n\t\ttypeof err === \"object\" && err !== null && \"error\" in err && typeof err.error === \"string\"\n\t\t\t? err.error\n\t\t\t: err?.message ?? String(err);\n\n\tlet stackTrace = err?.stackTrace;\n\tif (!stackTrace && (runner as any)?.main_thread?.processor?.generateStackTrace) {\n\t\tstackTrace = (runner as any).main_thread.processor.generateStackTrace();\n\t}\n\n\treturn {\n\t\terror: errorMessage,\n\t\ttype: err?.type ?? fallbackType,\n\t\tline: err?.line,\n\t\tcolumn: err?.column,\n\t\tfile: err?.file ?? fallbackFile,\n\t\tstack: err?.stack,\n\t\tstackTrace,\n\t};\n}\n\nexport class L8BVM {\n\tpublic context: VMContext;\n\tpublic runner: Runner;\n\tpublic storage_service: StorageService;\n\tpublic error_info: ErrorInfo | null = null;\n\n\tconstructor(\n\t\tmeta: Partial<MetaFunctions> = {},\n\t\tglobal: Partial<GlobalAPI> = {},\n\t\tnamespace = \"/l8b\",\n\t\tpreserve_ls = false,\n\t) {\n\t\t// Initialize VM execution context with meta functions and global API\n\t\tthis.context = createVMContext(meta, global);\n\n\t\t// Initialize storage service for persistent data (localStorage/sessionStorage)\n\t\tthis.storage_service = new StorageService(namespace, preserve_ls);\n\n\t\t// Inject storage API into global scope for LootiScript access\n\t\tthis.context.global.storage = this.storage_service.getInterface();\n\n\t\t// Create Runner instance with reference to this VM for bidirectional communication\n\t\tthis.runner = new Runner(this as any);\n\n\t\t// Initialize Runner and create main execution thread\n\t\tthis.runner.init();\n\n\t\t// Add custom array methods to Array.prototype for LootiScript\n\t\tsetupArrayExtensions();\n\t}\n\n\t/**\n\t * Run source code\n\t *\n\t * Compiles and executes a string of LootiScript code.\n\t *\n\t * @param {string} source - The source code to execute\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @param {string} [filename=\"\"] - Filename for error reporting\n\t * @returns {any} The result of the last statement execution\n\t * @throws {ErrorInfo} If compilation or execution fails\n\t */\n\trun(source: string, timeout = 3000, filename = \"\"): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.run(source, filename);\n\t\t\tthis.storage_service.check();\n\n\t\t\tif (result !== null && result !== undefined) {\n\t\t\t\treturn this.runner.toString(result);\n\t\t\t}\n\t\t\treturn null;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"runtime\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Call a global function\n\t *\n\t * Executes a specific function defined in the global scope.\n\t * Useful for game loop hooks (update, draw) or event handlers.\n\t *\n\t * @param {string} name - Name of the function to call\n\t * @param {any[]} [args=[]] - Arguments to pass to the function\n\t * @param {number} [timeout=3000] - Execution time limit in ms\n\t * @returns {any} The return value of the function\n\t * @throws {ErrorInfo} If the function doesn't exist or execution fails\n\t */\n\tcall(name: string, args: any[] = [], timeout = 3000): any {\n\t\tthis.error_info = null;\n\t\tthis.context.timeout = Date.now() + timeout;\n\t\tthis.context.stack_size = 0;\n\n\t\ttry {\n\t\t\tconst result = this.runner.call(name, ...args);\n\t\t\tthis.storage_service.check();\n\t\t\treturn result;\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, name, \"call\", this.runner);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Load a pre-compiled routine (for production builds)\n\t *\n\t * Loads bytecode directly into the VM, bypassing the compilation step.\n\t * Used in production to improve startup time and obfuscate source.\n\t *\n\t * @param {any} routineData - Either a Routine instance or serialized JSON\n\t * @param {string} [filename=\"\"] - Name of the file for error reporting\n\t * @throws {ErrorInfo} If loading fails\n\t */\n\tloadRoutine(routineData: any, filename: string = \"\"): void {\n\t\tthis.error_info = null;\n\n\t\ttry {\n\t\t\tlet routine: Routine;\n\n\t\t\t// Handle both Routine instances and serialized routine data\n\t\t\t// Serialized data needs to be imported first\n\t\t\tif (routineData instanceof Routine) {\n\t\t\t\troutine = routineData;\n\t\t\t} else {\n\t\t\t\troutine = new Routine(0).import(normalizeSerializedRoutine(routineData));\n\t\t\t}\n\n\t\t\t// Add to main thread for execution\n\t\t\tthis.runner.main_thread.addCall(routine);\n\t\t\tthis.runner.tick();\n\t\t} catch (err: any) {\n\t\t\tthis.error_info = extractErrorInfo(err, filename, \"compile\");\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Clear warnings\n\t */\n\tclearWarnings(): void {\n\t\tthis.context.warnings = {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t};\n\t}\n\n\t/**\n\t * Get warnings\n\t */\n\tgetWarnings(): Record<string, any> {\n\t\treturn this.context.warnings || {};\n\t}\n\n\t/**\n\t * Convert value to string (for printing)\n\t */\n\ttoString(value: any): string {\n\t\treturn this.runner.toString(value);\n\t}\n}\n\n// Inline types stub for @al8b/framework-shared\ninterface CompiledModuleArtifact {\n\tformat: \"l8b-compiled-routine\";\n\troutine: SerializedRoutineData;\n}\ntype SerializedRoutineData = {\n\tnum_args: number;\n\tops: number[];\n\targs: any[];\n\timport_refs: any[];\n\timport_values: any[];\n\timport_self: number;\n\tlocals_size?: number;\n};\n\nfunction normalizeSerializedRoutine(routineData: CompiledModuleArtifact | SerializedRoutineData): SerializedRoutineData {\n\tif (isCompiledModuleArtifact(routineData)) {\n\t\treturn routineData.routine;\n\t}\n\n\treturn routineData;\n}\n\nfunction isCompiledModuleArtifact(value: unknown): value is CompiledModuleArtifact {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"format\" in value &&\n\t\t(value as { format?: unknown }).format === \"l8b-compiled-routine\" &&\n\t\t\"routine\" in value\n\t);\n}\n","/**\n * VM Context creation utilities\n */\n\nimport { Random } from \"@al8b/lootiscript\";\nimport type { GlobalAPI, MetaFunctions, VMContext } from \"./types\";\n\n// Shared math lambdas — allocated once, reused across all VM instances\nconst _baseMeta = {\n\tround: (x: number) => Math.round(x),\n\tfloor: (x: number) => Math.floor(x),\n\tceil: (x: number) => Math.ceil(x),\n\tabs: (x: number) => Math.abs(x),\n\tmin: (x: number, y: number) => Math.min(x, y),\n\tmax: (x: number, y: number) => Math.max(x, y),\n\tsqrt: (x: number) => Math.sqrt(x),\n\tpow: (x: number, y: number) => x ** y,\n\tsin: (x: number) => Math.sin(x),\n\tcos: (x: number) => Math.cos(x),\n\ttan: (x: number) => Math.tan(x),\n\tasin: (x: number) => Math.asin(x),\n\tacos: (x: number) => Math.acos(x),\n\tatan: (x: number) => Math.atan(x),\n\tatan2: (y: number, x: number) => Math.atan2(y, x),\n\tsind: (x: number) => Math.sin((x / 180) * Math.PI),\n\tcosd: (x: number) => Math.cos((x / 180) * Math.PI),\n\ttand: (x: number) => Math.tan((x / 180) * Math.PI),\n\tasind: (x: number) => (Math.asin(x) * 180) / Math.PI,\n\tacosd: (x: number) => (Math.acos(x) * 180) / Math.PI,\n\tatand: (x: number) => (Math.atan(x) * 180) / Math.PI,\n\tatan2d: (y: number, x: number) => (Math.atan2(y, x) * 180) / Math.PI,\n\tlog: (x: number) => Math.log(x),\n\texp: (x: number) => Math.exp(x),\n\trandom: new Random(0),\n\tPI: Math.PI,\n\ttrue: 1 as const,\n\tfalse: 0 as const,\n};\n\nconst _defaultPrint = (text: any) => console.log(text);\n\n/**\n * Create meta functions (built-in functions)\n */\nexport function createMetaFunctions(customPrint?: (text: any) => void): MetaFunctions {\n\treturn {\n\t\t..._baseMeta,\n\t\tprint: customPrint ?? _defaultPrint,\n\t};\n}\n\n/**\n * Create VM context\n */\nexport function createVMContext(meta: Partial<MetaFunctions>, global: Partial<GlobalAPI>): VMContext {\n\tconst fullMeta: MetaFunctions = {\n\t\t..._baseMeta,\n\t\tprint: meta.print ?? _defaultPrint,\n\t\t...meta,\n\t};\n\n\treturn {\n\t\tmeta: fullMeta as MetaFunctions,\n\t\tglobal: global as GlobalAPI,\n\t\tlocal: global,\n\t\tobject: global,\n\t\tbreakable: 0,\n\t\tcontinuable: 0,\n\t\treturnable: 0,\n\t\tstack_size: 0,\n\t\ttimeout: Date.now() + 3000,\n\t\twarnings: {\n\t\t\tusing_undefined_variable: {},\n\t\t\tassigning_field_to_undefined: {},\n\t\t\tinvoking_non_function: {},\n\t\t\tassigning_api_variable: {},\n\t\t\tassignment_as_condition: {},\n\t\t},\n\t};\n}\n","/**\n * Array extensions\n */\n\n/**\n * Setup array extensions\n */\nexport function setupArrayExtensions(): void {\n\t// Insert element at beginning of array (returns the inserted element)\n\tif (!Array.prototype.insert) {\n\t\tArray.prototype.insert = function (element: any) {\n\t\t\tthis.splice(0, 0, element);\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Insert element at specific index (returns the inserted element)\n\tif (!Array.prototype.insertAt) {\n\t\tArray.prototype.insertAt = function (element: any, index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\tthis.splice(index, 0, element);\n\t\t\t} else {\n\t\t\t\tthis.push(element);\n\t\t\t}\n\t\t\treturn element;\n\t\t};\n\t}\n\n\t// Remove element at index (returns removed element or 0 if out of bounds)\n\tif (!Array.prototype.remove) {\n\t\tArray.prototype.remove = function (index: number) {\n\t\t\tif (index >= 0 && index < this.length) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Remove first occurrence of element (returns removed element or 0 if not found)\n\tif (!Array.prototype.removeElement) {\n\t\tArray.prototype.removeElement = function (element: any) {\n\t\t\tconst index = this.indexOf(element);\n\t\t\tif (index >= 0) {\n\t\t\t\treturn this.splice(index, 1)[0];\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t}\n\n\t// Check if array contains element (returns 1 if found, 0 if not found)\n\tif (!Array.prototype.contains) {\n\t\tArray.prototype.contains = function (element: any) {\n\t\t\treturn this.indexOf(element) >= 0 ? 1 : 0;\n\t\t};\n\t}\n\n\t// Sort array with optional comparator function\n\tif (!Array.prototype.sortList) {\n\t\tArray.prototype.sortList = function (fn?: (a: any, b: any) => number) {\n\t\t\tif (fn) {\n\t\t\t\treturn this.sort(fn);\n\t\t\t}\n\t\t\treturn this.sort();\n\t\t};\n\t}\n}\n\n// TypeScript type declarations for Array prototype extensions\ndeclare global {\n\tinterface Array<T> {\n\t\tinsert(element: T): T;\n\t\tinsertAt(element: T, index: number): T;\n\t\tremove(index: number): T | 0;\n\t\tremoveElement(element: T): T | 0;\n\t\tcontains(element: T): 0 | 1;\n\t\tsortList(fn?: (a: T, b: T) => number): T[];\n\t}\n}\n"],"mappings":"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","names":["StorageService","Routine","Runner","Random","_baseMeta","round","x","Math","floor","ceil","abs","min","y","max","sqrt","pow","sin","cos","tan","asin","acos","atan","atan2","sind","PI","cosd","tand","asind","acosd","atand","atan2d","log","exp","random","Random","true","false","_defaultPrint","text","console","createVMContext","meta","global","fullMeta","_baseMeta","print","_defaultPrint","local","object","breakable","continuable","returnable","stack_size","timeout","Date","now","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","setupArrayExtensions","Array","prototype","insert","element","splice","insertAt","index","length","push","remove","removeElement","indexOf","contains","sortList","fn","sort","extractErrorInfo","err","fallbackFile","fallbackType","runner","errorMessage","error","message","String","stackTrace","main_thread","processor","generateStackTrace","type","line","column","file","stack","L8BVM","context","storage_service","error_info","meta","global","namespace","preserve_ls","createVMContext","StorageService","storage","getInterface","Runner","init","setupArrayExtensions","run","source","timeout","filename","Date","now","stack_size","result","check","undefined","toString","call","name","args","loadRoutine","routineData","routine","Routine","import","normalizeSerializedRoutine","addCall","tick","clearWarnings","warnings","using_undefined_variable","assigning_field_to_undefined","invoking_non_function","assigning_api_variable","assignment_as_condition","getWarnings","value","isCompiledModuleArtifact","format"]}
|
package/package.json
CHANGED
|
@@ -1,38 +1,37 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
2
|
+
"name": "@al8b/vm",
|
|
3
|
+
"version": "0.1.14",
|
|
4
|
+
"sideEffects": false,
|
|
5
|
+
"files": [
|
|
6
|
+
"dist/**/*",
|
|
7
|
+
"README.md",
|
|
8
|
+
"package.json"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsup",
|
|
12
|
+
"clean": "bun --bun ../../../scripts/clean-package.mjs dist",
|
|
13
|
+
"test": "vitest run --passWithNoTests"
|
|
14
|
+
},
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"module": "./dist/index.mjs",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.mjs",
|
|
22
|
+
"require": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@al8b/lootiscript": "^0.1.13",
|
|
27
|
+
"@al8b/io": "^0.1.14"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"vm",
|
|
31
|
+
"runtime",
|
|
32
|
+
"lootiscript"
|
|
33
|
+
],
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
}
|
|
38
37
|
}
|