aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMeng-Ying Yang <garfield@dexon.org>2019-04-16 17:13:40 +0800
committerMeng-Ying Yang <garfield@dexon.org>2019-05-09 09:29:30 +0800
commitf60d57ffc915e9a4131da02a743763603332c8b3 (patch)
tree90e81aaf7fe580b2aeb10df00d8e34e2098f8b08
parent26abaf0894500bbe30d0c931b8429ef7a02b7a90 (diff)
downloaddexon-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.go20
-rw-r--r--core/vm/sqlvm/runtime/instructions_op_test.go62
-rw-r--r--core/vm/sqlvm/runtime/instructions_tmpl_data.go62
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
},
}