tests for i64/i32 leb

This commit is contained in:
NikVolf
2017-04-20 19:17:20 +03:00
parent 30f8472a27
commit b13248470b
6 changed files with 90 additions and 9 deletions

Binary file not shown.

View File

@ -7,6 +7,12 @@
i32.const 8192 i32.const 8192
i32.const 16384 i32.const 16384
i32.const 32767 i32.const 32767
i32.const -1024
i32.const -2048
i32.const -4096
i32.const -8192
i32.const -16384
i32.const -32768
return return
) )
) )

View File

@ -23,7 +23,7 @@ pub use self::import_entry::{ImportEntry, MemoryType, TableType, GlobalType, Ext
pub use self::export_entry::{ExportEntry, Internal}; pub use self::export_entry::{ExportEntry, Internal};
pub use self::global_entry::GlobalEntry; pub use self::global_entry::GlobalEntry;
pub use self::primitives::{ pub use self::primitives::{
VarUint32, VarUint7, VarUint1, VarInt7, Uint32, VarUint32, VarUint7, VarUint1, VarInt7, Uint32, VarInt32, VarInt64,
Uint64, VarUint64, CountedList, CountedWriter, CountedListWriter, Uint64, VarUint64, CountedList, CountedWriter, CountedListWriter,
}; };
pub use self::types::{Type, ValueType, BlockType, FunctionType}; pub use self::types::{Type, ValueType, BlockType, FunctionType};

View File

@ -245,7 +245,7 @@ mod integration_tests {
let module = deserialize_file("./res/cases/v1/const.wasm").expect("Should be deserialized"); let module = deserialize_file("./res/cases/v1/const.wasm").expect("Should be deserialized");
let func = &module.code_section().expect("Code section to exist").bodies()[0]; let func = &module.code_section().expect("Code section to exist").bodies()[0];
assert_eq!(func.code().elements().len(), 8); assert_eq!(func.code().elements().len(), 14);
assert_eq!(I32Const(1024), func.code().elements()[0]); assert_eq!(I32Const(1024), func.code().elements()[0]);
assert_eq!(I32Const(2048), func.code().elements()[1]); assert_eq!(I32Const(2048), func.code().elements()[1]);
@ -253,5 +253,11 @@ mod integration_tests {
assert_eq!(I32Const(8192), func.code().elements()[3]); assert_eq!(I32Const(8192), func.code().elements()[3]);
assert_eq!(I32Const(16384), func.code().elements()[4]); assert_eq!(I32Const(16384), func.code().elements()[4]);
assert_eq!(I32Const(32767), func.code().elements()[5]); assert_eq!(I32Const(32767), func.code().elements()[5]);
assert_eq!(I32Const(-1024), func.code().elements()[6]);
assert_eq!(I32Const(-2048), func.code().elements()[7]);
assert_eq!(I32Const(-4096), func.code().elements()[8]);
assert_eq!(I32Const(-8192), func.code().elements()[9]);
assert_eq!(I32Const(-16384), func.code().elements()[10]);
assert_eq!(I32Const(-32768), func.code().elements()[11]);
} }
} }

View File

@ -2,7 +2,8 @@ use std::io;
use super::{ use super::{
Serialize, Deserialize, Error, VarUint7, Serialize, Deserialize, Error, VarUint7,
VarUint1, VarUint32, CountedList, BlockType, VarUint1, VarUint32, CountedList, BlockType,
Uint32, VarUint64, Uint64, CountedListWriter Uint32, VarUint64, Uint64, CountedListWriter,
VarInt32, VarInt64,
}; };
/// Collection of opcodes (usually inside a block section). /// Collection of opcodes (usually inside a block section).
@ -428,8 +429,8 @@ impl Deserialize for Opcode {
0x3f => CurrentMemory(VarUint1::deserialize(reader)?.into()), 0x3f => CurrentMemory(VarUint1::deserialize(reader)?.into()),
0x40 => GrowMemory(VarUint1::deserialize(reader)?.into()), 0x40 => GrowMemory(VarUint1::deserialize(reader)?.into()),
0x41 => I32Const(VarUint32::deserialize(reader)?.into()), 0x41 => I32Const(VarInt32::deserialize(reader)?.into()),
0x42 => I64Const(VarUint64::deserialize(reader)?.into()), 0x42 => I64Const(VarInt64::deserialize(reader)?.into()),
0x43 => F32Const(Uint32::deserialize(reader)?.into()), 0x43 => F32Const(Uint32::deserialize(reader)?.into()),
0x44 => F64Const(Uint64::deserialize(reader)?.into()), 0x44 => F64Const(Uint64::deserialize(reader)?.into()),
0x45 => I32Eqz, 0x45 => I32Eqz,
@ -741,10 +742,10 @@ impl Serialize for Opcode {
VarUint1::from(flag).serialize(writer)?; VarUint1::from(flag).serialize(writer)?;
}), }),
I32Const(def) => op!(writer, 0x41, { I32Const(def) => op!(writer, 0x41, {
VarUint32::from(def).serialize(writer)?; VarInt32::from(def).serialize(writer)?;
}), }),
I64Const(def) => op!(writer, 0x42, { I64Const(def) => op!(writer, 0x42, {
VarUint64::from(def).serialize(writer)?; VarInt64::from(def).serialize(writer)?;
}), }),
F32Const(def) => op!(writer, 0x43, { F32Const(def) => op!(writer, 0x43, {
Uint32::from(def).serialize(writer)?; Uint32::from(def).serialize(writer)?;

View File

@ -206,7 +206,7 @@ impl Serialize for VarInt7 {
} }
} }
/// 32-bit signed integer, encoded in LEB128 (always 1 byte length) /// 32-bit signed integer, encoded in LEB128 (can be 1-5 bytes length)
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct VarInt32(i32); pub struct VarInt32(i32);
@ -236,7 +236,7 @@ impl Deserialize for VarInt32 {
res |= ((b & 0x7f) as i32) << shift; res |= ((b & 0x7f) as i32) << shift;
shift += 7; shift += 7;
if (b >> 7) == 0 { if (b >> 7) == 0 {
if b & 0b0100_0000 == 0b0100_0000 { if shift < 32 && b & 0b0100_0000 == 0b0100_0000 {
res |= - (1 << shift); res |= - (1 << shift);
} }
break; break;
@ -269,6 +269,69 @@ impl Serialize for VarInt32 {
} }
} }
/// 64-bit signed integer, encoded in LEB128 (can be 1-9 bytes length)
#[derive(Copy, Clone)]
pub struct VarInt64(i64);
impl From<VarInt64> for i64 {
fn from(v: VarInt64) -> i64 {
v.0
}
}
impl From<i64> for VarInt64 {
fn from(v: i64) -> VarInt64 {
VarInt64(v)
}
}
impl Deserialize for VarInt64 {
type Error = Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
let mut res = 0i64;
let mut shift = 0;
let mut u8buf = [0u8; 1];
loop {
reader.read_exact(&mut u8buf)?;
let b = u8buf[0];
res |= ((b & 0x7f) as i64) << shift;
shift += 7;
if (b >> 7) == 0 {
if shift < 64 && b & 0b0100_0000 == 0b0100_0000 {
res |= - (1 << shift);
}
break;
}
}
Ok(VarInt64(res))
}
}
impl Serialize for VarInt64 {
type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let mut buf = [0u8; 1];
let mut v = self.0;
let mut more = true;
while more {
buf[0] = (v & 0b0111_1111) as u8;
v >>= 7;
if (v == 0 && buf[0] & 0b0100_0000 == 0) || (v == -1 && buf[0] & 0b0100_0000 == 0b0100_0000) {
more = false
} else {
buf[0] |= 0b1000_0000
}
writer.write_all(&buf[..])?;
}
Ok(())
}
}
/// 32-bit unsigned integer, encoded in little endian /// 32-bit unsigned integer, encoded in little endian
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct Uint32(u32); pub struct Uint32(u32);
@ -554,6 +617,11 @@ mod tests {
varint32_serde_test(vec![0x80, 0xc0, 0x00], 8192); varint32_serde_test(vec![0x80, 0xc0, 0x00], 8192);
} }
#[test]
fn varint32_neg_8192() {
varint32_serde_test(vec![0x80, 0x40], -8192);
}
#[test] #[test]
fn counted_list() { fn counted_list() {
let payload = vec![ let payload = vec![