github.com/cloudwego/frugal@v0.1.15/internal/binary/encoder/linker_emu.go (about) 1 /* 2 * Copyright 2022 ByteDance Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package encoder 18 19 import ( 20 `unsafe` 21 22 `github.com/cloudwego/frugal/internal/atm/emu` 23 `github.com/cloudwego/frugal/internal/atm/hir` 24 `github.com/cloudwego/frugal/internal/rt` 25 `github.com/cloudwego/frugal/iov` 26 ) 27 28 func link_emu(prog hir.Program) Encoder { 29 return func(buf unsafe.Pointer, len int, mem iov.BufferWriter, p unsafe.Pointer, rs *RuntimeState, st int) (ret int, err error) { 30 ctx := emu.LoadProgram(prog) 31 exc := (*rt.GoIface)(unsafe.Pointer(&err)) 32 iop := (*rt.GoIface)(unsafe.Pointer(&mem)) 33 ctx.Ap(0,buf) 34 ctx.Au(1, uint64(len)) 35 ctx.Ap(2, unsafe.Pointer(iop.Itab)) 36 ctx.Ap(3, iop.Value) 37 ctx.Ap(4, p) 38 ctx.Ap(5, unsafe.Pointer(rs)) 39 ctx.Au(6, uint64(st)) 40 ctx.Run() 41 ret = int(ctx.Ru(0)) 42 exc.Itab = (*rt.GoItab)(ctx.Rp(1)) 43 exc.Value = ctx.Rp(2) 44 ctx.Free() 45 return 46 } 47 } 48 49 func emu_wbuf(ctx hir.CallContext, i int) (v iov.BufferWriter) { 50 (*rt.GoIface)(unsafe.Pointer(&v)).Itab = (*rt.GoItab)(ctx.Ap(i)) 51 (*rt.GoIface)(unsafe.Pointer(&v)).Value = ctx.Ap(i + 1) 52 return 53 } 54 55 func emu_setret(ctx hir.CallContext) func(int, error) { 56 return func(ret int, err error) { 57 vv := (*rt.GoIface)(unsafe.Pointer(&err)) 58 ctx.Ru(0, uint64(ret)) 59 ctx.Rp(1, unsafe.Pointer(vv.Itab)) 60 ctx.Rp(2, vv.Value) 61 } 62 } 63 64 func emu_encode(ctx hir.CallContext) (int, error) { 65 return encode( 66 (*rt.GoType)(ctx.Ap(0)), 67 ctx.Ap(1), 68 int(ctx.Au(2)), 69 emu_wbuf(ctx, 3), 70 ctx.Ap(5), 71 (*RuntimeState)(ctx.Ap(6)), 72 int(ctx.Au(7)), 73 ) 74 } 75 76 func emu_gcall_encode(ctx hir.CallContext) { 77 if !ctx.Verify("**i****i", "i**") { 78 panic("invalid encode call") 79 } else { 80 emu_setret(ctx)(emu_encode(ctx)) 81 } 82 }