From 4e58bd74116499165614dc7561af43e9c2a2e169 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Tue, 25 Oct 2022 18:20:55 +0300 Subject: [PATCH] compiler: use shorter and cheaper sequence to convert to Boolean --- pkg/compiler/codegen.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 871433851..f21d421c4 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -1945,10 +1945,16 @@ func transformArgs(fs *funcScope, fun ast.Expr, isBuiltin bool, args []ast.Expr) // emitConvert converts the top stack item to the specified type. func (c *codegen) emitConvert(typ stackitem.Type) { - emit.Opcodes(c.prog.BinWriter, opcode.DUP) - emit.Instruction(c.prog.BinWriter, opcode.ISTYPE, []byte{byte(typ)}) - emit.Instruction(c.prog.BinWriter, opcode.JMPIF, []byte{2 + 2}) // After CONVERT. - emit.Instruction(c.prog.BinWriter, opcode.CONVERT, []byte{byte(typ)}) + if typ == stackitem.BooleanT { + // DUP + ISTYPE + JMPIF costs 3 already with CONVERT of a cost 8192. + // NOT+NOT at the same time costs 4 and always works (and is shorter). + emit.Opcodes(c.prog.BinWriter, opcode.NOT, opcode.NOT) + } else { + emit.Opcodes(c.prog.BinWriter, opcode.DUP) + emit.Instruction(c.prog.BinWriter, opcode.ISTYPE, []byte{byte(typ)}) + emit.Instruction(c.prog.BinWriter, opcode.JMPIF, []byte{2 + 2}) // After CONVERT. + emit.Instruction(c.prog.BinWriter, opcode.CONVERT, []byte{byte(typ)}) + } } func (c *codegen) convertByteArray(elems []ast.Expr) {