diff --git a/hbrt/ops_compare.go b/hbrt/ops_compare.go index 9f6693c..8982c83 100644 --- a/hbrt/ops_compare.go +++ b/hbrt/ops_compare.go @@ -22,9 +22,26 @@ import "strings" // Equal pops two values, pushes boolean result. // Harbour: hb_vmEqual (hvm.c:3974) func (t *Thread) Equal() { - b := t.pop() - a := t.pop() - t.push(MakeBool(valueEqual(a, b))) + t.sp -= 2 + a := t.stack[t.sp] + b := t.stack[t.sp+1] + t.stack[t.sp+1] = cachedNil + // Fast path: Int == Int + if a.Type() == tInt && b.Type() == tInt { + if int64(a.scalar) == int64(b.scalar) { + t.stack[t.sp] = cachedTrue + } else { + t.stack[t.sp] = cachedFalse + } + t.sp++ + return + } + if valueEqual(a, b) { + t.stack[t.sp] = cachedTrue + } else { + t.stack[t.sp] = cachedFalse + } + t.sp++ } // ExactEqual pops two values, pushes boolean result. @@ -37,9 +54,25 @@ func (t *Thread) ExactEqual() { // NotEqual pops two values, pushes boolean result. func (t *Thread) NotEqual() { - b := t.pop() - a := t.pop() - t.push(MakeBool(!valueEqual(a, b))) + t.sp -= 2 + a := t.stack[t.sp] + b := t.stack[t.sp+1] + t.stack[t.sp+1] = cachedNil + if a.Type() == tInt && b.Type() == tInt { + if int64(a.scalar) != int64(b.scalar) { + t.stack[t.sp] = cachedTrue + } else { + t.stack[t.sp] = cachedFalse + } + t.sp++ + return + } + if !valueEqual(a, b) { + t.stack[t.sp] = cachedTrue + } else { + t.stack[t.sp] = cachedFalse + } + t.sp++ } // --- Relational operators --- @@ -47,13 +80,29 @@ func (t *Thread) NotEqual() { // Less pops two values, pushes boolean result. // Harbour: hb_vmLess (hvm.c:4176) func (t *Thread) Less() { - b := t.pop() - a := t.pop() + t.sp -= 2 + a := t.stack[t.sp] + b := t.stack[t.sp+1] + t.stack[t.sp+1] = cachedNil + if a.Type() == tInt && b.Type() == tInt { + if int64(a.scalar) < int64(b.scalar) { + t.stack[t.sp] = cachedTrue + } else { + t.stack[t.sp] = cachedFalse + } + t.sp++ + return + } cmp, ok := valueCompare(a, b) if !ok { panic(t.argError("<", a, b)) } - t.push(MakeBool(cmp < 0)) + if cmp < 0 { + t.stack[t.sp] = cachedTrue + } else { + t.stack[t.sp] = cachedFalse + } + t.sp++ } // LessEqual pops two values, pushes boolean result. @@ -86,24 +135,56 @@ func (t *Thread) LessEqual() { // Greater pops two values, pushes boolean result. func (t *Thread) Greater() { - b := t.pop() - a := t.pop() + t.sp -= 2 + a := t.stack[t.sp] + b := t.stack[t.sp+1] + t.stack[t.sp+1] = cachedNil + if a.Type() == tInt && b.Type() == tInt { + if int64(a.scalar) > int64(b.scalar) { + t.stack[t.sp] = cachedTrue + } else { + t.stack[t.sp] = cachedFalse + } + t.sp++ + return + } cmp, ok := valueCompare(a, b) if !ok { panic(t.argError(">", a, b)) } - t.push(MakeBool(cmp > 0)) + if cmp > 0 { + t.stack[t.sp] = cachedTrue + } else { + t.stack[t.sp] = cachedFalse + } + t.sp++ } // GreaterEqual pops two values, pushes boolean result. func (t *Thread) GreaterEqual() { - b := t.pop() - a := t.pop() + t.sp -= 2 + a := t.stack[t.sp] + b := t.stack[t.sp+1] + t.stack[t.sp+1] = cachedNil + if a.Type() == tInt && b.Type() == tInt { + if int64(a.scalar) >= int64(b.scalar) { + t.stack[t.sp] = cachedTrue + } else { + t.stack[t.sp] = cachedFalse + } + t.sp++ + return + } cmp, ok := valueCompare(a, b) if !ok { panic(t.argError(">=", a, b)) } - t.push(MakeBool(cmp >= 0)) + if cmp >= 0 { + t.stack[t.sp] = cachedTrue + } else { + t.stack[t.sp] = cachedFalse + } + t.sp++ } // --- Logical operators ---