Implement function types / indirect calls / trampolines (#39)

This commit is contained in:
Daniel Wirtz
2018-03-12 14:06:39 +01:00
committed by GitHub
parent 5d5f458ab1
commit 423533c6b0
67 changed files with 7499 additions and 5763 deletions

View File

@ -5,16 +5,14 @@
* sure that there are no more references to cleared memory afterwards. Always aligns to 8 bytes.
*/
const AL_BITS: usize = 3;
const AL_SIZE: usize = 1 << AL_BITS;
const AL_MASK: usize = AL_SIZE - 1;
import { MASK as AL_MASK } from "./common/alignment";
var OFFSET: usize = (HEAP_BASE + AL_MASK) & ~AL_MASK;
var offset: usize = (HEAP_BASE + AL_MASK) & ~AL_MASK;
@global
export function allocate_memory(size: usize): usize {
if (!size) return 0;
var ptr = OFFSET;
var ptr = offset;
var newPtr = (ptr + size + AL_MASK) & ~AL_MASK;
var pagesBefore = current_memory();
if (newPtr > <usize>pagesBefore << 16) {
@ -26,7 +24,7 @@ export function allocate_memory(size: usize): usize {
}
}
}
OFFSET = newPtr;
offset = newPtr;
return ptr;
}
@ -37,5 +35,5 @@ export function free_memory(ptr: usize): void {
@global
export function reset_memory(): void {
OFFSET = (HEAP_BASE + AL_MASK) & ~AL_MASK;
offset = (HEAP_BASE + AL_MASK) & ~AL_MASK;
}

View File

@ -61,7 +61,7 @@ const MIN_ALLOC: usize = 1 << MIN_ALLOC_LOG2;
* heaps will have multiple allocations, so the real maximum allocation limit
* is at most 1gb.
*/
const MAX_ALLOC_LOG2: usize = 31;
const MAX_ALLOC_LOG2: usize = 30; // 31;
const MAX_ALLOC: usize = 1 << MAX_ALLOC_LOG2;
/*
@ -338,7 +338,7 @@ function lower_bucket_limit(bucket: usize): u32 {
}
@global
function allocate_memory(request: usize): usize {
export function allocate_memory(request: usize): usize {
var original_bucket: usize, bucket: usize;
/*
@ -475,7 +475,7 @@ function allocate_memory(request: usize): usize {
}
@global
function free_memory(ptr: usize): void {
export function free_memory(ptr: usize): void {
var bucket: usize, i: usize;
/*
@ -539,3 +539,8 @@ function free_memory(ptr: usize): void {
*/
list_push(buckets$get(bucket), changetype<List>(ptr_for_node(i, bucket)));
}
@global
export function reset_memory(): void {
unreachable();
}

View File

@ -0,0 +1,8 @@
/** Number of alignment bits. */
export const BITS: u32 = 3;
/** Number of possible alignment values. */
export const SIZE: usize = 1 << <usize>BITS;
/** Mask to obtain just the alignment bits. */
export const MASK: usize = SIZE - 1;

View File

@ -20,4 +20,6 @@ export function free_memory(ptr: usize): void {
}
@global
export { reset_memory } from "./none";
export function reset_memory(): void {
unreachable();
}

View File

@ -1,15 +0,0 @@
/**
* @file Memory Allocator Stub
*/
export function allocate_memory(size: usize): usize {
throw new Error("not supported");
}
export function free_memory(ptr: usize): void {
throw new Error("not supported");
}
export function reset_memory(): void {
throw new Error("not supported");
}

View File

@ -19,4 +19,6 @@ export function free_memory(ptr: usize): void {
}
@global
export { reset_memory } from "./none";
export function reset_memory(): void {
unreachable();
}

View File

@ -13,9 +13,11 @@
// └───────────────────────────────────────────────┴─────────╨─────┘
// FL: first level, SL: second level, AL: alignment, SB: small block
const AL_BITS: u32 = 3; // always align to 8 bytes
const AL_SIZE: usize = 1 << <usize>AL_BITS;
const AL_MASK: usize = AL_SIZE - 1;
import {
BITS as AL_BITS,
SIZE as AL_SIZE,
MASK as AL_MASK
} from "./common/alignment";
const SL_BITS: u32 = 5;
const SL_SIZE: usize = 1 << <usize>SL_BITS;
@ -32,7 +34,7 @@ const FL_BITS: u32 = (sizeof<usize>() == sizeof<u32>()
// 3 2 1
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits
// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┼─┼─┤
// │ size │L│F│ ◄─┐
// │ size │L│F│ ◄─┐ info
// ╞═══════════════════════════════════════════════════════════╧═╧═╡ │ ┐
// │ if free: ◄ prev │ ◄─┤ usize
// ├───────────────────────────────────────────────────────────────┤ │
@ -495,4 +497,7 @@ export function free_memory(data: usize): void {
}
}
export { reset_memory } from "./none";
@global
export function reset_memory(): void {
unreachable();
}