mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-24 12:11:50 +00:00
Implement function types / indirect calls / trampolines (#39)
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
8
std/assembly/allocator/common/alignment.ts
Normal file
8
std/assembly/allocator/common/alignment.ts
Normal 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;
|
@ -20,4 +20,6 @@ export function free_memory(ptr: usize): void {
|
||||
}
|
||||
|
||||
@global
|
||||
export { reset_memory } from "./none";
|
||||
export function reset_memory(): void {
|
||||
unreachable();
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
@ -19,4 +19,6 @@ export function free_memory(ptr: usize): void {
|
||||
}
|
||||
|
||||
@global
|
||||
export { reset_memory } from "./none";
|
||||
export function reset_memory(): void {
|
||||
unreachable();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Reference in New Issue
Block a user