// Alignment guarantees // @ts-ignore: decorator @inline export const AL_BITS: u32 = 4; // 16 bytes to fit up to v128 // @ts-ignore: decorator @inline export const AL_SIZE: usize = 1 << AL_BITS; // @ts-ignore: decorator @inline export const AL_MASK: usize = AL_SIZE - 1; // Extra debugging // @ts-ignore: decorator @inline export const DEBUG = true; // ╒════════════════ Common block 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 // ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤ // │ MM info │ -16 // ├───────────────────────────────────────────────────────────────┤ // │ GC info │ -12 // ├───────────────────────────────────────────────────────────────┤ // │ runtime id │ -8 // ├───────────────────────────────────────────────────────────────┤ // │ runtime size │ -4 // ╞═══════════════════════════════════════════════════════════════╡ // │ ... │ ref @unmanaged export class BLOCK { /** Memory manager info. */ mmInfo: usize; // WASM64 needs adaption /** Garbage collector info. */ gcInfo: u32; /** Runtime class id. */ rtId: u32; /** Runtime object size. */ rtSize: u32; } // @ts-ignore: decorator @inline export const BLOCK_OVERHEAD = (offsetof() + AL_MASK) & ~AL_MASK; // @ts-ignore: decorator @inline export const BLOCK_MAXSIZE: usize = (1 << 30) - BLOCK_OVERHEAD; /////////////////////////////////// Type information interface //////////////////////////////////// import { RTTI_BASE } from "builtins"; import { RTTIData, RTTIFlags } from "common/rtti"; // @ts-ignore: decorator @unsafe @global export function __typeinfo(id: u32): RTTIFlags { var ptr = RTTI_BASE; return !id || id > load(ptr) ? unreachable() : changetype(ptr + id * offsetof()).flags; } // @ts-ignore: decorator @unsafe @global export function __instanceof(ref: usize, superId: u32): bool { // keyword var id = changetype(ref - BLOCK_OVERHEAD).rtId; var ptr = RTTI_BASE; if (id && id <= load(ptr)) { do if (id == superId) return true; while (id = changetype(ptr + id * offsetof()).base); } return false; } ///////////////////////////////////////////// Helpers ///////////////////////////////////////////// import { idof } from "builtins"; import { ArrayBufferView } from "arraybuffer"; // @ts-ignore: decorator @unsafe @global export function __allocArray(length: i32, alignLog2: usize, id: u32, data: usize = 0): usize { var array = __alloc(offsetof(), id); var bufferSize = length << alignLog2; var buffer = __alloc(bufferSize, idof()); changetype(array).data = changetype(buffer); // TODO/RT: retains changetype(array).dataStart = buffer; changetype(array).dataLength = bufferSize; store(changetype(array), length, offsetof("length_")); if (data) memory.copy(buffer, data, bufferSize); return array; }