mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-03 21:32:24 -06: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:])
							 | 
						||
| 
								 | 
							
								}
							 |