pass RuntimeContext on create Go instance

This commit is contained in:
syumai 2024-01-04 23:43:24 +09:00
parent 7585460853
commit 85ccbfb050
6 changed files with 39 additions and 41 deletions

View File

@ -78,5 +78,5 @@ func init() {
return jsutil.NewPromise(cb) return jsutil.NewPromise(cb)
}) })
js.Global().Set("runScheduler", runSchedulerCallback) jsutil.Binding.Set("runScheduler", runSchedulerCallback)
} }

View File

@ -21,7 +21,7 @@ export function init(m) {
mod = m; mod = m;
} }
async function run() { async function run(ctx) {
let ready; let ready;
const readyPromise = new Promise((resolve) => { const readyPromise = new Promise((resolve) => {
ready = resolve; ready = resolve;
@ -32,31 +32,35 @@ async function run() {
ready: () => { ready() } ready: () => { ready() }
}, },
}); });
go.run(instance); go.run(instance, ctx);
await readyPromise; await readyPromise;
} }
function createRuntimeContext(env, ctx) { function createRuntimeContext(env, ctx, binding) {
return { return {
env, env,
ctx, ctx,
connect, connect,
binding,
}; };
} }
export async function fetch(req, env, ctx) { export async function fetch(req, env, ctx) {
await run(); const binding = {};
return handleRequest(req, createRuntimeContext(env, ctx)); await run(createRuntimeContext(env, ctx, binding));
return binding.handleRequest(req);
} }
export async function scheduled(event, env, ctx) { export async function scheduled(event, env, ctx) {
await run(); const binding = {};
return runScheduler(event, createRuntimeContext(env, ctx)); await run(createRuntimeContext(env, ctx, binding));
return binding.runScheduler(event);
} }
// onRequest handles request to Cloudflare Pages // onRequest handles request to Cloudflare Pages
export async function onRequest(ctx) { export async function onRequest(ctx) {
await run(); const binding = {};
const { request, env } = ctx; const { request, env } = ctx;
return handleRequest(request, createRuntimeContext(env, ctx)); await run(createRuntimeContext(env, ctx, binding));
return binding.handleRequest(request);
} }

View File

@ -462,19 +462,27 @@
}; };
} }
async run(instance) { async run(instance, context) {
if (!(instance instanceof WebAssembly.Instance)) { if (!(instance instanceof WebAssembly.Instance)) {
throw new Error("Go.run: WebAssembly.Instance expected"); throw new Error("Go.run: WebAssembly.Instance expected");
} }
this._inst = instance; this._inst = instance;
this.mem = new DataView(this._inst.exports.mem.buffer); this.mem = new DataView(this._inst.exports.mem.buffer);
const globalProxy = new Proxy(globalThis, {
get(target, prop) {
if (prop === 'context') {
return context;
}
return Reflect.get(...arguments);
}
})
this._values = [ // JS values that Go currently has references to, indexed by reference id this._values = [ // JS values that Go currently has references to, indexed by reference id
NaN, NaN,
0, 0,
null, null,
true, true,
false, false,
globalThis, globalProxy,
this, this,
]; ];
this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id

View File

@ -458,15 +458,23 @@
this.importObject.env = this.importObject.gojs; this.importObject.env = this.importObject.gojs;
} }
async run(instance) { async run(instance, context) {
this._inst = instance; this._inst = instance;
const globalProxy = new Proxy(global, {
get(target, prop) {
if (prop === 'context') {
return context;
}
return Reflect.get(...arguments);
}
})
this._values = [ // JS values that Go currently has references to, indexed by reference id this._values = [ // JS values that Go currently has references to, indexed by reference id
NaN, NaN,
0, 0,
null, null,
true, true,
false, false,
global, globalProxy,
this, this,
]; ];
this._goRefCounts = []; // number of references that Go has to a JS value, indexed by reference id this._goRefCounts = []; // number of references that Go has to a JS value, indexed by reference id
@ -513,25 +521,4 @@
}; };
} }
} }
if (
global.require &&
global.require.main === module &&
global.process &&
global.process.versions &&
!global.process.versions.electron
) {
if (process.argv.length != 3) {
console.error("usage: go_js_wasm_exec [wasm binary] [arguments]");
process.exit(1);
}
const go = new Go();
WebAssembly.instantiate(fs.readFileSync(process.argv[2]), go.importObject).then((result) => {
return go.run(result.instance);
}).catch((err) => {
console.error(err);
process.exit(1);
});
}
})(); })();

View File

@ -17,14 +17,11 @@ var httpHandler http.Handler
func init() { func init() {
var handleRequestCallback js.Func var handleRequestCallback js.Func
handleRequestCallback = js.FuncOf(func(this js.Value, args []js.Value) any { handleRequestCallback = js.FuncOf(func(this js.Value, args []js.Value) any {
if len(args) > 2 { if len(args) > 1 {
panic(fmt.Errorf("too many args given to handleRequest: %d", len(args))) panic(fmt.Errorf("too many args given to handleRequest: %d", len(args)))
} }
reqObj := args[0] reqObj := args[0]
runtimeCtxObj := js.Null() runtimeCtxObj := jsutil.RuntimeContext
if len(args) > 1 {
runtimeCtxObj = args[1]
}
var cb js.Func var cb js.Func
cb = js.FuncOf(func(_ js.Value, pArgs []js.Value) any { cb = js.FuncOf(func(_ js.Value, pArgs []js.Value) any {
defer cb.Release() defer cb.Release()
@ -40,7 +37,7 @@ func init() {
}) })
return jsutil.NewPromise(cb) return jsutil.NewPromise(cb)
}) })
js.Global().Set("handleRequest", handleRequestCallback) jsutil.Binding.Set("handleRequest", handleRequestCallback)
} }
// handleRequest accepts a Request object and returns Response object. // handleRequest accepts a Request object and returns Response object.

View File

@ -7,6 +7,8 @@ import (
) )
var ( var (
RuntimeContext = js.Global().Get("context")
Binding = js.Global().Get("context").Get("binding")
ObjectClass = js.Global().Get("Object") ObjectClass = js.Global().Get("Object")
PromiseClass = js.Global().Get("Promise") PromiseClass = js.Global().Get("Promise")
RequestClass = js.Global().Get("Request") RequestClass = js.Global().Get("Request")