diff --git a/src/core/org/luaj/vm2/LuaBoolean.java b/src/core/org/luaj/vm2/LuaBoolean.java index c8d3881f..c5b44e80 100644 --- a/src/core/org/luaj/vm2/LuaBoolean.java +++ b/src/core/org/luaj/vm2/LuaBoolean.java @@ -69,5 +69,10 @@ public class LuaBoolean extends LuaValue { public LuaValue getmetatable() { return s_metatable; - } + } + + // __eq metatag processing + public boolean eqmt( LuaValue val ) { + return s_metatable!=null && val.isboolean()? LuaValue.eqmtcall(this, val, s_metatable): false; + } } diff --git a/src/core/org/luaj/vm2/LuaDouble.java b/src/core/org/luaj/vm2/LuaDouble.java index 3b598362..1ec775f2 100644 --- a/src/core/org/luaj/vm2/LuaDouble.java +++ b/src/core/org/luaj/vm2/LuaDouble.java @@ -75,10 +75,9 @@ public class LuaDouble extends LuaNumber { public boolean equals(Object o) { return o instanceof LuaDouble? ((LuaDouble)o).v == v: false; } // arithmetic equality - public LuaValue eq( LuaValue rhs ) { return rhs.eq_b(v) || rhs.type()==TNUMBER && eqmt_b(rhs)? TRUE: FALSE; } - public boolean eq_b( LuaValue rhs ) { return rhs.eq_b(v); } - public boolean eq_b( double rhs ) { return v == rhs; } - public boolean eq_b( int rhs ) { return v == rhs; } + public boolean raweq( LuaValue val ) { return val.raweq(v); } + public boolean raweq( double val ) { return v == val; } + public boolean raweq( int val ) { return v == val; } // basic binary arithmetic public LuaValue add( LuaValue rhs ) { return rhs.add(v); } diff --git a/src/core/org/luaj/vm2/LuaFunction.java b/src/core/org/luaj/vm2/LuaFunction.java index c7c6eea7..4b5967c7 100644 --- a/src/core/org/luaj/vm2/LuaFunction.java +++ b/src/core/org/luaj/vm2/LuaFunction.java @@ -68,5 +68,8 @@ public class LuaFunction extends LuaValue { this.env = env!=null? env: NIL; } - + // __eq metatag processing + public boolean eqmt( LuaValue val ) { + return s_metatable!=null && val.isfunction()? LuaValue.eqmtcall(this, val, s_metatable): false; + } } diff --git a/src/core/org/luaj/vm2/LuaInteger.java b/src/core/org/luaj/vm2/LuaInteger.java index 9afee4a7..59b3a4e8 100644 --- a/src/core/org/luaj/vm2/LuaInteger.java +++ b/src/core/org/luaj/vm2/LuaInteger.java @@ -105,10 +105,9 @@ public class LuaInteger extends LuaNumber { public boolean equals(Object o) { return o instanceof LuaInteger? ((LuaInteger)o).v == v: false; } // arithmetic equality - public LuaValue eq( LuaValue rhs ) { return rhs.eq_b(v) || rhs.type()==TNUMBER && eqmt_b(rhs)? TRUE: FALSE; } - public boolean eq_b( LuaValue rhs ) { return rhs.eq_b(v); } - public boolean eq_b( double rhs ) { return v == rhs; } - public boolean eq_b( int rhs ) { return v == rhs; } + public boolean raweq( LuaValue val ) { return val.raweq(v); } + public boolean raweq( double val ) { return v == val; } + public boolean raweq( int val ) { return v == val; } // arithmetic operators public LuaValue add( LuaValue rhs ) { return rhs.add(v); } diff --git a/src/core/org/luaj/vm2/LuaNil.java b/src/core/org/luaj/vm2/LuaNil.java index 2c1ff6c1..f9f4b0a7 100644 --- a/src/core/org/luaj/vm2/LuaNil.java +++ b/src/core/org/luaj/vm2/LuaNil.java @@ -83,4 +83,9 @@ public class LuaNil extends LuaValue { public Object optuserdata(Object defval) { return defval; } public Object optuserdata(Class c, Object defval) { return defval; } public LuaValue optvalue(LuaValue defval) { return defval; } + + // __eq metatag processing + public boolean eqmt( LuaValue val ) { + return s_metatable!=null && val.isnil()? LuaValue.eqmtcall(this, val, s_metatable): false; + } } diff --git a/src/core/org/luaj/vm2/LuaNumber.java b/src/core/org/luaj/vm2/LuaNumber.java index d8d19a66..3fe8c6ab 100644 --- a/src/core/org/luaj/vm2/LuaNumber.java +++ b/src/core/org/luaj/vm2/LuaNumber.java @@ -67,4 +67,8 @@ public class LuaNumber extends LuaValue { public LuaValue concatTo(LuaNumber lhs) { return strvalue().concatTo(lhs.strvalue()); } public LuaValue concatTo(LuaString lhs) { return strvalue().concatTo(lhs); } + // __eq metatag processing + public boolean eqmt( LuaValue val ) { + return s_metatable!=null && val.isnumber()? LuaValue.eqmtcall(this, val, s_metatable): false; + } } diff --git a/src/core/org/luaj/vm2/LuaString.java b/src/core/org/luaj/vm2/LuaString.java index 5ccc0a27..f422ab3f 100644 --- a/src/core/org/luaj/vm2/LuaString.java +++ b/src/core/org/luaj/vm2/LuaString.java @@ -292,14 +292,16 @@ public class LuaString extends LuaValue { // object comparison, used in key comparison public boolean equals( Object o ) { if ( o instanceof LuaString ) { - return eq_b( (LuaString) o ); + return raweq( (LuaString) o ); } return false; } - public boolean eq_b( LuaString s ) { - if ( s == this ) - return true; + public boolean raweq( LuaValue val ) { + return (this == val) || val.raweq(this); + } + + public boolean raweq( LuaString s ) { if ( s.m_length != m_length ) return false; if ( s.m_bytes == m_bytes && s.m_offset == m_offset ) @@ -311,9 +313,10 @@ public class LuaString extends LuaValue { return false; return true; } - - public boolean eq_b( LuaValue val ) { - return val == this || (val.type()==TSTRING && val.eq_b(this)); + + // metatag equality + public boolean eqmt( LuaValue val ) { + return s_metatable!=null && val.type()==TSTRING? LuaValue.eqmtcall(this, val, s_metatable): false; } public static boolean equals( LuaString a, int i, LuaString b, int j, int n ) { diff --git a/src/core/org/luaj/vm2/LuaTable.java b/src/core/org/luaj/vm2/LuaTable.java index 84cad90e..6773ef7f 100644 --- a/src/core/org/luaj/vm2/LuaTable.java +++ b/src/core/org/luaj/vm2/LuaTable.java @@ -286,18 +286,6 @@ public class LuaTable extends LuaValue { public LuaValue len() { return LuaInteger.valueOf(length()); } - - public LuaValue eq( LuaValue rhs ) { - return rhs.eq_b(this)? TRUE: FALSE; - } - - public boolean eq_b( LuaValue rhs ) { - return rhs.eq_b(this); - } - - public boolean eq_b( LuaTable val ) { - return this == val || (m_metatable!=null && val.eqmt_b(this)); - } public int maxn() { int n = 0; @@ -426,7 +414,7 @@ public class LuaTable extends LuaValue { // This loop is guaranteed to terminate as long as we never allow the // table to get 100% full. LuaValue k; - while ( ( k = hashKeys[i] ) != null && !k.eq_b(key) ) { + while ( ( k = hashKeys[i] ) != null && !k.raweq(key) ) { i = ( i + 1 ) % hashKeys.length; } return i; @@ -587,4 +575,9 @@ public class LuaTable extends LuaValue { l.copyInto(a); return a; } + + // __eq metatag processing + public boolean eqmt( LuaValue val ) { + return m_metatable!=null && val.istable()? LuaValue.eqmtcall(this, m_metatable, val, val.getmetatable()): false; + } } diff --git a/src/core/org/luaj/vm2/LuaThread.java b/src/core/org/luaj/vm2/LuaThread.java index 5a8fbc96..06d94271 100644 --- a/src/core/org/luaj/vm2/LuaThread.java +++ b/src/core/org/luaj/vm2/LuaThread.java @@ -243,5 +243,9 @@ public class LuaThread extends LuaValue implements Runnable { } + // __eq metatag processing + public boolean eqmt( LuaValue val ) { + return s_metatable!=null && val.isthread()? LuaValue.eqmtcall(this, val, s_metatable): false; + } } diff --git a/src/core/org/luaj/vm2/LuaUserdata.java b/src/core/org/luaj/vm2/LuaUserdata.java index 9f07ff37..8039b36a 100644 --- a/src/core/org/luaj/vm2/LuaUserdata.java +++ b/src/core/org/luaj/vm2/LuaUserdata.java @@ -103,16 +103,15 @@ public class LuaUserdata extends LuaValue { LuaUserdata u = (LuaUserdata) val; return m_instance.equals(u.m_instance); } - - public LuaValue eq( LuaValue rhs ) { - return rhs.eq_b(this)? TRUE: FALSE; + + // equality without metatag processing + public boolean raweq( LuaValue val ) { return val.raweq(this); } + public boolean raweq( LuaUserdata val ) { + return this == val || m_instance.equals(val.m_instance); } - public boolean eq_b( LuaValue rhs ) { - return rhs.eq_b(this); - } - - public boolean eq_b( LuaUserdata val ) { - return this == val || m_instance.equals(val.m_instance) || (m_metatable!=null && val.eqmt_b(this)); + // __eq metatag processing + public boolean eqmt( LuaValue val ) { + return m_metatable!=null && val.isuserdata()? LuaValue.eqmtcall(this, m_metatable, val, val.getmetatable()): false; } } diff --git a/src/core/org/luaj/vm2/LuaValue.java b/src/core/org/luaj/vm2/LuaValue.java index 81751369..942ea9d2 100644 --- a/src/core/org/luaj/vm2/LuaValue.java +++ b/src/core/org/luaj/vm2/LuaValue.java @@ -255,21 +255,30 @@ public class LuaValue extends Varargs { // object equality, used for key comparison public boolean equals(Object obj) { return this == obj; } - // arithmetic equality - public LuaValue eq( LuaValue val ) { return this == val || eq_b(val)? TRUE: FALSE; } - public boolean eq_b( LuaValue val ) { return this == val || (type() == val.type() && eqmt_b(val)); } - public boolean eq_b( LuaTable val ) { return false; } - public boolean eq_b( LuaUserdata val ) { return false; } - public boolean eq_b( LuaString val ) { return false; } - public boolean eq_b( double val ) { return false; } - public boolean eq_b( int val ) { return false; } - public LuaValue neq( LuaValue val ) { return eq_b(val)? FALSE: TRUE; } - public boolean neq_b( LuaValue val ) { return ! eq_b(val); } - public boolean neq_b( double val ) { return ! eq_b(val); } - public boolean neq_b( int val ) { return ! eq_b(val); } - protected boolean eqmt_b( LuaValue op2 ) { - LuaValue h = metatag(EQ); - return !h.isnil() && h==op2.metatag(EQ)? h.call(this,op2).toboolean(): false; + // arithmetic equality with metatag processing + public LuaValue eq( LuaValue val ) { return raweq(val) || eqmt(val)? TRUE: FALSE; } + public LuaValue neq( LuaValue val ) { return raweq(val) || eqmt(val)? FALSE: TRUE; } + public boolean eq_b( LuaValue val ) { return raweq(val) || eqmt(val); } + public boolean neq_b( LuaValue val ) { return !(raweq(val) || eqmt(val)); } + + // equality without metatag processing + public boolean raweq( LuaValue val ) { return this == val; } + public boolean raweq( LuaUserdata val ) { return false; } + public boolean raweq( LuaString val ) { return false; } + public boolean raweq( double val ) { return false; } + public boolean raweq( int val ) { return false; } + + // __eq metatag processing + public boolean eqmt( LuaValue val ) { return false; } + public static final boolean eqmtcall(LuaValue lhs, LuaValue lhsmt, LuaValue rhs, LuaValue rhsmt) { + if ( lhsmt == null || rhsmt == null ) return false; + LuaValue h = lhsmt.rawget(EQ); + return h.isnil() || h!=rhsmt.rawget(EQ)? false: h.call(lhs,rhs).toboolean(); + } + public static final boolean eqmtcall(LuaValue lhs, LuaValue rhs, LuaValue sharedmt) { + if ( sharedmt == null ) return false; + LuaValue h = sharedmt.rawget(EQ); + return h.isnil()? false: h.call(lhs,rhs).toboolean(); } // arithmetic operators diff --git a/src/core/org/luaj/vm2/WeakTable.java b/src/core/org/luaj/vm2/WeakTable.java index 2023c846..beef71fd 100644 --- a/src/core/org/luaj/vm2/WeakTable.java +++ b/src/core/org/luaj/vm2/WeakTable.java @@ -137,7 +137,7 @@ public class WeakTable extends LuaTable { return 0; } else { - if ( k.eq_b(key) ) + if ( k.raweq(key) ) return i; i = ( i + 1 ) % hashKeys.length; } @@ -205,9 +205,9 @@ public class WeakTable extends LuaTable { return o!=null? (LuaValue)o: NIL; } - public boolean eq_b(LuaValue rhs) { + public boolean raweq(LuaValue rhs) { Object o = ref.get(); - return o!=null && rhs.eq_b((LuaValue)o); + return o!=null && rhs.raweq((LuaValue)o); } public boolean isweaknil() { @@ -233,11 +233,11 @@ public class WeakTable extends LuaTable { return o!=null? userdataOf(o,mt): NIL; } - public boolean eq_b(LuaValue rhs) { + public boolean raweq(LuaValue rhs) { if ( ! rhs.isuserdata() ) return false; LuaValue v = (LuaValue) ref.get(); - if ( v != null && v.eq_b(rhs) ) + if ( v != null && v.raweq(rhs) ) return true; return rhs.touserdata() == ob.get(); } @@ -287,15 +287,11 @@ public class WeakTable extends LuaTable { return keyhash; } - public boolean eq_b(LuaValue rhs) { - //return rhs.eq_b(weakkey.strongvalue()); - return weakkey.eq_b(rhs); + public boolean raweq(LuaValue rhs) { + //return rhs.raweq(weakkey.strongvalue()); + return weakkey.raweq(rhs); } - public boolean eq_b( LuaString rhs ) { return false; } - public boolean eq_b( double val ) { return false; } - public boolean eq_b( int val ) { return false; } - public boolean isweaknil() { return weakkey.isweaknil() || weakvalue.isweaknil(); }