UNPKG

@aire-ux/aire-condensation

Version:

Client-side serialization library for Aire-UX

92 lines (91 loc) 2.15 kB
/** * alias for a constructor type */ export class Dynamic { } /** * represents a location in a region (memory arena) */ export class Address { constructor(region) { if (isRegion(region)) { this.value = region.address(); } else { this.value = region; } } } /** * guard allowing use of pointers as addresses * @param t the value to check */ export function isPointer(t) { return t.address !== undefined; } /** * allocate a value into a pointer * @param value the value to allocate * @param region the region to allocate into */ export function allocate(value, region = DefaultRegion) { const address = new Address(region); region.values[address.value] = value; const handler = { get: (target, prop, receiver) => { const property = value[prop]; if (prop === "value") { return value; } if (prop === "address") { return address; } if (property) { return property; } return Reflect.get(target, prop, receiver); }, }; return new Proxy(value, handler); } export class Regions { } Regions.regions = new Map(); /** * a contiguous set of memory locations */ export class Region { constructor(name) { this.values = []; if (name) { Regions.regions.set(name, this); } else { Regions.regions.set(Region.value++, this); } } address() { return this.values.length; } addressOf(t) { return new Address(this.values.indexOf(t)); } move(ptr, target) { const result = this.delete(ptr.address); if (result) { return allocate(ptr.value, target); } return undefined; } delete(address) { let vs = this.values, value = vs[address.value]; if (value) { return vs.splice(address.value, 1)[0]; } return null; } } export const DefaultRegion = new Region(); function isRegion(r) { return r.values !== undefined; }