diff options
author | Meng-Ying Yang <garfield@dexon.org> | 2019-04-16 17:13:40 +0800 |
---|---|---|
committer | Meng-Ying Yang <garfield@dexon.org> | 2019-05-09 09:29:30 +0800 |
commit | f60d57ffc915e9a4131da02a743763603332c8b3 (patch) | |
tree | 90e81aaf7fe580b2aeb10df00d8e34e2098f8b08 | |
parent | 26abaf0894500bbe30d0c931b8429ef7a02b7a90 (diff) | |
download | dexon-f60d57ffc915e9a4131da02a743763603332c8b3.tar.gz dexon-f60d57ffc915e9a4131da02a743763603332c8b3.tar.zst dexon-f60d57ffc915e9a4131da02a743763603332c8b3.zip |
core: vm: sqlvm: add built-in function BITXOR()
-rw-r--r-- | core/vm/sqlvm/runtime/functions.go | 20 | ||||
-rw-r--r-- | core/vm/sqlvm/runtime/instructions_op_test.go | 62 | ||||
-rw-r--r-- | core/vm/sqlvm/runtime/instructions_tmpl_data.go | 62 |
3 files changed, 144 insertions, 0 deletions
diff --git a/core/vm/sqlvm/runtime/functions.go b/core/vm/sqlvm/runtime/functions.go index 26e2d0d91..7b062fdee 100644 --- a/core/vm/sqlvm/runtime/functions.go +++ b/core/vm/sqlvm/runtime/functions.go @@ -28,6 +28,7 @@ const ( RAND BITAND BITOR + BITXOR ) type fn func(*common.Context, []*Operand, uint64) (*Operand, error) @@ -46,6 +47,7 @@ var ( RAND: fnRand, BITAND: fnBitAnd, BITOR: fnBitOr, + BITXOR: fnBitXor, } ) @@ -336,3 +338,21 @@ func fnBitOr(ctx *common.Context, ops []*Operand, length uint64) (result *Operan } return } + +func fnBitXor(ctx *common.Context, ops []*Operand, length uint64) (result *Operand, err error) { + n, op1, op2, err := extractOps(ops) + if err != nil { + return + } + + result = op1.clone(true) + result.Data = make([]Tuple, n) + for i := 0; i < n; i++ { + result.Data[i] = op1.Data[i].bitBinOp( + op2.Data[i], + op1.Meta, + func(b1, b2 byte) byte { return b1 ^ b2 }, + ) + } + return +} diff --git a/core/vm/sqlvm/runtime/instructions_op_test.go b/core/vm/sqlvm/runtime/instructions_op_test.go index 14c8d853d..42f5074db 100644 --- a/core/vm/sqlvm/runtime/instructions_op_test.go +++ b/core/vm/sqlvm/runtime/instructions_op_test.go @@ -3817,3 +3817,65 @@ func (s *instructionSuite) TestOpFuncBitOr() { s.run(testcases, opFunc) } + +func (s *instructionSuite) TestOpFuncBitXor() { + testcases := []opTestcase{ + { + "Func BitXor", + Instruction{ + Op: FUNC, + Input: []*Operand{ + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(ast.DataTypeMajorUint, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(2)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(ast.DataTypeMajorUint, 1), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(12)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(ast.DataTypeMajorUint, 0), ast.ComposeDataType(ast.DataTypeMajorUint, 0), ast.ComposeDataType(ast.DataTypeMajorInt, 0), ast.ComposeDataType(ast.DataTypeMajorInt, 0), ast.ComposeDataType(ast.DataTypeMajorFixedBytes, 0), ast.ComposeDataType(ast.DataTypeMajorFixedBytes, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-128)}, &Raw{Bytes: []byte{0x12, 0x34}}, &Raw{Bytes: []byte{0x56, 0x78}}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(ast.DataTypeMajorUint, 0), ast.ComposeDataType(ast.DataTypeMajorUint, 0), ast.ComposeDataType(ast.DataTypeMajorInt, 0), ast.ComposeDataType(ast.DataTypeMajorInt, 0), ast.ComposeDataType(ast.DataTypeMajorFixedBytes, 0), ast.ComposeDataType(ast.DataTypeMajorFixedBytes, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(6)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Bytes: []byte{0xff, 0xff}}, &Raw{Bytes: []byte{0x00, 0x00}}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(ast.DataTypeMajorUint, 0), ast.ComposeDataType(ast.DataTypeMajorUint, 0), ast.ComposeDataType(ast.DataTypeMajorInt, 0), ast.ComposeDataType(ast.DataTypeMajorInt, 0), ast.ComposeDataType(ast.DataTypeMajorFixedBytes, 0), ast.ComposeDataType(ast.DataTypeMajorFixedBytes, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(4)}, &Raw{Value: decimal.NewFromFloat(4)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(126)}, &Raw{Bytes: []byte{0xed, 0xcb}}, &Raw{Bytes: []byte{0x56, 0x78}}}, + }, + ), + nil, + }, + } + + s.run(testcases, opFunc) +} diff --git a/core/vm/sqlvm/runtime/instructions_tmpl_data.go b/core/vm/sqlvm/runtime/instructions_tmpl_data.go index 3d92346f9..c0928615f 100644 --- a/core/vm/sqlvm/runtime/instructions_tmpl_data.go +++ b/core/vm/sqlvm/runtime/instructions_tmpl_data.go @@ -2722,5 +2722,67 @@ var testData = &tmplData{ }, }, // -- end of FUNC BITOR + { + TestName: "OpFuncBitXor", OpFunc: "opFunc", + Cases: []*tmplTestCase{ + { + Name: "Func BitXor", + Error: "nil", OpCode: "FUNC", + Inputs: []*tmplOp{ + { + Im: true, + Metas: []*tmplOpMeta{ + {Major: "Uint", Minor: 0}, + }, + Data: []string{`{V: 2}`}, + }, + { + Im: true, + Metas: []*tmplOpMeta{ + {Major: "Uint", Minor: 1}, + }, + Data: []string{`{V: 12}`}, + }, + { + Im: false, + Metas: []*tmplOpMeta{ + {Major: "Uint", Minor: 0}, + {Major: "Uint", Minor: 0}, + {Major: "Int", Minor: 0}, + {Major: "Int", Minor: 0}, + {Major: "FixedBytes", Minor: 0}, + {Major: "FixedBytes", Minor: 0}, + }, + Data: []string{"{V: 1, V: 2, V: -1, V: -128, B: {0x12, 0x34}, B: {0x56, 0x78}}"}, + }, + { + Im: false, + Metas: []*tmplOpMeta{ + {Major: "Uint", Minor: 0}, + {Major: "Uint", Minor: 0}, + {Major: "Int", Minor: 0}, + {Major: "Int", Minor: 0}, + {Major: "FixedBytes", Minor: 0}, + {Major: "FixedBytes", Minor: 0}, + }, + Data: []string{"{V: 5, V: 6, V: -2, V: -2, B: {0xff, 0xff}, B:{0x00, 0x00}}"}, + }, + }, + Output: &tmplOp{ + Im: false, + Metas: []*tmplOpMeta{ + {Major: "Uint", Minor: 0}, + {Major: "Uint", Minor: 0}, + {Major: "Int", Minor: 0}, + {Major: "Int", Minor: 0}, + {Major: "FixedBytes", Minor: 0}, + {Major: "FixedBytes", Minor: 0}, + }, + Data: []string{`{V: 4, V: 4, V: 1, V: 126, B: {0xed, 0xcb}, B: {0x56, 0x78}}`}, + }, + }, + }, + }, + // -- end of FUNC BITXOR }, } |