@aire-ux/aire-condensation
Version:
Client-side serialization library for Aire-UX
92 lines (91 loc) • 2.15 kB
JavaScript
/**
* 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;
}