mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-03 23:02:24 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			74 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			74 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package wasm
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
 | 
						|
	"github.com/tetratelabs/wazero/api"
 | 
						|
	"github.com/tetratelabs/wazero/experimental"
 | 
						|
)
 | 
						|
 | 
						|
type snapshotskey struct{}
 | 
						|
 | 
						|
// withSetjmpLongjmp updates the context to contain wazero/experimental.Snapshotter{} support,
 | 
						|
// and embeds the necessary snapshots map required for later calls to Setjmp() / Longjmp().
 | 
						|
func withSetjmpLongjmp(ctx context.Context) context.Context {
 | 
						|
	snapshots := make(map[uint32]experimental.Snapshot, 10)
 | 
						|
	ctx = experimental.WithSnapshotter(ctx)
 | 
						|
	ctx = context.WithValue(ctx, snapshotskey{}, snapshots)
 | 
						|
	return ctx
 | 
						|
}
 | 
						|
 | 
						|
func getSnapshots(ctx context.Context) map[uint32]experimental.Snapshot {
 | 
						|
	v, _ := ctx.Value(snapshotskey{}).(map[uint32]experimental.Snapshot)
 | 
						|
	return v
 | 
						|
}
 | 
						|
 | 
						|
// setjmp implements the C function: setjmp(env jmp_buf)
 | 
						|
func setjmp(ctx context.Context, mod api.Module, stack []uint64) {
 | 
						|
 | 
						|
	// Input arguments.
 | 
						|
	envptr := api.DecodeU32(stack[0])
 | 
						|
 | 
						|
	// Take snapshot of current execution environment.
 | 
						|
	snapshotter := experimental.GetSnapshotter(ctx)
 | 
						|
	snapshot := snapshotter.Snapshot()
 | 
						|
 | 
						|
	// Get stored snapshots map.
 | 
						|
	snapshots := getSnapshots(ctx)
 | 
						|
	if snapshots == nil {
 | 
						|
		panic("setjmp / longjmp not supported")
 | 
						|
	}
 | 
						|
 | 
						|
	// Set latest snapshot in map.
 | 
						|
	snapshots[envptr] = snapshot
 | 
						|
 | 
						|
	// Set return.
 | 
						|
	stack[0] = 0
 | 
						|
}
 | 
						|
 | 
						|
// longjmp implements the C function: int longjmp(env jmp_buf, value int)
 | 
						|
func longjmp(ctx context.Context, mod api.Module, stack []uint64) {
 | 
						|
 | 
						|
	// Input arguments.
 | 
						|
	envptr := api.DecodeU32(stack[0])
 | 
						|
	// val := stack[1]
 | 
						|
 | 
						|
	// Get stored snapshots map.
 | 
						|
	snapshots := getSnapshots(ctx)
 | 
						|
	if snapshots == nil {
 | 
						|
		panic("setjmp / longjmp not supported")
 | 
						|
	}
 | 
						|
 | 
						|
	// Get snapshot stored in map.
 | 
						|
	snapshot := snapshots[envptr]
 | 
						|
	if snapshot == nil {
 | 
						|
		panic("must first call setjmp")
 | 
						|
	}
 | 
						|
 | 
						|
	// Set return.
 | 
						|
	stack[0] = 0
 | 
						|
 | 
						|
	// Restore execution and
 | 
						|
	// return passed value arg.
 | 
						|
	snapshot.Restore(stack[1:])
 | 
						|
}
 |