mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 04:22:25 -05:00 
			
		
		
		
	
		
			
	
	
		
			75 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			75 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:]) | ||
|  | } |