Skip to content

Commit

Permalink
Implement invoke wrong module workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
jerbob92 committed Aug 17, 2023
1 parent 28d6429 commit 3b29107
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
3 changes: 3 additions & 0 deletions internal/emscripten/emscripten.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,16 @@ func NewInvokeFunc(importName string, params, results []api.ValueType) *wasm.Hos
}
}

type invokeFuncParentModuleKey struct{}

type InvokeFunc struct {
*wasm.FunctionType
}

// Call implements api.GoModuleFunction by special casing dynamic calls needed
// for emscripten `invoke_` functions such as `invoke_ii` or `invoke_v`.
func (v *InvokeFunc) Call(ctx context.Context, mod api.Module, stack []uint64) {
ctx = context.WithValue(ctx, invokeFuncParentModuleKey{}, mod)
m := mod.(*wasm.ModuleInstance)

// Lookup the type of the function we are calling indirectly.
Expand Down
25 changes: 25 additions & 0 deletions internal/emscripten/exceptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ var CxaThrow = &wasm.HostFunc{
ParamTypes: []wasm.ValueType{wasm.ValueTypeI32, wasm.ValueTypeI32, wasm.ValueTypeI32},
ParamNames: []string{"ptr", "type", "destructor"},
Code: wasm.Code{GoFunc: api.GoModuleFunc(func(ctx context.Context, mod api.Module, params []uint64) {
mod = resolveMainModule(ctx, mod)
ptr := api.DecodeI32(params[0])
exceptionType := api.DecodeI32(params[1])
destructor := api.DecodeI32(params[2])
Expand Down Expand Up @@ -279,6 +280,7 @@ type FindMatchingCatchFunc struct {
}

func (v *FindMatchingCatchFunc) Call(ctx context.Context, mod api.Module, stack []uint64) {
mod = resolveMainModule(ctx, mod)
passThroughNull := func() {
_, err := mod.ExportedFunction("setTempRet0").Call(ctx, 0)
if err != nil {
Expand Down Expand Up @@ -369,6 +371,7 @@ var CxaBeginCatch = &wasm.HostFunc{
ResultTypes: []wasm.ValueType{wasm.ValueTypeI32},
ResultNames: []string{"exception_ptr"},
Code: wasm.Code{GoFunc: api.GoModuleFunc(func(ctx context.Context, mod api.Module, stack []uint64) {
mod = resolveMainModule(ctx, mod)
info := newExceptionInfo(api.DecodeI32(stack[0]))
if info.GetCaught(mod) == 0 {
info.SetCaught(mod, 1)
Expand Down Expand Up @@ -396,6 +399,7 @@ var CxaEndCatch = &wasm.HostFunc{
ExportName: FunctionCxaEndCatch,
Name: FunctionCxaEndCatch,
Code: wasm.Code{GoFunc: api.GoModuleFunc(func(ctx context.Context, mod api.Module, stack []uint64) {
mod = resolveMainModule(ctx, mod)
_, err := mod.ExportedFunction("setThrew").Call(ctx, 0, 0)
if err != nil {
panic(err)
Expand Down Expand Up @@ -423,6 +427,7 @@ var ResumeException = &wasm.HostFunc{
ParamNames: []string{"ptr"},
Code: wasm.Code{GoFunc: api.GoModuleFunc(func(ctx context.Context, mod api.Module, stack []uint64) {
if exceptionLast == nil {
mod = resolveMainModule(ctx, mod)
exception, err := newCppException(ctx, mod, api.DecodeI32(stack[0]))
if err != nil {
panic(err)
Expand All @@ -442,6 +447,7 @@ var CxaRethrow = &wasm.HostFunc{
if len(exceptionCaught) == 0 {
panic("no exception to throw")
}
mod = resolveMainModule(ctx, mod)

// Get the last entry and pop it from the list.
info := exceptionCaught[len(exceptionCaught)-1]
Expand Down Expand Up @@ -486,6 +492,7 @@ var CxaGetExceptionPtr = &wasm.HostFunc{
ResultTypes: []wasm.ValueType{wasm.ValueTypeI32},
ResultNames: []string{"exception_ptr"},
Code: wasm.Code{GoFunc: api.GoModuleFunc(func(ctx context.Context, mod api.Module, stack []uint64) {
mod = resolveMainModule(ctx, mod)
info := newExceptionInfo(api.DecodeI32(stack[0]))
rtn, err := info.GetExceptionPtr(ctx, mod)
if err != nil {
Expand Down Expand Up @@ -519,6 +526,7 @@ var CxaCurrentPrimaryException = &wasm.HostFunc{
stack[0] = 0
return
}
mod = resolveMainModule(ctx, mod)
info := exceptionCaught[len(exceptionCaught)-1]
_, err := mod.ExportedFunction("__cxa_increment_exception_refcount").Call(ctx, api.EncodeI32(info.excPtr))
if err != nil {
Expand All @@ -537,6 +545,7 @@ var CxaRethrowPrimaryException = &wasm.HostFunc{
ParamTypes: []wasm.ValueType{wasm.ValueTypeI32},
ParamNames: []string{"ptr"},
Code: wasm.Code{GoFunc: api.GoModuleFunc(func(ctx context.Context, mod api.Module, stack []uint64) {
mod = resolveMainModule(ctx, mod)
if stack[0] == 0 {
return
}
Expand All @@ -550,3 +559,19 @@ var CxaRethrowPrimaryException = &wasm.HostFunc{
}
})},
}

func resolveMainModule(ctx context.Context, mod api.Module) api.Module {
if mod.Name() == "" {
return mod
}

parentMod := ctx.Value(invokeFuncParentModuleKey{})
if parentMod != nil {
typedParentMod, ok := parentMod.(api.Module)
if ok {
return typedParentMod
}
}

panic(fmt.Errorf("resolveMainModule, need the main module for a host function but my module is %s and there is no parent module in the context", mod.Name()))
}

0 comments on commit 3b29107

Please sign in to comment.