diff --git a/src/core/org/luaj/vm2/LuaBoolean.java b/src/core/org/luaj/vm2/LuaBoolean.java index c5b44e80..58b7a22a 100644 --- a/src/core/org/luaj/vm2/LuaBoolean.java +++ b/src/core/org/luaj/vm2/LuaBoolean.java @@ -71,8 +71,8 @@ public class LuaBoolean extends LuaValue { return s_metatable; } - // __eq metatag processing - public boolean eqmt( LuaValue val ) { - return s_metatable!=null && val.isboolean()? LuaValue.eqmtcall(this, val, s_metatable): false; + // equality + public boolean eq_b( LuaValue val ) { + return this == val || (s_metatable!=null && val.isboolean() && LuaValue.eqmtcall(this, val, s_metatable)); } } diff --git a/src/core/org/luaj/vm2/LuaDouble.java b/src/core/org/luaj/vm2/LuaDouble.java index 1ec775f2..912c6a4b 100644 --- a/src/core/org/luaj/vm2/LuaDouble.java +++ b/src/core/org/luaj/vm2/LuaDouble.java @@ -74,7 +74,10 @@ public class LuaDouble extends LuaNumber { // object equality, used for key comparison public boolean equals(Object o) { return o instanceof LuaDouble? ((LuaDouble)o).v == v: false; } - // arithmetic equality + // equality w/ metatable processing + public boolean eq_b( LuaValue val ) { return val.raweq(v) || (s_metatable!=null && val.type()==TNUMBER && LuaValue.eqmtcall(val, this, s_metatable)); } + + // equality w/o metatable processing 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; } diff --git a/src/core/org/luaj/vm2/LuaFunction.java b/src/core/org/luaj/vm2/LuaFunction.java index 4b5967c7..0d1ec3c3 100644 --- a/src/core/org/luaj/vm2/LuaFunction.java +++ b/src/core/org/luaj/vm2/LuaFunction.java @@ -68,8 +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; - } + // equality + public boolean eq_b( LuaValue val ) { + return this == val || (s_metatable!=null && val.isfunction() && LuaValue.eqmtcall(this, val, s_metatable)); + } } diff --git a/src/core/org/luaj/vm2/LuaInteger.java b/src/core/org/luaj/vm2/LuaInteger.java index 59b3a4e8..b985cea3 100644 --- a/src/core/org/luaj/vm2/LuaInteger.java +++ b/src/core/org/luaj/vm2/LuaInteger.java @@ -104,10 +104,13 @@ public class LuaInteger extends LuaNumber { // object equality, used for key comparison public boolean equals(Object o) { return o instanceof LuaInteger? ((LuaInteger)o).v == v: false; } - // arithmetic equality - 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; } + // equality w/ metatable processing + public boolean eq_b( LuaValue val ) { return val.raweq(v) || (s_metatable!=null && val.type()==TNUMBER && LuaValue.eqmtcall(val, this, s_metatable)); } + + // equality w/o metatable processing + 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 f9f4b0a7..772bc4d1 100644 --- a/src/core/org/luaj/vm2/LuaNil.java +++ b/src/core/org/luaj/vm2/LuaNil.java @@ -84,8 +84,7 @@ public class LuaNil extends LuaValue { 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; - } + // equality + public LuaValue eq( LuaValue val ) { return this == val? TRUE: FALSE; } + public boolean eq_b( LuaValue val ) { return this == val; } } diff --git a/src/core/org/luaj/vm2/LuaNumber.java b/src/core/org/luaj/vm2/LuaNumber.java index 3fe8c6ab..d8d19a66 100644 --- a/src/core/org/luaj/vm2/LuaNumber.java +++ b/src/core/org/luaj/vm2/LuaNumber.java @@ -67,8 +67,4 @@ 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 f422ab3f..615c0f16 100644 --- a/src/core/org/luaj/vm2/LuaString.java +++ b/src/core/org/luaj/vm2/LuaString.java @@ -297,11 +297,27 @@ public class LuaString extends LuaValue { return false; } + // equality w/ metatable processing + public boolean eq_b( LuaValue val ) { + if ( val.raweq(this) ) return true; + if ( s_metatable == null || val.type()!=TSTRING || s_inmeta) return false; + s_inmeta = true; + try { + return LuaValue.eqmtcall(val, this, s_metatable); + } finally { + s_inmeta = false; + } + } + private static boolean s_inmeta = false; + + // equality w/o metatable processing public boolean raweq( LuaValue val ) { - return (this == val) || val.raweq(this); + return val.raweq(this); } public boolean raweq( LuaString s ) { + if ( this == s ) + return true; if ( s.m_length != m_length ) return false; if ( s.m_bytes == m_bytes && s.m_offset == m_offset ) @@ -314,11 +330,6 @@ public class LuaString extends LuaValue { return true; } - // 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 ) { return equals( a.m_bytes, a.m_offset + i, b.m_bytes, b.m_offset + j, n ); } diff --git a/src/core/org/luaj/vm2/LuaTable.java b/src/core/org/luaj/vm2/LuaTable.java index 6773ef7f..905d22fc 100644 --- a/src/core/org/luaj/vm2/LuaTable.java +++ b/src/core/org/luaj/vm2/LuaTable.java @@ -576,8 +576,11 @@ public class LuaTable extends LuaValue { 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; + // equality w/ metatable processing + public boolean eq_b( LuaValue val ) { + if ( this == val ) return true; + if ( m_metatable == null || !val.istable() ) return false; + LuaValue valmt = val.getmetatable(); + return valmt!=null && LuaValue.eqmtcall(this, m_metatable, val, valmt); } } diff --git a/src/core/org/luaj/vm2/LuaThread.java b/src/core/org/luaj/vm2/LuaThread.java index 06d94271..ff145ed7 100644 --- a/src/core/org/luaj/vm2/LuaThread.java +++ b/src/core/org/luaj/vm2/LuaThread.java @@ -243,9 +243,8 @@ 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; - } - + // equality + public boolean eq_b( LuaValue val ) { + return this == val || (s_metatable!=null && val.isthread() && LuaValue.eqmtcall(this, val, s_metatable)); + } } diff --git a/src/core/org/luaj/vm2/LuaUserdata.java b/src/core/org/luaj/vm2/LuaUserdata.java index 8039b36a..d7d79d14 100644 --- a/src/core/org/luaj/vm2/LuaUserdata.java +++ b/src/core/org/luaj/vm2/LuaUserdata.java @@ -104,10 +104,19 @@ public class LuaUserdata extends LuaValue { return m_instance.equals(u.m_instance); } - // equality without metatag processing + // equality w/ metatable processing + public LuaValue eq( LuaValue val ) { return val.eq_b(this)? TRUE: FALSE; } + public boolean eq_b( LuaUserdata val ) { + if ( val.raweq(this) ) return true; + if ( m_metatable == null || !val.isuserdata() ) return false; + LuaValue valmt = val.getmetatable(); + return valmt!=null && LuaValue.eqmtcall(this, m_metatable, val, valmt); + } + + // equality w/o metatable 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 raweq( LuaUserdata val ) { + return this == val || (m_metatable == val.m_metatable && m_instance.equals(val.m_instance)); } // __eq metatag processing diff --git a/src/core/org/luaj/vm2/LuaValue.java b/src/core/org/luaj/vm2/LuaValue.java index 942ea9d2..f8b93e19 100644 --- a/src/core/org/luaj/vm2/LuaValue.java +++ b/src/core/org/luaj/vm2/LuaValue.java @@ -256,10 +256,10 @@ public class LuaValue extends Varargs { public boolean equals(Object obj) { return this == obj; } // 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)); } + public LuaValue eq( LuaValue val ) { return eq_b(val)? TRUE: FALSE; } + public boolean eq_b( LuaValue val ) { return false; } + public LuaValue neq( LuaValue val ) { return eq_b(val)? FALSE: TRUE; } + public boolean neq_b( LuaValue val ) { return !eq_b(val); } // equality without metatag processing public boolean raweq( LuaValue val ) { return this == val; } @@ -269,14 +269,11 @@ public class LuaValue extends Varargs { 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(); }