wa-lang.org/wazero@v1.0.2/internal/engine/compiler/compiler_conditional_save_test.go (about) 1 package compiler 2 3 import ( 4 "testing" 5 6 "wa-lang.org/wazero/internal/testing/require" 7 "wa-lang.org/wazero/internal/wazeroir" 8 ) 9 10 // TestCompiler_conditional_value_saving ensure that saving conditional register works correctly even if there's 11 // no free registers available. 12 func TestCompiler_conditional_value_saving(t *testing.T) { 13 env := newCompilerEnvironment() 14 compiler := env.requireNewCompiler(t, newCompiler, nil) 15 err := compiler.compilePreamble() 16 require.NoError(t, err) 17 18 // Place the f32 local. 19 err = compiler.compileConstF32(&wazeroir.OperationConstF32{Value: 1.0}) 20 require.NoError(t, err) 21 22 // Generate constants to occupy all the unreserved GP registers. 23 for i := 0; i < len(unreservedGeneralPurposeRegisters); i++ { 24 err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: 100}) 25 require.NoError(t, err) 26 } 27 28 // Pick the f32 floating point local (1.0) twice. 29 // Note that the f32 (function local variable in general) is placed above the call frame. 30 err = compiler.compilePick(&wazeroir.OperationPick{Depth: int(compiler.runtimeValueLocationStack().sp - 1 - callFrameDataSizeInUint64)}) 31 32 require.NoError(t, err) 33 err = compiler.compilePick(&wazeroir.OperationPick{Depth: int(compiler.runtimeValueLocationStack().sp - 1 - callFrameDataSizeInUint64)}) 34 35 require.NoError(t, err) 36 // Generate conditional flag via floating point comparisons. 37 err = compiler.compileLe(&wazeroir.OperationLe{Type: wazeroir.SignedTypeFloat32}) 38 require.NoError(t, err) 39 40 // Ensures that we have conditional value at top of stack. 41 l := compiler.runtimeValueLocationStack().peek() 42 require.True(t, l.onConditionalRegister()) 43 44 // Ensures that no free registers are available. 45 _, ok := compiler.runtimeValueLocationStack().takeFreeRegister(registerTypeGeneralPurpose) 46 require.False(t, ok) 47 48 // We should be able to use the conditional value (an i32 value in Wasm) as an operand for, say, i32.add. 49 err = compiler.compileAdd(&wazeroir.OperationAdd{Type: wazeroir.UnsignedTypeI32}) 50 require.NoError(t, err) 51 52 err = compiler.compileReturnFunction() 53 require.NoError(t, err) 54 55 // Generate and run the code under test. 56 code, _, err := compiler.compile() 57 require.NoError(t, err) 58 env.exec(code) 59 60 // expect 101 = 100(== the integer const) + 1 (== flag value == the result of (1.0 <= 1.0)) 61 require.Equal(t, uint32(101), env.stackTopAsUint32()) 62 }