diff --git a/std/assembly/object.ts b/std/assembly/object.ts index c9543fe3df..8a44e6462e 100644 --- a/std/assembly/object.ts +++ b/std/assembly/object.ts @@ -1,21 +1,22 @@ export class Object { - static is(value1: T, value2: T): bool { + static is(x: T, y: T): bool { if (isFloat()) { - if (value1 == value2) { - // 0 == -0, but they are not identical - if (sizeof() == 8) { - // @ts-ignore: typecast - return reinterpret(value1) == reinterpret(value2); - } else { - // @ts-ignore: typecast - return reinterpret(value1) == reinterpret(value2); - } + // Float pointing is special we shoulr presere following identities: + // 0.0 !=-0.0 + // NaN == NaN + if (sizeof() == 8) { + return ( + bool(u32(x != x) & u32(y != y) | + u32(reinterpret(f64(x)) == reinterpret(f64(y)))) + ); + } else { + return ( + bool(u32(x != x) & u32(y != y) | + u32(reinterpret(f32(x)) == reinterpret(f32(y)))) + ); } - // NaN != NaN, but they are identical. - // @ts-ignore: typecast - return bool(i32(isNaN(value1)) & i32(isNaN(value2))); } // For references, strings, integers and booleans - return value1 == value2; + return x == y; } } diff --git a/tests/compiler/std/object.debug.wat b/tests/compiler/std/object.debug.wat index d0971879de..937c1b7b9e 100644 --- a/tests/compiler/std/object.debug.wat +++ b/tests/compiler/std/object.debug.wat @@ -24,74 +24,64 @@ (elem $0 (i32.const 1)) (export "memory" (memory $0)) (start $~start) - (func $~lib/object/Object.is (param $value1 f64) (param $value2 f64) (result i32) + (func $~lib/object/Object.is (param $x f64) (param $y f64) (result i32) i32.const 1 drop - local.get $value1 - local.get $value2 - f64.eq - if - i32.const 8 - i32.const 8 - i32.eq - drop - local.get $value1 - i64.reinterpret_f64 - local.get $value2 - i64.reinterpret_f64 - i64.eq - return - end - local.get $value1 - local.get $value1 + i32.const 8 + i32.const 8 + i32.eq + drop + local.get $x + local.get $x f64.ne - local.get $value2 - local.get $value2 + local.get $y + local.get $y f64.ne i32.and + local.get $x + i64.reinterpret_f64 + local.get $y + i64.reinterpret_f64 + i64.eq + i32.or return ) - (func $~lib/object/Object.is (param $value1 f32) (param $value2 f32) (result i32) + (func $~lib/object/Object.is (param $x f32) (param $y f32) (result i32) i32.const 1 drop - local.get $value1 - local.get $value2 - f32.eq - if - i32.const 4 - i32.const 8 - i32.eq - drop - local.get $value1 - i32.reinterpret_f32 - local.get $value2 - i32.reinterpret_f32 - i32.eq - return - end - local.get $value1 - local.get $value1 + i32.const 4 + i32.const 8 + i32.eq + drop + local.get $x + local.get $x f32.ne - local.get $value2 - local.get $value2 + local.get $y + local.get $y f32.ne i32.and + local.get $x + i32.reinterpret_f32 + local.get $y + i32.reinterpret_f32 + i32.eq + i32.or return ) - (func $~lib/object/Object.is (param $value1 i32) (param $value2 i32) (result i32) + (func $~lib/object/Object.is (param $x i32) (param $y i32) (result i32) i32.const 0 drop - local.get $value1 - local.get $value2 + local.get $x + local.get $y i32.eq ) - (func $~lib/object/Object.is (param $value1 i32) (param $value2 i32) (result i32) + (func $~lib/object/Object.is (param $x i32) (param $y i32) (result i32) i32.const 0 drop - local.get $value1 + local.get $x i32.const 0 i32.ne - local.get $value2 + local.get $y i32.const 0 i32.ne i32.eq @@ -251,18 +241,18 @@ call $~lib/util/string/compareImpl i32.eqz ) - (func $~lib/object/Object.is<~lib/string/String> (param $value1 i32) (param $value2 i32) (result i32) + (func $~lib/object/Object.is<~lib/string/String> (param $x i32) (param $y i32) (result i32) i32.const 0 drop - local.get $value1 - local.get $value2 + local.get $x + local.get $y call $~lib/string/String.__eq ) - (func $~lib/object/Object.is<~lib/string/String|null> (param $value1 i32) (param $value2 i32) (result i32) + (func $~lib/object/Object.is<~lib/string/String|null> (param $x i32) (param $y i32) (result i32) i32.const 0 drop - local.get $value1 - local.get $value2 + local.get $x + local.get $y call $~lib/string/String.__eq ) (func $~start @@ -294,6 +284,8 @@ f64.const 0 f64.const 0 call $~lib/object/Object.is + i32.const 0 + i32.ne i32.const 1 i32.eq i32.eqz @@ -309,6 +301,8 @@ f64.const -0 call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -323,6 +317,8 @@ f64.const 0 call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -337,6 +333,8 @@ f64.const 1 call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -351,6 +349,8 @@ f64.const -1 call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -364,6 +364,8 @@ f64.const 1 f64.const 1 call $~lib/object/Object.is + i32.const 0 + i32.ne i32.const 1 i32.eq i32.eqz @@ -378,6 +380,8 @@ f64.const inf f64.const inf call $~lib/object/Object.is + i32.const 0 + i32.ne i32.const 1 i32.eq i32.eqz @@ -394,6 +398,8 @@ f64.const inf f64.neg call $~lib/object/Object.is + i32.const 0 + i32.ne i32.const 1 i32.eq i32.eqz @@ -410,6 +416,8 @@ f64.neg call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -425,6 +433,8 @@ f64.const inf call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -439,6 +449,8 @@ f64.const nan:0x8000000000000 call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -453,6 +465,8 @@ f64.const inf call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -466,6 +480,8 @@ f64.const nan:0x8000000000000 f64.const nan:0x8000000000000 call $~lib/object/Object.is + i32.const 0 + i32.ne i32.const 1 i32.eq i32.eqz @@ -480,6 +496,8 @@ f32.const 0 f32.const 0 call $~lib/object/Object.is + i32.const 0 + i32.ne i32.const 1 i32.eq i32.eqz @@ -495,6 +513,8 @@ f32.const -0 call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -509,6 +529,8 @@ f32.const 0 call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -523,6 +545,8 @@ f32.const 1 call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -537,6 +561,8 @@ f32.const -1 call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -550,6 +576,8 @@ f32.const 1 f32.const 1 call $~lib/object/Object.is + i32.const 0 + i32.ne i32.const 1 i32.eq i32.eqz @@ -564,6 +592,8 @@ f32.const inf f32.const inf call $~lib/object/Object.is + i32.const 0 + i32.ne i32.const 1 i32.eq i32.eqz @@ -580,6 +610,8 @@ f32.const inf f32.neg call $~lib/object/Object.is + i32.const 0 + i32.ne i32.const 1 i32.eq i32.eqz @@ -596,6 +628,8 @@ f32.neg call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -611,6 +645,8 @@ f32.const inf call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -625,6 +661,8 @@ f32.const nan:0x400000 call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -639,6 +677,8 @@ f32.const inf call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -652,6 +692,8 @@ f32.const nan:0x400000 f32.const nan:0x400000 call $~lib/object/Object.is + i32.const 0 + i32.ne i32.const 1 i32.eq i32.eqz @@ -669,6 +711,8 @@ f64.mul call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -685,6 +729,8 @@ f64.mul call $~lib/object/Object.is i32.const 0 + i32.ne + i32.const 0 i32.eq i32.eqz if @@ -698,6 +744,8 @@ f64.const 0 f64.const 0 call $~lib/object/Object.is + i32.const 0 + i32.ne i32.const 1 i32.eq i32.eqz