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();
}

View File

@ -43,7 +43,7 @@ function copy_memory(dest: usize, src: usize, n: usize): void {
if (n >= 32) {
switch (dest & 3) {
// known to be != 0
case 1:
case 1: {
w = load<u32>(src);
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
@ -61,7 +61,8 @@ function copy_memory(dest: usize, src: usize, n: usize): void {
src += 16; dest += 16; n -= 16;
}
break;
case 2:
}
case 2: {
w = load<u32>(src);
store<u8>(dest++, load<u8>(src++));
store<u8>(dest++, load<u8>(src++));
@ -78,7 +79,8 @@ function copy_memory(dest: usize, src: usize, n: usize): void {
src += 16; dest += 16; n -= 16;
}
break;
case 3:
}
case 3: {
w = load<u32>(src);
store<u8>(dest++, load<u8>(src++));
n -= 1;
@ -94,6 +96,7 @@ function copy_memory(dest: usize, src: usize, n: usize): void {
src += 16; dest += 16; n -= 16;
}
break;
}
}
}

View File

@ -319,19 +319,19 @@ export class String {
function isWhiteSpaceOrLineTerminator(c: u16): bool {
switch (c) {
case 10: // <LF>
case 13: // <CR>
case 8232: // <LS>
case 8233: // <PS>
case 9: // <TAB>
case 11: // <VT>
case 12: // <FF>
case 32: // <SP>
case 160: // <NBSP>
case 65279: // <ZWNBSP>
case 10: // <LF>
case 13: // <CR>
case 8232: // <LS>
case 8233: // <PS>
case 9: // <TAB>
case 11: // <VT>
case 12: // <FF>
case 32: // <SP>
case 160: // <NBSP>
case 65279: { // <ZWNBSP>
return true;
default:
return false;
}
default: return false;
}
}
@ -405,27 +405,27 @@ function parse<T>(str: String, radix: i32 = 0): T {
if (!radix) {
if (code == CharCode._0 && len > 2) {
switch (<i32>load<u16>(ptr + 2, HEAD)) {
case CharCode.B:
case CharCode.b:
case CharCode.b: {
ptr += 4; len -= 2;
radix = 2;
break;
}
case CharCode.O:
case CharCode.o:
case CharCode.o: {
ptr += 4; len -= 2;
radix = 8;
break;
}
case CharCode.X:
case CharCode.x:
case CharCode.x: {
ptr += 4; len -= 2;
radix = 16;
break;
default:
}
default: {
radix = 10;
}
}
} else radix = 10;
} else if (radix < 2 || radix > 36) {