1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

builtin: add builtin/wasm_bare (#13078)

This commit is contained in:
playX
2022-01-07 14:16:06 +03:00
committed by GitHub
parent c9d8fecc75
commit 287331bc19
5 changed files with 301 additions and 21 deletions

View File

@@ -111,12 +111,6 @@ fn memcmp(a &C.void, b &C.void, n usize) int {
[export: 'free']
[unsafe]
fn __free(ptr &C.void) {
/*
err := mm_free(ptr)
if err != .enoerror {
eprintln('free error:')
panic(err)
}*/
unsafe {
global_allocator.free_(ptr)
}

View File

@@ -38,7 +38,7 @@ fn system_alloc(_ voidptr, size usize) (voidptr, usize, u32) {
map_flags := MapFlags(int(MapFlags.map_private) | int(MapFlags.map_anonymous))
// END CONSTS
a, e := sys_mmap(&byte(0), u64(size + sizeof(u64)), mem_prot, map_flags, -1, 0)
a, e := sys_mmap(&byte(0), u64(size), mem_prot, map_flags, -1, 0)
if e == .enoerror {
return a, size, 0

View File

@@ -0,0 +1,173 @@
module builtin
import dlmalloc
__global global_allocator dlmalloc.Dlmalloc
[unsafe]
pub fn memcpy(dest &C.void, src &C.void, n usize) &C.void {
dest_ := unsafe { &byte(dest) }
src_ := unsafe { &byte(src) }
unsafe {
for i in 0 .. int(n) {
dest_[i] = src_[i]
}
}
return unsafe { dest }
}
[export: 'malloc']
[unsafe]
fn __malloc(n usize) &C.void {
return unsafe { global_allocator.malloc(n) }
}
[unsafe]
fn strlen(_s &C.void) usize {
s := unsafe { &byte(_s) }
mut i := 0
for ; unsafe { s[i] } != 0; i++ {}
return usize(i)
}
[unsafe]
fn realloc(old_area &C.void, new_size usize) &C.void {
if old_area == 0 {
return unsafe { malloc(int(new_size)) }
}
if new_size == usize(0) {
unsafe { free(old_area) }
return 0
}
old_size := unsafe { *(&u64(old_area - sizeof(u64))) }
if u64(new_size) <= old_size {
return unsafe { old_area }
} else {
new_area := unsafe { malloc(int(new_size)) }
unsafe { memmove(new_area, old_area, usize(old_size)) }
unsafe { free(old_area) }
return new_area
}
}
[unsafe]
fn memset(s &C.void, c int, n usize) &C.void {
mut s_ := unsafe { &char(s) }
for i in 0 .. int(n) {
unsafe {
s_[i] = char(c)
}
}
return unsafe { s }
}
[unsafe]
fn memmove(dest &C.void, src &C.void, n usize) &C.void {
dest_ := unsafe { &byte(dest) }
src_ := unsafe { &byte(src) }
mut temp_buf := unsafe { malloc(int(n)) }
for i in 0 .. int(n) {
unsafe {
temp_buf[i] = src_[i]
}
}
for i in 0 .. int(n) {
unsafe {
dest_[i] = temp_buf[i]
}
}
unsafe { free(temp_buf) }
return unsafe { dest }
}
[export: 'calloc']
[unsafe]
fn __calloc(nmemb usize, size usize) &C.void {
new_area := unsafe { malloc(int(nmemb) * int(size)) }
unsafe { memset(new_area, 0, nmemb * size) }
return new_area
}
fn getchar() int {
return 0
}
fn memcmp(a &C.void, b &C.void, n usize) int {
a_ := unsafe { &byte(a) }
b_ := unsafe { &byte(b) }
for i in 0 .. int(n) {
if unsafe { a_[i] != b_[i] } {
unsafe {
return a_[i] - b_[i]
}
}
}
return 0
}
[export: 'free']
[unsafe]
fn __free(ptr &C.void) {
unsafe {
global_allocator.free_(ptr)
}
}
fn vsprintf(str &char, format &char, ap &byte) int {
panic('vsprintf(): string interpolation is not supported in `-freestanding`')
}
fn vsnprintf(str &char, size usize, format &char, ap &byte) int {
panic('vsnprintf(): string interpolation is not supported in `-freestanding`')
}
enum Errno {
enoerror
eerror
}
// not really needed
fn bare_read(buf &byte, count u64) (i64, Errno) {
return 0, Errno.eerror
}
pub fn bare_print(buf &byte, len u64) {
}
fn bare_eprint(buf &byte, len u64) {
}
pub fn write(_fd i64, _buf &byte, _count u64) i64 {
return -1
}
[noreturn]
fn bare_panic(msg string) {
println('V panic' + msg)
exit(1)
}
fn bare_backtrace() string {
return 'backtraces are not available with `-freestanding`'
}
[export: 'exit']
[noreturn]
fn __exit(code int) {
unsafe {
// the only way to abort process execution in WASM
mut x := &int(voidptr(0))
*x = code
}
for {}
}
[export: 'qsort']
fn __qsort(base voidptr, nmemb usize, size usize, sort_cb FnSortCB) {
panic('qsort() is not yet implemented in `-freestanding`')
}
fn init_global_allocator() {
global_allocator = dlmalloc.new(get_wasm_allocator())
}

View File

@@ -0,0 +1,68 @@
module builtin
import dlmalloc
// Corresponding intrinsic to wasms `memory.grow` instruction
//
// This function, when called, will attempt to grow the default linear memory by the specified delta of pages.
// The current WebAssembly page size is 65536 bytes (64 KB). If memory is successfully grown then the previous size of memory, in pages, is returned.
// If memory cannot be grown then -1 is returned.
//
// The argument mem is the numerical index of which memory to return the size of. Note that currently the WebAssembly specification only supports one memory,
// so it is required that zero is passed in. The argument is present to be forward-compatible with future WebAssembly revisions.
// If a nonzero argument is passed to this function it will currently unconditionally abort
fn C.__builtin_wasm_memory_grow(mem u32, delta usize) usize
/// Corresponding intrinsic to wasm's `memory.size` instruction
///
/// This function, when called, will return the current memory size in units of
/// pages. The current WebAssembly page size is 65536 bytes (64 KB).
fn C.__builtin_wasm_memory_size(mem u32) usize
const page_size = 65536
fn system_alloc(_ voidptr, size usize) (voidptr, usize, u32) {
pages := size / page_size
prev := C.__builtin_wasm_memory_grow(0, pages)
if prev == -1 {
return voidptr(0), 0, 0
}
return voidptr(prev * page_size), pages * page_size, 0
}
fn system_remap(_ voidptr, _ voidptr, _ usize, _ usize, _ bool) voidptr {
return voidptr(0)
}
fn system_free_part(_ voidptr, _ voidptr, _ usize, _ usize) bool {
return false
}
fn system_free(_ voidptr, _ voidptr, _ usize) bool {
return false
}
fn system_allocates_zeros(_ voidptr) bool {
return false
}
fn system_page_size(_ voidptr) usize {
return page_size
}
fn system_can_release_part(_ voidptr, _ u32) bool {
return false
}
fn get_wasm_allocator() dlmalloc.Allocator {
return dlmalloc.Allocator{
alloc: system_alloc
remap: system_remap
free_part: system_free_part
free_: system_free
can_release_part: system_can_release_part
allocates_zeros: system_allocates_zeros
page_size: system_page_size
data: voidptr(0)
}
}