mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-12 14:31:28 +00:00
Progress and a tiny WASM binary parser
This commit is contained in:
@ -7,28 +7,31 @@
|
||||
* @module std/assembly/allocator/arena
|
||||
*//***/
|
||||
|
||||
import { MASK as AL_MASK } from "./common/alignment";
|
||||
import { AL_MASK } from "./common";
|
||||
|
||||
var startOffset: usize = (HEAP_BASE + AL_MASK) & ~AL_MASK;
|
||||
var offset: usize = startOffset;
|
||||
|
||||
@global
|
||||
export function allocate_memory(size: usize): usize {
|
||||
if (!size) return 0;
|
||||
var ptr = offset;
|
||||
var newPtr = (ptr + size + AL_MASK) & ~AL_MASK;
|
||||
var pagesBefore = current_memory();
|
||||
if (newPtr > <usize>pagesBefore << 16) {
|
||||
let pagesNeeded = ((newPtr - ptr + 0xffff) & ~0xffff) >>> 16;
|
||||
let pagesWanted = max(pagesBefore, pagesNeeded); // double memory
|
||||
if (grow_memory(pagesWanted) < 0) {
|
||||
if (grow_memory(pagesNeeded) < 0) {
|
||||
unreachable(); // out of memory
|
||||
const MAX_SIZE: usize = 1 << 30;
|
||||
if (size && size < MAX_SIZE) {
|
||||
let ptr = offset;
|
||||
let newPtr = (ptr + size + AL_MASK) & ~AL_MASK;
|
||||
let pagesBefore = current_memory();
|
||||
if (newPtr > <usize>pagesBefore << 16) {
|
||||
let pagesNeeded = ((newPtr - ptr + 0xffff) & ~0xffff) >>> 16;
|
||||
let pagesWanted = max(pagesBefore, pagesNeeded); // double memory
|
||||
if (grow_memory(pagesWanted) < 0) {
|
||||
if (grow_memory(pagesNeeded) < 0) {
|
||||
unreachable(); // out of memory
|
||||
}
|
||||
}
|
||||
}
|
||||
offset = newPtr;
|
||||
return ptr;
|
||||
}
|
||||
offset = newPtr;
|
||||
return ptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@global
|
||||
|
@ -347,7 +347,7 @@ export function allocate_memory(request: usize): usize {
|
||||
* a hard-coded limit on the maximum allocation size because of the way this
|
||||
* allocator works.
|
||||
*/
|
||||
if (request + HEADER_SIZE > MAX_ALLOC) {
|
||||
if (request > MAX_ALLOC - HEADER_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,13 +0,0 @@
|
||||
/**
|
||||
* Shared alignment constants.
|
||||
* @module std/assembly/allocator/common/alignment
|
||||
*//***/
|
||||
|
||||
/** 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;
|
16
std/assembly/allocator/common/index.ts
Normal file
16
std/assembly/allocator/common/index.ts
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Shared allocator constants.
|
||||
* @module std/assembly/allocator/common
|
||||
*//***/
|
||||
|
||||
/** Number of alignment bits. */
|
||||
export const AL_BITS: u32 = 3;
|
||||
|
||||
/** Number of possible alignment values. */
|
||||
export const AL_SIZE: usize = 1 << <usize>AL_BITS;
|
||||
|
||||
/** Mask to obtain just the alignment bits. */
|
||||
export const AL_MASK: usize = AL_SIZE - 1;
|
||||
|
||||
/** Maximum 32-bit allocation size. */
|
||||
export const MAX_SIZE_32: usize = 1 << 30; // 1GB
|
@ -16,10 +16,11 @@
|
||||
// FL: first level, SL: second level, AL: alignment, SB: small block
|
||||
|
||||
import {
|
||||
BITS as AL_BITS,
|
||||
SIZE as AL_SIZE,
|
||||
MASK as AL_MASK
|
||||
} from "./common/alignment";
|
||||
AL_BITS,
|
||||
AL_SIZE,
|
||||
AL_MASK,
|
||||
MAX_SIZE_32
|
||||
} from "./common";
|
||||
|
||||
const SL_BITS: u32 = 5;
|
||||
const SL_SIZE: usize = 1 << <usize>SL_BITS;
|
||||
@ -32,6 +33,8 @@ const FL_BITS: u32 = (sizeof<usize>() == sizeof<u32>()
|
||||
: 32 // ^= up to 4GB per block
|
||||
) - SB_BITS;
|
||||
|
||||
// assert(1 << (FL_BITS + SB_BITS) == MAX_SIZE_32);
|
||||
|
||||
// ╒════════════════ Block structure layout (32-bit) ══════════════╕
|
||||
// 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
|
||||
@ -457,7 +460,8 @@ export function allocate_memory(size: usize): usize {
|
||||
|
||||
// search for a suitable block
|
||||
var data: usize = 0;
|
||||
if (size && size < Block.MAX_SIZE) {
|
||||
if (size && size <= Block.MAX_SIZE) {
|
||||
// 32-bit MAX_SIZE is 1 << 30 and itself aligned, hence the following can't overflow MAX_SIZE
|
||||
size = max<usize>((size + AL_MASK) & ~AL_MASK, Block.MIN_SIZE);
|
||||
|
||||
let block = root.search(size);
|
||||
|
Reference in New Issue
Block a user