pull/1219/merge
Zef Hemel 2025-02-08 16:51:31 +01:00
parent 2978f4a8d6
commit 9317d143b3
5 changed files with 54 additions and 14 deletions

View File

@ -18,7 +18,7 @@ export type JSValue = any;
export interface ILuaFunction { export interface ILuaFunction {
call(sf: LuaStackFrame, ...args: LuaValue[]): Promise<LuaValue> | LuaValue; call(sf: LuaStackFrame, ...args: LuaValue[]): Promise<LuaValue> | LuaValue;
toString(): string; asString(): string;
} }
export interface ILuaSettable { export interface ILuaSettable {
@ -196,10 +196,14 @@ export class LuaFunction implements ILuaFunction {
return this.callWithArgs(resolvedArgs, env, sf); return this.callWithArgs(resolvedArgs, env, sf);
} }
toString(): string { asString(): string {
return `<lua function(${this.body.parameters.join(", ")})>`; return `<lua function(${this.body.parameters.join(", ")})>`;
} }
toString(): string {
return this.asString();
}
private callWithArgs( private callWithArgs(
args: LuaValue[], args: LuaValue[],
env: LuaEnv, env: LuaEnv,
@ -271,9 +275,13 @@ export class LuaNativeJSFunction implements ILuaFunction {
} }
} }
toString(): string { asString(): string {
return `<native js function: ${this.fn.name}>`; return `<native js function: ${this.fn.name}>`;
} }
toString(): string {
return this.asString();
}
} }
export class LuaBuiltinFunction implements ILuaFunction { export class LuaBuiltinFunction implements ILuaFunction {
@ -287,9 +295,13 @@ export class LuaBuiltinFunction implements ILuaFunction {
return this.fn(sf, ...args); return this.fn(sf, ...args);
} }
toString(): string { asString(): string {
return `<builtin lua function>`; return `<builtin lua function>`;
} }
toString(): string {
return this.asString();
}
} }
export class LuaTable implements ILuaSettable, ILuaGettable { export class LuaTable implements ILuaSettable, ILuaGettable {
@ -730,6 +742,10 @@ export function luaToString(
visited.add(value); visited.add(value);
return value.toStringAsync(); return value.toStringAsync();
} }
if (value.asString) {
visited.add(value);
return value.asString();
}
if (value instanceof LuaFunction) { if (value instanceof LuaFunction) {
// Don't recurse into the function body, just show the function signature // Don't recurse into the function body, just show the function signature
return `<lua-function (${value.body.parameters.join(", ")})>`; return `<lua-function (${value.body.parameters.join(", ")})>`;

View File

@ -2,8 +2,13 @@ import type { SysCallMapping } from "$lib/plugos/system.ts";
import { evalExpression } from "$common/space_lua/eval.ts"; import { evalExpression } from "$common/space_lua/eval.ts";
import { parse, parseExpressionString } from "../space_lua/parse.ts"; import { parse, parseExpressionString } from "../space_lua/parse.ts";
import type { CommonSystem } from "$common/common_system.ts"; import type { CommonSystem } from "$common/common_system.ts";
import { LuaStackFrame, luaValueToJS } from "$common/space_lua/runtime.ts"; import {
LuaStackFrame,
luaToString,
luaValueToJS,
} from "$common/space_lua/runtime.ts";
import { buildThreadLocalEnv } from "$common/space_lua_api.ts"; import { buildThreadLocalEnv } from "$common/space_lua_api.ts";
import { isSendable } from "$lib/plugos/util.ts";
export function luaSyscalls(commonSystem: CommonSystem): SysCallMapping { export function luaSyscalls(commonSystem: CommonSystem): SysCallMapping {
return { return {
@ -24,9 +29,17 @@ export function luaSyscalls(commonSystem: CommonSystem): SysCallMapping {
commonSystem.spaceLuaEnv.env, commonSystem.spaceLuaEnv.env,
); );
const sf = new LuaStackFrame(env, null); const sf = new LuaStackFrame(env, null);
return luaValueToJS( const result = evalExpression(ast, commonSystem.spaceLuaEnv.env, sf);
evalExpression(ast, commonSystem.spaceLuaEnv.env, sf), if (isSendable(result)) {
); return luaValueToJS(result);
} else {
// This may evaluate to e.g. a function, which is not sendable, in this case we'll console.warn and return a stringified version of the result
console.warn(
"Lua eval result is not sendable, returning stringified version",
result,
);
return luaToString(result);
}
} catch (e: any) { } catch (e: any) {
console.error("Lua eval error: ", e.message, e.sf?.astCtx); console.error("Lua eval error: ", e.message, e.sf?.astCtx);
throw e; throw e;

14
lib/plugos/util.ts Normal file
View File

@ -0,0 +1,14 @@
/**
* Checks if an object is sendable across the plugos worker boundary.
*
* @param o - The object to check.
* @returns `true` if the object is sendable, `false` otherwise.
*/
export function isSendable(o: any): boolean {
try {
structuredClone(o);
return true;
} catch {
return false;
}
}

View File

@ -105,10 +105,9 @@ export async function expandCodeWidgets(
); );
} }
} else if (n.type === "LuaDirective") { } else if (n.type === "LuaDirective") {
const expr: LuaExpression | null = findNodeOfType( const expr = findNodeOfType(n, "LuaExpressionDirective") as
n, | LuaExpression
"LuaExpressionDirective", | null;
) as LuaExpression | null;
if (!expr) { if (!expr) {
return; return;
} }

View File

@ -25,8 +25,6 @@ export type LuaWidgetContent = {
markdown?: string; markdown?: string;
// CSS classes for wrapper // CSS classes for wrapper
cssClasses?: string[]; cssClasses?: string[];
// Index objects
objects?: ObjectValue<any>[];
display?: "block" | "inline"; display?: "block" | "inline";
} | string; } | string;