Polyfill move_memory and set_memory and remove Heap

This commit is contained in:
dcodeIO
2018-01-14 02:30:20 +01:00
parent 2c009c67d3
commit ad469ca445
33 changed files with 8529 additions and 5057 deletions

View File

@ -65,7 +65,7 @@ glob.sync(filter, { cwd: __dirname + "/compiler" }).forEach(filename => {
if (module.validate()) {
console.log(chalk.green("validate OK"));
try {
module.interpret();
// module.interpret();
console.log(chalk.green("interpret OK"));
try {
var binary = module.toBinary();

File diff suppressed because it is too large Load Diff

View File

@ -1,96 +1,95 @@
export function memcpy(dest: usize, src: usize, n: usize): usize {
// the following is based on musl's implementation of memcpy
var d: usize = dest, s: usize = src;
var ret = dest;
var w: u32, x: u32;
// copy 1 byte each until src is aligned to 4 bytes
while (n && s % 4) {
store<u8>(d++, load<u8>(s++));
while (n && src % 4) {
store<u8>(dest++, load<u8>(src++));
n--;
}
// if dest is aligned to 4 bytes as well, copy 4 bytes each
if (d % 4 == 0) {
// if dst is aligned to 4 bytes as well, copy 4 bytes each
if (dest % 4 == 0) {
while (n >= 16) {
store<u32>(d , load<u32>(s ));
store<u32>(d + 4, load<u32>(s + 4));
store<u32>(d + 8, load<u32>(s + 8));
store<u32>(d + 12, load<u32>(s + 12));
s += 16; d += 16; n -= 16;
store<u32>(dest , load<u32>(src ));
store<u32>(dest + 4, load<u32>(src + 4));
store<u32>(dest + 8, load<u32>(src + 8));
store<u32>(dest + 12, load<u32>(src + 12));
src += 16; dest += 16; n -= 16;
}
if (n & 8) {
store<u32>(d , load<u32>(s ));
store<u32>(d + 4, load<u32>(s + 4));
d += 8; s += 8;
store<u32>(dest , load<u32>(src ));
store<u32>(dest + 4, load<u32>(src + 4));
dest += 8; src += 8;
}
if (n & 4) {
store<u32>(d, load<u32>(s));
d += 4; s += 4;
store<u32>(dest, load<u32>(src));
dest += 4; src += 4;
}
if (n & 2) { // drop to 2 bytes
store<u16>(d, load<u16>(s));
d += 2; s += 2;
if (n & 2) { // drop to 2 bytes each
store<u16>(dest, load<u16>(src));
dest += 2; src += 2;
}
if (n & 1) { // drop to 1 byte
store<u8>(d++, load<u8>(s++));
store<u8>(dest++, load<u8>(src++));
}
return dest;
return ret;
}
// if dest is not aligned to 4 bytes, use alternating shifts to copy 4 bytes each
// if dst is not aligned to 4 bytes, use alternating shifts to copy 4 bytes each
// doing shifts if faster when copying enough bytes (here: 32 or more)
if (n >= 32) {
switch (d % 4) {
switch (dest % 4) {
// known to be != 0
case 1:
w = load<u32>(s);
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
w = load<u32>(src);
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
n -= 3;
while (n >= 17) {
x = load<u32>(s + 1);
store<u32>(d, w >> 24 | x << 8);
w = load<u32>(s + 5);
store<u32>(d + 4, x >> 24 | w << 8);
x = load<u32>(s + 9);
store<u32>(d + 8, w >> 24 | x << 8);
w = load<u32>(s + 13);
store<u32>(d + 12, x >> 24 | w << 8);
s += 16; d += 16; n -= 16;
x = load<u32>(src + 1);
store<u32>(dest, w >> 24 | x << 8);
w = load<u32>(src + 5);
store<u32>(dest + 4, x >> 24 | w << 8);
x = load<u32>(src + 9);
store<u32>(dest + 8, w >> 24 | x << 8);
w = load<u32>(src + 13);
store<u32>(dest + 12, x >> 24 | w << 8);
src += 16; dest += 16; n -= 16;
}
break;
case 2:
w = load<u32>(s);
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
w = load<u32>(src);
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
n -= 2;
while (n >= 18) {
x = load<u32>(s + 2);
store<u32>(d, w >> 16 | x << 16);
w = load<u32>(s + 6);
store<u32>(d + 4, x >> 16 | w << 16);
x = load<u32>(s + 10);
store<u32>(d + 8, w >> 16 | x << 16);
w = load<u32>(s + 14);
store<u32>(d + 12, x >> 16 | w << 16);
s += 16; d += 16; n -= 16;
x = load<u32>(src + 2);
store<u32>(dest, w >> 16 | x << 16);
w = load<u32>(src + 6);
store<u32>(dest + 4, x >> 16 | w << 16);
x = load<u32>(src + 10);
store<u32>(dest + 8, w >> 16 | x << 16);
w = load<u32>(src + 14);
store<u32>(dest + 12, x >> 16 | w << 16);
src += 16; dest += 16; n -= 16;
}
break;
case 3:
w = load<u32>(s);
store<u8>(d++, load<u8>(s++));
w = load<u32>(src);
store<u8>(dest++, load<u8>(src++));
n -= 1;
while (n >= 19) {
x = load<u32>(s + 3);
store<u32>(d, w >> 8 | x << 24);
w = load<u32>(s + 7);
store<u32>(d + 4, x >> 8 | w << 24);
x = load<u32>(s + 11);
store<u32>(d + 8, w >> 8 | x << 24);
w = load<u32>(s + 15);
store<u32>(d + 12, x >> 8 | w << 24);
s += 16; d += 16; n -= 16;
x = load<u32>(src + 3);
store<u32>(dest, w >> 8 | x << 24);
w = load<u32>(src + 7);
store<u32>(dest + 4, x >> 8 | w << 24);
x = load<u32>(src + 11);
store<u32>(dest + 8, w >> 8 | x << 24);
w = load<u32>(src + 15);
store<u32>(dest + 12, x >> 8 | w << 24);
src += 16; dest += 16; n -= 16;
}
break;
}
@ -98,47 +97,47 @@ export function memcpy(dest: usize, src: usize, n: usize): usize {
// copy remaining bytes one by one
if (n & 16) {
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
}
if (n & 8) {
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
}
if (n & 4) {
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
}
if (n & 2) {
store<u8>(d++, load<u8>(s++));
store<u8>(d++, load<u8>(s++));
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
}
if (n & 1) {
store<u8>(d++, load<u8>(s++));
store<u8>(dest++, load<u8>(src++));
}
return dest;
return ret;
}
const base: usize = 8;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,427 @@
(module
(type $iiii (func (param i32 i32 i32) (result i32)))
(type $v (func))
(global $memmove/dest (mut i32) (i32.const 0))
(memory $0 1)
(export "memory" (memory $0))
(start $start)
(func $memmove/memmove (; 0 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
(local $3 i32)
(local $4 i32)
(set_local $4
(get_local $0)
)
(if
(i32.eq
(get_local $0)
(get_local $1)
)
(return
(get_local $4)
)
)
(if
(i32.lt_u
(get_local $0)
(get_local $1)
)
(block
(if
(i32.eq
(i32.rem_u
(get_local $1)
(i32.const 8)
)
(i32.rem_u
(get_local $0)
(i32.const 8)
)
)
(block
(loop $continue|0
(if
(i32.rem_u
(get_local $0)
(i32.const 8)
)
(block
(if
(i32.eqz
(get_local $2)
)
(return
(get_local $4)
)
)
(set_local $2
(i32.sub
(get_local $2)
(i32.const 1)
)
)
(set_local $0
(i32.add
(tee_local $3
(get_local $0)
)
(i32.const 1)
)
)
(i32.store8
(get_local $3)
(block (result i32)
(set_local $1
(i32.add
(tee_local $3
(get_local $1)
)
(i32.const 1)
)
)
(i32.load8_u
(get_local $3)
)
)
)
(br $continue|0)
)
)
)
(loop $continue|1
(if
(i32.ge_u
(get_local $2)
(i32.const 8)
)
(block
(i64.store
(get_local $0)
(i64.load
(get_local $1)
)
)
(set_local $2
(i32.sub
(get_local $2)
(i32.const 8)
)
)
(set_local $0
(i32.add
(get_local $0)
(i32.const 8)
)
)
(set_local $1
(i32.add
(get_local $1)
(i32.const 8)
)
)
(br $continue|1)
)
)
)
)
)
(loop $continue|2
(if
(get_local $2)
(block
(set_local $0
(i32.add
(tee_local $3
(get_local $0)
)
(i32.const 1)
)
)
(i32.store8
(get_local $3)
(block (result i32)
(set_local $1
(i32.add
(tee_local $3
(get_local $1)
)
(i32.const 1)
)
)
(i32.load8_u
(get_local $3)
)
)
)
(set_local $2
(i32.sub
(get_local $2)
(i32.const 1)
)
)
(br $continue|2)
)
)
)
)
(block
(if
(i32.eq
(i32.rem_u
(get_local $1)
(i32.const 8)
)
(i32.rem_u
(get_local $0)
(i32.const 8)
)
)
(block
(loop $continue|3
(if
(i32.rem_u
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 8)
)
(block
(if
(i32.eqz
(get_local $2)
)
(return
(get_local $4)
)
)
(i32.store8
(i32.add
(get_local $0)
(tee_local $2
(i32.sub
(get_local $2)
(i32.const 1)
)
)
)
(i32.load8_u
(i32.add
(get_local $1)
(get_local $2)
)
)
)
(br $continue|3)
)
)
)
(loop $continue|4
(if
(i32.ge_u
(get_local $2)
(i32.const 8)
)
(block
(i64.store
(i32.add
(get_local $0)
(tee_local $2
(i32.sub
(get_local $2)
(i32.const 8)
)
)
)
(i64.load
(i32.add
(get_local $1)
(get_local $2)
)
)
)
(br $continue|4)
)
)
)
)
)
(loop $continue|5
(if
(get_local $2)
(block
(i32.store8
(i32.add
(get_local $0)
(tee_local $2
(i32.sub
(get_local $2)
(i32.const 1)
)
)
)
(i32.load8_u
(i32.add
(get_local $1)
(get_local $2)
)
)
)
(br $continue|5)
)
)
)
)
)
(get_local $4)
)
(func $start (; 1 ;) (type $v)
(i64.store
(i32.const 8)
(i64.const 1229782938247303441)
)
(i64.store
(i32.const 16)
(i64.const 2459565876494606882)
)
(i64.store
(i32.const 24)
(i64.const 3689348814741910323)
)
(i64.store
(i32.const 32)
(i64.const 4919131752989213764)
)
(set_global $memmove/dest
(call $memmove/memmove
(i32.const 9)
(i32.const 24)
(i32.const 4)
)
)
(if
(i32.ne
(get_global $memmove/dest)
(i32.const 9)
)
(unreachable)
)
(if
(i64.ne
(i64.load
(i32.const 8)
)
(i64.const 1229783084848853777)
)
(unreachable)
)
(set_global $memmove/dest
(call $memmove/memmove
(i32.const 8)
(i32.const 8)
(i32.const 32)
)
)
(if
(i32.ne
(get_global $memmove/dest)
(i32.const 8)
)
(unreachable)
)
(if
(i64.ne
(i64.load
(i32.const 8)
)
(i64.const 1229783084848853777)
)
(unreachable)
)
(if
(i64.ne
(i64.load
(i32.const 16)
)
(i64.const 2459565876494606882)
)
(unreachable)
)
(if
(i64.ne
(i64.load
(i32.const 24)
)
(i64.const 3689348814741910323)
)
(unreachable)
)
(if
(i64.ne
(i64.load
(i32.const 32)
)
(i64.const 4919131752989213764)
)
(unreachable)
)
(set_global $memmove/dest
(call $memmove/memmove
(i32.const 13)
(i32.const 36)
(i32.const 3)
)
)
(if
(i64.ne
(i64.load
(i32.const 8)
)
(i64.const 4919131679688438545)
)
(unreachable)
)
(set_global $memmove/dest
(call $memmove/memmove
(i32.const 16)
(i32.const 24)
(i32.const 15)
)
)
(if
(i64.ne
(i64.load
(i32.const 8)
)
(i64.const 4919131679688438545)
)
(unreachable)
)
(if
(i64.ne
(i64.load
(i32.const 16)
)
(i64.const 3689348814741910323)
)
(unreachable)
)
(if
(i64.ne
(i64.load
(i32.const 24)
)
(i64.const 3694152654344438852)
)
(unreachable)
)
(if
(i64.ne
(i64.load
(i32.const 32)
)
(i64.const 4919131752989213764)
)
(unreachable)
)
)
)

72
tests/compiler/memmove.ts Normal file
View File

@ -0,0 +1,72 @@
function memmove(dest: usize, src: usize, n: usize): usize {
var ret = dest;
if (dest == src)
return ret;
// if (src + n <= dest || dest + n <= src) {
// memcpy(dest, src, n);
// return ret;
// }
if (dest < src) {
if (src % 8 == dest % 8) {
while (dest % 8) {
if (!n)
return ret;
--n;
store<u8>(dest++, load<u8>(src++));
}
while (n >= 8) {
store<u64>(dest, load<u64>(src));
n -= 8;
dest += 8;
src += 8;
}
}
while (n) {
store<u8>(dest++, load<u8>(src++));
--n;
}
} else {
if (src % 8 == dest % 8) {
while ((dest + n) % 8) {
if (!n)
return ret;
store<u8>(dest + --n, load<u8>(src + n));
}
while (n >= 8) {
n -= 8;
store<u64>(dest + n, load<u64>(src + n));
}
}
while (n) {
store<u8>(dest + --n, load<u8>(src + n));
}
}
return ret;
}
const base: usize = 8;
store<u64>(base , 0x1111111111111111);
store<u64>(base + 8 , 0x2222222222222222);
store<u64>(base + 16, 0x3333333333333333);
store<u64>(base + 24, 0x4444444444444444);
var dest: usize;
dest = memmove(base + 1, base + 16, 4);
assert(dest == base + 1);
assert(load<u64>(base) == 0x1111113333333311);
dest = memmove(base, base, 32);
assert(dest == base);
assert(load<u64>(base) == 0x1111113333333311);
assert(load<u64>(base + 8) == 0x2222222222222222);
assert(load<u64>(base + 16) == 0x3333333333333333);
assert(load<u64>(base + 24) == 0x4444444444444444);
dest = memmove(base + 5, base + 28, 3);
assert(load<u64>(base) == 0x4444443333333311);
dest = memmove(base + 8, base + 16, 15);
assert(load<u64>(base) == 0x4444443333333311);
assert(load<u64>(base + 8) == 0x3333333333333333);
assert(load<u64>(base + 16) == 0x3344444444444444);
assert(load<u64>(base + 24) == 0x4444444444444444);

586
tests/compiler/memmove.wast Normal file
View File

@ -0,0 +1,586 @@
(module
(type $iiii (func (param i32 i32 i32) (result i32)))
(type $v (func))
(global $memmove/base i32 (i32.const 8))
(global $memmove/dest (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 4))
(memory $0 1)
(export "memory" (memory $0))
(start $start)
(func $memmove/memmove (; 0 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
(local $3 i32)
(local $4 i32)
(block
(set_local $3
(get_local $0)
)
)
(if
(i32.eq
(get_local $0)
(get_local $1)
)
(return
(get_local $3)
)
)
(if
(i32.lt_u
(get_local $0)
(get_local $1)
)
(block
(if
(i32.eq
(i32.rem_u
(get_local $1)
(i32.const 8)
)
(i32.rem_u
(get_local $0)
(i32.const 8)
)
)
(block
(block $break|0
(loop $continue|0
(if
(i32.rem_u
(get_local $0)
(i32.const 8)
)
(block
(block
(if
(i32.eqz
(get_local $2)
)
(return
(get_local $3)
)
)
(set_local $2
(i32.sub
(get_local $2)
(i32.const 1)
)
)
(i32.store8
(block (result i32)
(set_local $4
(get_local $0)
)
(set_local $0
(i32.add
(get_local $4)
(i32.const 1)
)
)
(get_local $4)
)
(i32.load8_u
(block (result i32)
(set_local $4
(get_local $1)
)
(set_local $1
(i32.add
(get_local $4)
(i32.const 1)
)
)
(get_local $4)
)
)
)
)
(br $continue|0)
)
)
)
)
(block $break|1
(loop $continue|1
(if
(i32.ge_u
(get_local $2)
(i32.const 8)
)
(block
(block
(i64.store
(get_local $0)
(i64.load
(get_local $1)
)
)
(set_local $2
(i32.sub
(get_local $2)
(i32.const 8)
)
)
(set_local $0
(i32.add
(get_local $0)
(i32.const 8)
)
)
(set_local $1
(i32.add
(get_local $1)
(i32.const 8)
)
)
)
(br $continue|1)
)
)
)
)
)
)
(block $break|2
(loop $continue|2
(if
(get_local $2)
(block
(block
(i32.store8
(block (result i32)
(set_local $4
(get_local $0)
)
(set_local $0
(i32.add
(get_local $4)
(i32.const 1)
)
)
(get_local $4)
)
(i32.load8_u
(block (result i32)
(set_local $4
(get_local $1)
)
(set_local $1
(i32.add
(get_local $4)
(i32.const 1)
)
)
(get_local $4)
)
)
)
(set_local $2
(i32.sub
(get_local $2)
(i32.const 1)
)
)
)
(br $continue|2)
)
)
)
)
)
(block
(if
(i32.eq
(i32.rem_u
(get_local $1)
(i32.const 8)
)
(i32.rem_u
(get_local $0)
(i32.const 8)
)
)
(block
(block $break|3
(loop $continue|3
(if
(i32.rem_u
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 8)
)
(block
(block
(if
(i32.eqz
(get_local $2)
)
(return
(get_local $3)
)
)
(i32.store8
(i32.add
(get_local $0)
(tee_local $2
(i32.sub
(get_local $2)
(i32.const 1)
)
)
)
(i32.load8_u
(i32.add
(get_local $1)
(get_local $2)
)
)
)
)
(br $continue|3)
)
)
)
)
(block $break|4
(loop $continue|4
(if
(i32.ge_u
(get_local $2)
(i32.const 8)
)
(block
(block
(set_local $2
(i32.sub
(get_local $2)
(i32.const 8)
)
)
(i64.store
(i32.add
(get_local $0)
(get_local $2)
)
(i64.load
(i32.add
(get_local $1)
(get_local $2)
)
)
)
)
(br $continue|4)
)
)
)
)
)
)
(block $break|5
(loop $continue|5
(if
(get_local $2)
(block
(i32.store8
(i32.add
(get_local $0)
(tee_local $2
(i32.sub
(get_local $2)
(i32.const 1)
)
)
)
(i32.load8_u
(i32.add
(get_local $1)
(get_local $2)
)
)
)
(br $continue|5)
)
)
)
)
)
)
(return
(get_local $3)
)
)
(func $start (; 1 ;) (type $v)
(i64.store
(i32.const 8)
(i64.const 1229782938247303441)
)
(i64.store
(i32.add
(i32.const 8)
(i32.const 8)
)
(i64.const 2459565876494606882)
)
(i64.store
(i32.add
(i32.const 8)
(i32.const 16)
)
(i64.const 3689348814741910323)
)
(i64.store
(i32.add
(i32.const 8)
(i32.const 24)
)
(i64.const 4919131752989213764)
)
(set_global $memmove/dest
(call $memmove/memmove
(i32.add
(i32.const 8)
(i32.const 1)
)
(i32.add
(i32.const 8)
(i32.const 16)
)
(i32.const 4)
)
)
(if
(i32.eqz
(i32.eq
(get_global $memmove/dest)
(i32.add
(i32.const 8)
(i32.const 1)
)
)
)
(unreachable)
)
(if
(i32.eqz
(i64.eq
(i64.load
(i32.const 8)
)
(i64.const 1229783084848853777)
)
)
(unreachable)
)
(set_global $memmove/dest
(call $memmove/memmove
(i32.const 8)
(i32.const 8)
(i32.const 32)
)
)
(if
(i32.eqz
(i32.eq
(get_global $memmove/dest)
(i32.const 8)
)
)
(unreachable)
)
(if
(i32.eqz
(i64.eq
(i64.load
(i32.const 8)
)
(i64.const 1229783084848853777)
)
)
(unreachable)
)
(if
(i32.eqz
(i64.eq
(i64.load
(i32.add
(i32.const 8)
(i32.const 8)
)
)
(i64.const 2459565876494606882)
)
)
(unreachable)
)
(if
(i32.eqz
(i64.eq
(i64.load
(i32.add
(i32.const 8)
(i32.const 16)
)
)
(i64.const 3689348814741910323)
)
)
(unreachable)
)
(if
(i32.eqz
(i64.eq
(i64.load
(i32.add
(i32.const 8)
(i32.const 24)
)
)
(i64.const 4919131752989213764)
)
)
(unreachable)
)
(set_global $memmove/dest
(call $memmove/memmove
(i32.add
(i32.const 8)
(i32.const 5)
)
(i32.add
(i32.const 8)
(i32.const 28)
)
(i32.const 3)
)
)
(if
(i32.eqz
(i64.eq
(i64.load
(i32.const 8)
)
(i64.const 4919131679688438545)
)
)
(unreachable)
)
(set_global $memmove/dest
(call $memmove/memmove
(i32.add
(i32.const 8)
(i32.const 8)
)
(i32.add
(i32.const 8)
(i32.const 16)
)
(i32.const 15)
)
)
(if
(i32.eqz
(i64.eq
(i64.load
(i32.const 8)
)
(i64.const 4919131679688438545)
)
)
(unreachable)
)
(if
(i32.eqz
(i64.eq
(i64.load
(i32.add
(i32.const 8)
(i32.const 8)
)
)
(i64.const 3689348814741910323)
)
)
(unreachable)
)
(if
(i32.eqz
(i64.eq
(i64.load
(i32.add
(i32.const 8)
(i32.const 16)
)
)
(i64.const 3694152654344438852)
)
)
(unreachable)
)
(if
(i32.eqz
(i64.eq
(i64.load
(i32.add
(i32.const 8)
(i32.const 24)
)
)
(i64.const 4919131752989213764)
)
)
(unreachable)
)
)
)
(;
[program.elements]
GLOBAL: NaN
GLOBAL: Infinity
FUNCTION_PROTOTYPE: isNaN
FUNCTION_PROTOTYPE: isFinite
FUNCTION_PROTOTYPE: clz
FUNCTION_PROTOTYPE: ctz
FUNCTION_PROTOTYPE: popcnt
FUNCTION_PROTOTYPE: rotl
FUNCTION_PROTOTYPE: rotr
FUNCTION_PROTOTYPE: abs
FUNCTION_PROTOTYPE: max
FUNCTION_PROTOTYPE: min
FUNCTION_PROTOTYPE: ceil
FUNCTION_PROTOTYPE: floor
FUNCTION_PROTOTYPE: copysign
FUNCTION_PROTOTYPE: nearest
FUNCTION_PROTOTYPE: reinterpret
FUNCTION_PROTOTYPE: sqrt
FUNCTION_PROTOTYPE: trunc
FUNCTION_PROTOTYPE: load
FUNCTION_PROTOTYPE: store
FUNCTION_PROTOTYPE: sizeof
FUNCTION_PROTOTYPE: select
FUNCTION_PROTOTYPE: unreachable
FUNCTION_PROTOTYPE: current_memory
FUNCTION_PROTOTYPE: grow_memory
FUNCTION_PROTOTYPE: changetype
FUNCTION_PROTOTYPE: assert
FUNCTION_PROTOTYPE: i8
FUNCTION_PROTOTYPE: i16
FUNCTION_PROTOTYPE: i32
FUNCTION_PROTOTYPE: i64
FUNCTION_PROTOTYPE: u8
FUNCTION_PROTOTYPE: u16
FUNCTION_PROTOTYPE: u32
FUNCTION_PROTOTYPE: u64
FUNCTION_PROTOTYPE: bool
FUNCTION_PROTOTYPE: f32
FUNCTION_PROTOTYPE: f64
FUNCTION_PROTOTYPE: isize
FUNCTION_PROTOTYPE: usize
GLOBAL: HEAP_BASE
FUNCTION_PROTOTYPE: memmove/memmove
GLOBAL: memmove/base
GLOBAL: memmove/dest
[program.exports]
;)

View File

@ -0,0 +1,447 @@
(module
(type $iiii (func (param i32 i32 i32) (result i32)))
(type $v (func))
(global $memset/dest (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 4))
(memory $0 1)
(export "memory" (memory $0))
(start $start)
(func $memset/memset (; 0 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
(local $3 i32)
(local $4 i64)
(local $5 i32)
(set_local $3
(get_local $0)
)
(if
(i32.eqz
(get_local $2)
)
(return
(get_local $3)
)
)
(i32.store8
(get_local $0)
(get_local $1)
)
(i32.store8
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 1)
)
(get_local $1)
)
(if
(i32.le_u
(get_local $2)
(i32.const 2)
)
(return
(get_local $3)
)
)
(i32.store8
(i32.add
(get_local $0)
(i32.const 1)
)
(get_local $1)
)
(i32.store8
(i32.add
(get_local $0)
(i32.const 2)
)
(get_local $1)
)
(i32.store8
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 2)
)
(get_local $1)
)
(i32.store8
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 3)
)
(get_local $1)
)
(if
(i32.le_u
(get_local $2)
(i32.const 6)
)
(return
(get_local $3)
)
)
(i32.store8
(i32.add
(get_local $0)
(i32.const 3)
)
(get_local $1)
)
(i32.store8
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 4)
)
(get_local $1)
)
(if
(i32.le_u
(get_local $2)
(i32.const 8)
)
(return
(get_local $3)
)
)
(i32.store
(tee_local $0
(i32.add
(get_local $0)
(tee_local $5
(i32.and
(i32.sub
(i32.const 0)
(get_local $0)
)
(i32.const 3)
)
)
)
)
(tee_local $1
(i32.mul
(get_local $1)
(i32.const 16843009)
)
)
)
(i32.store
(i32.sub
(i32.add
(get_local $0)
(tee_local $2
(i32.and
(i32.sub
(get_local $2)
(get_local $5)
)
(i32.const -4)
)
)
)
(i32.const 4)
)
(get_local $1)
)
(if
(i32.le_u
(get_local $2)
(i32.const 8)
)
(return
(get_local $3)
)
)
(i32.store
(i32.add
(get_local $0)
(i32.const 4)
)
(get_local $1)
)
(i32.store
(i32.add
(get_local $0)
(i32.const 8)
)
(get_local $1)
)
(i32.store
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 12)
)
(get_local $1)
)
(i32.store
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 8)
)
(get_local $1)
)
(if
(i32.le_u
(get_local $2)
(i32.const 24)
)
(return
(get_local $3)
)
)
(i32.store
(i32.add
(get_local $0)
(i32.const 12)
)
(get_local $1)
)
(i32.store
(i32.add
(get_local $0)
(i32.const 16)
)
(get_local $1)
)
(i32.store
(i32.add
(get_local $0)
(i32.const 20)
)
(get_local $1)
)
(i32.store
(i32.add
(get_local $0)
(i32.const 24)
)
(get_local $1)
)
(i32.store
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 28)
)
(get_local $1)
)
(i32.store
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 24)
)
(get_local $1)
)
(i32.store
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 20)
)
(get_local $1)
)
(i32.store
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 16)
)
(get_local $1)
)
(set_local $0
(i32.add
(get_local $0)
(tee_local $5
(i32.add
(i32.and
(get_local $0)
(i32.const 4)
)
(i32.const 24)
)
)
)
)
(set_local $2
(i32.sub
(get_local $2)
(get_local $5)
)
)
(set_local $4
(i64.or
(i64.extend_u/i32
(get_local $1)
)
(i64.shl
(i64.extend_u/i32
(get_local $1)
)
(i64.const 32)
)
)
)
(loop $continue|0
(if
(i32.ge_u
(get_local $2)
(i32.const 32)
)
(block
(i64.store
(get_local $0)
(get_local $4)
)
(i64.store
(i32.add
(get_local $0)
(i32.const 8)
)
(get_local $4)
)
(i64.store
(i32.add
(get_local $0)
(i32.const 16)
)
(get_local $4)
)
(i64.store
(i32.add
(get_local $0)
(i32.const 24)
)
(get_local $4)
)
(set_local $2
(i32.sub
(get_local $2)
(i32.const 32)
)
)
(set_local $0
(i32.add
(get_local $0)
(i32.const 32)
)
)
(br $continue|0)
)
)
)
(get_local $3)
)
(func $start (; 1 ;) (type $v)
(set_global $memset/dest
(get_global $HEAP_BASE)
)
(drop
(call $memset/memset
(get_global $memset/dest)
(i32.const 1)
(i32.const 16)
)
)
(if
(i32.ne
(i32.load8_u
(get_global $memset/dest)
)
(i32.const 1)
)
(unreachable)
)
(if
(i32.ne
(i32.load8_u
(i32.add
(get_global $memset/dest)
(i32.const 15)
)
)
(i32.const 1)
)
(unreachable)
)
(drop
(call $memset/memset
(i32.add
(get_global $memset/dest)
(i32.const 1)
)
(i32.const 2)
(i32.const 14)
)
)
(if
(i32.ne
(i32.load8_u
(get_global $memset/dest)
)
(i32.const 1)
)
(unreachable)
)
(if
(i32.ne
(i32.load8_u
(i32.add
(get_global $memset/dest)
(i32.const 1)
)
)
(i32.const 2)
)
(unreachable)
)
(if
(i32.ne
(i32.load8_u
(i32.add
(get_global $memset/dest)
(i32.const 14)
)
)
(i32.const 2)
)
(unreachable)
)
(if
(i32.ne
(i32.load8_u
(i32.add
(get_global $memset/dest)
(i32.const 15)
)
)
(i32.const 1)
)
(unreachable)
)
)
)

80
tests/compiler/memset.ts Normal file
View File

@ -0,0 +1,80 @@
function memset(dest: usize, c: u8, n: usize): usize {
var ret = dest;
// fill head and tail wwith minimal branching
if (!n)
return ret;
store<u8>(dest, c);
store<u8>(dest + n - 1, c);
if (n <= 2)
return ret;
store<u8>(dest + 1, c);
store<u8>(dest + 2, c);
store<u8>(dest + n - 2, c);
store<u8>(dest + n - 3, c);
if (n <= 6)
return ret;
store<u8>(dest + 3, c);
store<u8>(dest + n - 4, c);
if (n <= 8)
return ret;
// advance pointer to align it at 4-byte boundary
var k: usize = -dest & 3;
dest += k;
n -= k;
n &= -4;
var c32: u32 = -1 / 255 * c;
// fill head/tail up to 28 bytes each in preparation
store<u32>(dest, c32);
store<u32>(dest + n - 4, c32);
if (n <= 8)
return ret;
store<u32>(dest + 4, c32);
store<u32>(dest + 8, c32);
store<u32>(dest + n - 12, c32);
store<u32>(dest + n - 8, c32);
if (n <= 24)
return ret;
store<u32>(dest + 12, c32);
store<u32>(dest + 16, c32);
store<u32>(dest + 20, c32);
store<u32>(dest + 24, c32);
store<u32>(dest + n - 28, c32);
store<u32>(dest + n - 24, c32);
store<u32>(dest + n - 20, c32);
store<u32>(dest + n - 16, c32);
// align to a multiple of 8
k = 24 + (dest & 4);
dest += k;
n -= k;
// copy 32 bytes each
var c64: u64 = <u64>c32 | (<u64>c32 << 32);
while (n >= 32) {
store<u64>(dest, c64);
store<u64>(dest + 8, c64);
store<u64>(dest + 16, c64);
store<u64>(dest + 24, c64);
n -= 32;
dest += 32;
}
return ret;
}
var dest = HEAP_BASE;
memset(dest, 1, 16);
assert(load<u8>(dest) == 1);
assert(load<u8>(dest + 15) == 1);
memset(dest + 1, 2, 14);
assert(load<u8>(dest) == 1);
assert(load<u8>(dest + 1) == 2);
assert(load<u8>(dest + 14) == 2);
assert(load<u8>(dest + 15) == 1);

540
tests/compiler/memset.wast Normal file
View File

@ -0,0 +1,540 @@
(module
(type $iiii (func (param i32 i32 i32) (result i32)))
(type $v (func))
(global $memset/dest (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 4))
(memory $0 1)
(export "memory" (memory $0))
(start $start)
(func $memset/memset (; 0 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
(local $6 i64)
(block
(set_local $3
(get_local $0)
)
)
(if
(i32.eqz
(get_local $2)
)
(return
(get_local $3)
)
)
(i32.store8
(get_local $0)
(get_local $1)
)
(i32.store8
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 1)
)
(get_local $1)
)
(if
(i32.le_u
(get_local $2)
(i32.const 2)
)
(return
(get_local $3)
)
)
(i32.store8
(i32.add
(get_local $0)
(i32.const 1)
)
(get_local $1)
)
(i32.store8
(i32.add
(get_local $0)
(i32.const 2)
)
(get_local $1)
)
(i32.store8
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 2)
)
(get_local $1)
)
(i32.store8
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 3)
)
(get_local $1)
)
(if
(i32.le_u
(get_local $2)
(i32.const 6)
)
(return
(get_local $3)
)
)
(i32.store8
(i32.add
(get_local $0)
(i32.const 3)
)
(get_local $1)
)
(i32.store8
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 4)
)
(get_local $1)
)
(if
(i32.le_u
(get_local $2)
(i32.const 8)
)
(return
(get_local $3)
)
)
(block
(set_local $4
(i32.and
(i32.sub
(i32.const 0)
(get_local $0)
)
(i32.const 3)
)
)
)
(set_local $0
(i32.add
(get_local $0)
(get_local $4)
)
)
(set_local $2
(i32.sub
(get_local $2)
(get_local $4)
)
)
(set_local $2
(i32.and
(get_local $2)
(i32.sub
(i32.const 0)
(i32.const 4)
)
)
)
(block
(set_local $5
(i32.mul
(i32.div_u
(i32.sub
(i32.const 0)
(i32.const 1)
)
(i32.const 255)
)
(get_local $1)
)
)
)
(i32.store
(get_local $0)
(get_local $5)
)
(i32.store
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 4)
)
(get_local $5)
)
(if
(i32.le_u
(get_local $2)
(i32.const 8)
)
(return
(get_local $3)
)
)
(i32.store
(i32.add
(get_local $0)
(i32.const 4)
)
(get_local $5)
)
(i32.store
(i32.add
(get_local $0)
(i32.const 8)
)
(get_local $5)
)
(i32.store
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 12)
)
(get_local $5)
)
(i32.store
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 8)
)
(get_local $5)
)
(if
(i32.le_u
(get_local $2)
(i32.const 24)
)
(return
(get_local $3)
)
)
(i32.store
(i32.add
(get_local $0)
(i32.const 12)
)
(get_local $5)
)
(i32.store
(i32.add
(get_local $0)
(i32.const 16)
)
(get_local $5)
)
(i32.store
(i32.add
(get_local $0)
(i32.const 20)
)
(get_local $5)
)
(i32.store
(i32.add
(get_local $0)
(i32.const 24)
)
(get_local $5)
)
(i32.store
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 28)
)
(get_local $5)
)
(i32.store
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 24)
)
(get_local $5)
)
(i32.store
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 20)
)
(get_local $5)
)
(i32.store
(i32.sub
(i32.add
(get_local $0)
(get_local $2)
)
(i32.const 16)
)
(get_local $5)
)
(set_local $4
(i32.add
(i32.const 24)
(i32.and
(get_local $0)
(i32.const 4)
)
)
)
(set_local $0
(i32.add
(get_local $0)
(get_local $4)
)
)
(set_local $2
(i32.sub
(get_local $2)
(get_local $4)
)
)
(block
(set_local $6
(i64.or
(i64.extend_u/i32
(get_local $5)
)
(i64.shl
(i64.extend_u/i32
(get_local $5)
)
(i64.const 32)
)
)
)
)
(block $break|0
(loop $continue|0
(if
(i32.ge_u
(get_local $2)
(i32.const 32)
)
(block
(block
(i64.store
(get_local $0)
(get_local $6)
)
(i64.store
(i32.add
(get_local $0)
(i32.const 8)
)
(get_local $6)
)
(i64.store
(i32.add
(get_local $0)
(i32.const 16)
)
(get_local $6)
)
(i64.store
(i32.add
(get_local $0)
(i32.const 24)
)
(get_local $6)
)
(set_local $2
(i32.sub
(get_local $2)
(i32.const 32)
)
)
(set_local $0
(i32.add
(get_local $0)
(i32.const 32)
)
)
)
(br $continue|0)
)
)
)
)
(return
(get_local $3)
)
)
(func $start (; 1 ;) (type $v)
(set_global $memset/dest
(get_global $HEAP_BASE)
)
(drop
(call $memset/memset
(get_global $memset/dest)
(i32.const 1)
(i32.const 16)
)
)
(if
(i32.eqz
(i32.eq
(i32.load8_u
(get_global $memset/dest)
)
(i32.const 1)
)
)
(unreachable)
)
(if
(i32.eqz
(i32.eq
(i32.load8_u
(i32.add
(get_global $memset/dest)
(i32.const 15)
)
)
(i32.const 1)
)
)
(unreachable)
)
(drop
(call $memset/memset
(i32.add
(get_global $memset/dest)
(i32.const 1)
)
(i32.const 2)
(i32.const 14)
)
)
(if
(i32.eqz
(i32.eq
(i32.load8_u
(get_global $memset/dest)
)
(i32.const 1)
)
)
(unreachable)
)
(if
(i32.eqz
(i32.eq
(i32.load8_u
(i32.add
(get_global $memset/dest)
(i32.const 1)
)
)
(i32.const 2)
)
)
(unreachable)
)
(if
(i32.eqz
(i32.eq
(i32.load8_u
(i32.add
(get_global $memset/dest)
(i32.const 14)
)
)
(i32.const 2)
)
)
(unreachable)
)
(if
(i32.eqz
(i32.eq
(i32.load8_u
(i32.add
(get_global $memset/dest)
(i32.const 15)
)
)
(i32.const 1)
)
)
(unreachable)
)
)
)
(;
[program.elements]
GLOBAL: NaN
GLOBAL: Infinity
FUNCTION_PROTOTYPE: isNaN
FUNCTION_PROTOTYPE: isFinite
FUNCTION_PROTOTYPE: clz
FUNCTION_PROTOTYPE: ctz
FUNCTION_PROTOTYPE: popcnt
FUNCTION_PROTOTYPE: rotl
FUNCTION_PROTOTYPE: rotr
FUNCTION_PROTOTYPE: abs
FUNCTION_PROTOTYPE: max
FUNCTION_PROTOTYPE: min
FUNCTION_PROTOTYPE: ceil
FUNCTION_PROTOTYPE: floor
FUNCTION_PROTOTYPE: copysign
FUNCTION_PROTOTYPE: nearest
FUNCTION_PROTOTYPE: reinterpret
FUNCTION_PROTOTYPE: sqrt
FUNCTION_PROTOTYPE: trunc
FUNCTION_PROTOTYPE: load
FUNCTION_PROTOTYPE: store
FUNCTION_PROTOTYPE: sizeof
FUNCTION_PROTOTYPE: select
FUNCTION_PROTOTYPE: unreachable
FUNCTION_PROTOTYPE: current_memory
FUNCTION_PROTOTYPE: grow_memory
FUNCTION_PROTOTYPE: changetype
FUNCTION_PROTOTYPE: assert
FUNCTION_PROTOTYPE: i8
FUNCTION_PROTOTYPE: i16
FUNCTION_PROTOTYPE: i32
FUNCTION_PROTOTYPE: i64
FUNCTION_PROTOTYPE: u8
FUNCTION_PROTOTYPE: u16
FUNCTION_PROTOTYPE: u32
FUNCTION_PROTOTYPE: u64
FUNCTION_PROTOTYPE: bool
FUNCTION_PROTOTYPE: f32
FUNCTION_PROTOTYPE: f64
FUNCTION_PROTOTYPE: isize
FUNCTION_PROTOTYPE: usize
GLOBAL: HEAP_BASE
FUNCTION_PROTOTYPE: memset/memset
GLOBAL: memset/dest
[program.exports]
;)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
var arr = changetype<i32[]>(Heap.allocate(sizeof<usize>() + 2 * sizeof<i32>()));
var arr = changetype<i32[]>(allocate_memory(sizeof<usize>() + 2 * sizeof<i32>()));
assert(arr.length == 0);
assert(arr.__capacity == 0);
@ -36,7 +36,7 @@ assert(arr[0] == 43);
assert(arr[1] == 44);
assert(arr[2] == 45);
arr.unshift(42); // see FIXME in std:array
arr.unshift(42);
assert(arr.length == 4);
assert(arr.__capacity == 4);

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,13 @@
(export "memory" (memory $0))
(start $start)
(func $std:array/CArray#__get (; 0 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(if
(i32.lt_s
(get_local $1)
(i32.const 0)
)
(unreachable)
)
(i32.load
(i32.add
(get_local $0)
@ -19,6 +26,13 @@
)
)
(func $std:array/CArray#__set (; 1 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
(if
(i32.lt_s
(get_local $1)
(i32.const 0)
)
(unreachable)
)
(i32.store
(i32.add
(get_local $0)

View File

@ -8,6 +8,13 @@
(export "memory" (memory $0))
(start $start)
(func $std:array/CArray#__get (; 0 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(if
(i32.lt_s
(get_local $1)
(i32.const 0)
)
(unreachable)
)
(return
(i32.load
(i32.add
@ -21,6 +28,13 @@
)
)
(func $std:array/CArray#__set (; 1 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
(if
(i32.lt_s
(get_local $1)
(i32.const 0)
)
(unreachable)
)
(i32.store
(i32.add
(get_local $0)
@ -247,16 +261,17 @@
GLOBAL: std:heap/ALIGN_SIZE
GLOBAL: std:heap/ALIGN_MASK
GLOBAL: std:heap/HEAP_OFFSET
CLASS_PROTOTYPE: std:heap/Heap
CLASS_PROTOTYPE: Heap
PROPERTY: std:heap/Heap.used
PROPERTY: std:heap/Heap.free
PROPERTY: std:heap/Heap.size
FUNCTION_PROTOTYPE: std:heap/Heap.allocate
FUNCTION_PROTOTYPE: std:heap/Heap.dispose
FUNCTION_PROTOTYPE: std:heap/Heap.copy
FUNCTION_PROTOTYPE: std:heap/Heap.fill
FUNCTION_PROTOTYPE: std:heap/Heap.compare
FUNCTION_PROTOTYPE: std:heap/allocate_memory
FUNCTION_PROTOTYPE: allocate_memory
FUNCTION_PROTOTYPE: std:heap/free_memory
FUNCTION_PROTOTYPE: free_memory
FUNCTION_PROTOTYPE: std:heap/copy_memory
FUNCTION_PROTOTYPE: std:heap/move_memory
FUNCTION_PROTOTYPE: move_memory
FUNCTION_PROTOTYPE: std:heap/set_memory
FUNCTION_PROTOTYPE: set_memory
FUNCTION_PROTOTYPE: std:heap/compare_memory
FUNCTION_PROTOTYPE: compare_memory
CLASS_PROTOTYPE: std:map/Map
CLASS_PROTOTYPE: Map
CLASS_PROTOTYPE: std:regexp/RegExp
@ -277,7 +292,11 @@
CLASS_PROTOTYPE: std:array/CArray
CLASS_PROTOTYPE: std:error/Error
CLASS_PROTOTYPE: std:error/RangeError
CLASS_PROTOTYPE: std:heap/Heap
FUNCTION_PROTOTYPE: std:heap/allocate_memory
FUNCTION_PROTOTYPE: std:heap/free_memory
FUNCTION_PROTOTYPE: std:heap/move_memory
FUNCTION_PROTOTYPE: std:heap/set_memory
FUNCTION_PROTOTYPE: std:heap/compare_memory
CLASS_PROTOTYPE: std:map/Map
CLASS_PROTOTYPE: std:regexp/RegExp
CLASS_PROTOTYPE: std:set/Set

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,21 @@
const size: usize = 42;
let ptr1: usize = Heap.allocate(size);
let ptr2: usize = Heap.allocate(size);
let ptr1: usize = allocate_memory(size);
let ptr2: usize = allocate_memory(size);
assert(ptr1 != ptr2);
Heap.fill(ptr1, 0x12, size);
set_memory(ptr1, 0x12, size);
let i: usize;
for (i = 0; i < size; ++i)
assert(load<u8>(ptr1 + i) == 0x12);
Heap.copy(ptr2, ptr1, size);
move_memory(ptr2, ptr1, size);
for (i = 0; i < size; ++i)
assert(load<u8>(ptr2 + i) == 0x12);
assert(Heap.compare(ptr1, ptr2, size) == 0);
assert(compare_memory(ptr1, ptr2, size) == 0);
Heap.dispose(ptr1);
Heap.dispose(ptr2);
free_memory(ptr1);
free_memory(ptr2);

File diff suppressed because it is too large Load Diff