perf(vm): in-place And/Or with logical-only fast path
Fold And/Or into the same in-place sp-rewrite shape as Not/LessEqual. Both args must be tLogical — short-circuit on the raw scalar field so the hot path is pure integer arithmetic + two cached bool Values. Verification - go test ./... ALL PASS - FiveSql2 test_sql1999 43/43 - tests/compat_harbour 56/56 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -209,22 +209,38 @@ func (t *Thread) Not() {
|
||||
// And pops two values, pushes logical AND.
|
||||
// Harbour evaluates both sides (no short-circuit in VM ops).
|
||||
func (t *Thread) And() {
|
||||
b := t.pop()
|
||||
a := t.pop()
|
||||
if !a.IsLogical() || !b.IsLogical() {
|
||||
panic(t.argError(".AND.", 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() == tLogical && b.Type() == tLogical {
|
||||
if a.scalar != 0 && b.scalar != 0 {
|
||||
t.stack[t.sp] = cachedTrue
|
||||
} else {
|
||||
t.stack[t.sp] = cachedFalse
|
||||
}
|
||||
t.sp++
|
||||
return
|
||||
}
|
||||
t.push(MakeBool(a.AsBool() && b.AsBool()))
|
||||
panic(t.argError(".AND.", a, b))
|
||||
}
|
||||
|
||||
// Or pops two values, pushes logical OR.
|
||||
func (t *Thread) Or() {
|
||||
b := t.pop()
|
||||
a := t.pop()
|
||||
if !a.IsLogical() || !b.IsLogical() {
|
||||
panic(t.argError(".OR.", 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() == tLogical && b.Type() == tLogical {
|
||||
if a.scalar != 0 || b.scalar != 0 {
|
||||
t.stack[t.sp] = cachedTrue
|
||||
} else {
|
||||
t.stack[t.sp] = cachedFalse
|
||||
}
|
||||
t.sp++
|
||||
return
|
||||
}
|
||||
t.push(MakeBool(a.AsBool() || b.AsBool()))
|
||||
panic(t.argError(".OR.", a, b))
|
||||
}
|
||||
|
||||
// InString implements the $ operator: "bc" $ "abcde" → .T.
|
||||
|
||||
Reference in New Issue
Block a user