-
-
Notifications
You must be signed in to change notification settings - Fork 669
wasm-validator error: i64 != i32: binary child types must be equal #1911
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
That's strange. Could you share |
It' really long. |
class TestData<T1, T2> {
constructor(
public readonly input: T1,
public readonly output: T2,
) { }
}
describe("Compact", () => {
it("serialize", () => {
let ser = new ScaleSerializer();
let tests: Array<TestData<u64, Array<u8>>> = [
new TestData(0, [0x00]),
// we can omit the following tests.
// new TestData(63, [0xfc]),
// new TestData(16383, [0xfd, 0xff]),
// new TestData(16384, [0x02, 0x00, 0x01, 0x00]),
// new TestData(1073741823, [0xfe, 0xff, 0xff, 0xff]),
// new TestData(1073741824, [0x03, 0x00, 0x00, 0x00, 0x40]),
// new TestData((1 << 32) - 1, [0x03, 0xff, 0xff, 0xff, 0xff]),
// new TestData((1 << 32), [0x07, 0x00, 0x00, 0x00, 0x00, 0x01]),
// new TestData((1 << 40), [0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]),
// new TestData((1 << 48), [0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]),
// new TestData((1 << 56) - 1, [0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]),
// new TestData((1 << 56), [0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]),
// new TestData(u64.MAX_VALUE, [0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), ];
for (let i = 0; i < tests.length; i++) {
let test = tests[i];
let num = new Compact<u64>(test.input);
ser.clear();
let res = num.serialize<BytesBuffer, ScaleSerializer>(ser).toArray();
expect(res).toStrictEqual(test.output);
// meet the wasm-validator error
// if (test.input <= (u8.MAX_VALUE as u64)) {
// let num = new Compact<u8>(test.input as u8);
// ser.clear();
// let res = num.serialize<BytesBuffer, ScaleSerializer>(ser).toArray();
// expect(res).toStrictEqual(test.output);
// }
// meet the wasm-validator error
// if (test.input <= (u16.MAX_VALUE as u64)) {
// let num = new Compact<u16>(test.input as u16);
// ser.clear();
// let res = num.serialize<BytesBuffer, ScaleSerializer>(ser).toArray();
// expect(res).toStrictEqual(test.output);
// }
// It's ok
if (test.input <= (u32.MAX_VALUE as u64)) {
let num = new Compact<u32>(test.input as u32);
ser.clear();
let res = num.serialize<BytesBuffer, ScaleSerializer>(ser).toArray();
expect(res).toStrictEqual(test.output);
}
}
});
}); export interface CompactLen {
compactLen(): i32;
}
export class Compact<T extends number> implements CompactLen {
// @ts-ignore
constructor(protected _value: T = 0) {
if (!isInteger<T>()) {
unreachable();
}
}
@inline
unwrap(): T {
return this._value;
}
@inline
compactLen(): i32 {
return Compact.computeCompactLen(this._value as u64);
}
@inline
static computeCompactLen(val: u64): i32 {
if (val <= 0b0011_1111) return 1;
else if (val <= 0b0011_1111_1111_1111) return 2;
else if (val <= 0b0011_1111_1111_1111_1111_1111_1111_1111) return 4;
else {
return (8 - clz(val) / 8) as i32 + 1;
}
}
@inline
serialize<R, S extends Serializer<R>>(serializer: S): R {
const len = this.compactLen();
switch (len) {
case 1: {
return serializer.serialize<u8>((this._value as u8) << 2);
}
case 2: {
return serializer.serialize<u16>(((this._value as u16) << 2) | 0b01);
}
case 4: {
return serializer.serialize<u32>(((this._value as u32) << 2) | 0b10);
}
default: {
let bytesNeeded = 8 - clz(this._value as u64) / 8;
assert(bytesNeeded >= 4, "Previous match arm matches anyting less than 2^30; qed");
let ret = serializer.serializeU8(0b11 + ((bytesNeeded - 4) << 2) as u8);
let v = this._value;
for (let i: u8 = 0; i < u8(bytesNeeded); i++) {
ret = serializer.serializeU8(v as u8);
// @ts-ignore
v >>= 8;
}
// @ts-ignore
assert(v == 0, "shifted sufficient bits right to lead only leading zeros; qed");
return ret;
}
}
}
} This is still incomplete. |
it will be great if you reduce this to minimal reproducible example |
I try my best. |
@MaxGraey The minimal example: class N<T> {
constructor(public n: T) {
}
}
describe("N", () => {
it("validate-error", () => {
{
let testData: u64 = 0;
if (testData <= (u16.MAX_VALUE as u64)) {
let num = new N<u16>(testData as u16);
let bytesNeeded = 8 - clz(num.n as u64) / 8;
expect(bytesNeeded).toBeGreaterThan(1);
}
}
{
let testData: u64 = 1;
if (testData <= (u8.MAX_VALUE as u64)) {
let num = new N<u8>(testData as u8);
let bytesNeeded = 8 - clz(num.n as u64) / 8;
expect(bytesNeeded).toBeGreaterThan(1);
}
}
});
}); |
Thanks! I reduced it more: export function test(x: u16): u64 {
return x as u64;
} @dcodeIO could you check this? |
Whenever aspect is involved, best to remove it altogether. Because sometimes it's an aspect bug :) |
The text was updated successfully, but these errors were encountered: