github.com/cloudwego/frugal@v0.1.15/internal/atm/emu/emu_test.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 emu 18 19 import ( 20 `testing` 21 `unsafe` 22 23 `github.com/cloudwego/frugal/internal/atm/hir` 24 `github.com/davecgh/go-spew/spew` 25 ) 26 27 var ( 28 testfn = hir.RegisterGCall(testemu_pfunc, func(ctx hir.CallContext) { 29 var v0 struct {P unsafe.Pointer; L uint64} 30 var v1 struct {P unsafe.Pointer; L uint64} 31 var v2 struct {P unsafe.Pointer; L uint64} 32 if !ctx.Verify("*i*i*i", "*i*i") { 33 panic("invalid testemu_pfunc call") 34 } 35 v0.P = ctx.Ap(0) 36 v0.L = ctx.Au(1) 37 v1.P = ctx.Ap(2) 38 v1.L = ctx.Au(3) 39 v2.P = ctx.Ap(4) 40 v2.L = ctx.Au(5) 41 r0, r1 := testemu_pfunc( 42 *(*string)(unsafe.Pointer(&v0)), 43 *(*string)(unsafe.Pointer(&v1)), 44 *(*string)(unsafe.Pointer(&v2)), 45 ) 46 ctx.Ru(1, uint64(len(r0))) 47 ctx.Ru(3, uint64(len(r1))) 48 ctx.Rp(0, *(*unsafe.Pointer)(unsafe.Pointer(&r0))) 49 ctx.Rp(2, *(*unsafe.Pointer)(unsafe.Pointer(&r1))) 50 }) 51 ) 52 53 func testemu_pfunc(a string, b string, c string) (d string, e string) { 54 d = a + b 55 e = b + c 56 return 57 } 58 59 func runEmulator(init func(emu *Emulator), prog func(p *hir.Builder)) *Emulator { 60 pb := hir.CreateBuilder() 61 prog(pb) 62 emu := LoadProgram(pb.Build()) 63 if init != nil { 64 init(emu) 65 } 66 emu.Run() 67 return emu 68 } 69 70 func TestEmu_OpCode_GCALL(t *testing.T) { 71 a := "aaa" 72 b := "bbb" 73 c := "ccc" 74 emu := runEmulator(nil, func(p *hir.Builder) { 75 p.IP(&a, hir.P0) 76 p.IP(&b, hir.P1) 77 p.IP(&c, hir.P2) 78 p.LQ(hir.P0, 8, hir.R0) 79 p.LP(hir.P0, 0, hir.P0) 80 p.LQ(hir.P1, 8, hir.R1) 81 p.LP(hir.P1, 0, hir.P1) 82 p.LQ(hir.P2, 8, hir.R2) 83 p.LP(hir.P2, 0, hir.P2) 84 p.GCALL(testfn).A0(hir.P0).A1(hir.R0).A2(hir.P1).A3(hir.R1).A4(hir.P2).A5(hir.R2).R0(hir.P0).R1(hir.R0).R2(hir.P1).R3(hir.R1) 85 p.RET().R0(hir.P0).R1(hir.R0).R2(hir.P1).R3(hir.R1) 86 }) 87 val := [2]struct{P unsafe.Pointer; L uint64} { 88 {P: emu.Rp(0), L: emu.Ru(1)}, 89 {P: emu.Rp(2), L: emu.Ru(3)}, 90 } 91 spew.Dump(*(*[2]string)(unsafe.Pointer(&val))) 92 }