c-plus-wasm-loader
Version:
fixed bugs of cpp-wasm-loader
205 lines (204 loc) • 8.28 kB
JavaScript
;
var ASM_Memory = (function () {
function ASM_Memory(buffer) {
this.allocList = [];
this.sizeList = [];
this.allocPointer = 0;
this.mem = {
1: new Int8Array(buffer),
2: new Int16Array(buffer),
4: new Int32Array(buffer),
40: new Float32Array(buffer),
80: new Float64Array(buffer),
i8: new Int8Array(buffer),
i16: new Int16Array(buffer),
i32: new Int32Array(buffer),
f32: new Float32Array(buffer),
f64: new Float64Array(buffer),
char: new Int8Array(buffer),
uchar: new Uint8Array(buffer),
short: new Int16Array(buffer),
ushort: new Uint16Array(buffer),
int: new Int32Array(buffer),
uint: new Uint32Array(buffer),
float: new Float32Array(buffer),
double: new Float64Array(buffer)
};
this.max = buffer.byteLength - 1;
}
ASM_Memory.prototype.mark = function (stackTop) {
for (var i = 0; i <= stackTop; i++) {
this.allocPointer = i;
this.allocList[i] = true;
}
};
ASM_Memory.prototype.scan = function () {
var _this = this;
this.mem.char.forEach(function (val, i) {
if (val > 0) {
_this.allocPointer = i;
_this.allocList[i] = true;
}
});
};
ASM_Memory.prototype.set = function (addr, value, type) {
if (type === void 0) { type = 40; }
if (typeof addr !== "number" || typeof value !== "number") {
throw new Error("Address & value must be a number!");
}
type = (this.sizeList[addr] || type);
this.mem[type][Math.floor(addr / this.mem[type].BYTES_PER_ELEMENT)] = value;
return this;
};
ASM_Memory.prototype.get = function (addr, type) {
if (type === void 0) { type = 40; }
if (typeof addr !== "number") {
throw new Error("Address must be a number!");
}
type = (this.sizeList[addr] || type);
return this.mem[type][Math.floor(addr / this.mem[type].BYTES_PER_ELEMENT)];
};
ASM_Memory.prototype.avail = function (type) {
if (type === void 0) { type = 40; }
var totalBytes = (this.allocList.filter(function (l) { return l; }).length - this.mem.char.byteLength);
return Math.floor(totalBytes / this.mem[type].BYTES_PER_ELEMENT);
};
ASM_Memory.prototype.struct = function (values, type, nested) {
var _this = this;
var e = function () {
throw new Error("Struct can only use arrays of strings and numbers!");
};
if (!Array.isArray(values)) {
e();
}
var refs = {};
var offsets = [];
var sizeof = values.filter(function (k, i) { return i % 2 === 0; }).reduce(function (p, c, i) {
var thisSize = (c.split(":")[1] || type);
if (Array.isArray(values[(i * 2) + 1])) {
thisSize = "f32";
}
offsets.push(p);
return p + _this.mem[thisSize].BYTES_PER_ELEMENT;
}, 0);
var slots = this.malloc(sizeof, "char");
refs._addr = slots[0];
refs._length = sizeof;
refs._keys = values.filter(function (k, i) { return i % 2 === 0; });
refs._totalLength = sizeof;
var magicKeys = ["_addr", "_length", "_totalLength", "_keys", "_up"];
values.forEach(function (k, i) {
if (i % 2 === 0) {
if (typeof values[i] !== "string") {
e();
}
var key = values[i].split(":").shift();
var value = values[i + 1];
var addr = slots[0] + offsets[i / 2];
if (magicKeys.filter(function (k) { return nested ? (k !== "_up") : true; }).indexOf(key) !== -1) {
throw new Error("Can't use any of these keys in struct: " + magicKeys.join(", "));
}
if (Array.isArray(value)) {
refs[key] = _this.struct(["_up", addr].concat(value), type, true);
_this.sizeList[addr] = "f32";
_this.set(addr, refs[key]._addr);
refs._totalLength += refs[key]._length;
}
else if (typeof value === "number") {
refs[key] = addr;
_this.sizeList[addr] = values[i].split(":")[1] || type;
_this.set(refs[key], value || 0, values[i].split(":")[1] || type);
}
else {
e();
}
}
});
return refs;
};
ASM_Memory.prototype.malloc = function (size, type) {
var _this = this;
if (type === void 0) { type = 40; }
if (typeof size !== "number" || size < 1) {
throw new Error("Size must be greater than zero and a number!");
}
var addresses = [];
var remainingAdd = size * this.mem[type].BYTES_PER_ELEMENT;
var mod = this.allocPointer % this.mem[type].BYTES_PER_ELEMENT;
if (mod) {
this.allocPointer -= mod;
this.allocPointer += this.mem[type].BYTES_PER_ELEMENT;
}
var _loop_1 = function () {
var numTries = 0;
var tryAlloc = function () {
if (_this.allocPointer >= _this.max) {
_this.allocPointer = 0;
}
numTries++;
if (numTries >= _this.max) {
throw new Error("Not enough memory left!");
}
if (!_this.allocList[_this.allocPointer]) {
addresses.push(_this.allocPointer);
_this.allocPointer++;
if (addresses.length > 1) {
if (addresses[addresses.length - 1] - addresses[addresses.length - 2] !== 1) {
remainingAdd = size * _this.mem[type].BYTES_PER_ELEMENT;
addresses = [];
}
else {
remainingAdd--;
}
}
else {
remainingAdd--;
}
}
else {
_this.allocPointer++;
numTries % 500 === 0 ? setTimeout(tryAlloc, 0) : tryAlloc();
}
};
tryAlloc();
};
while (remainingAdd) {
_loop_1();
}
addresses.forEach(function (a) { _this.allocList[a] = true; });
var resultAddr = addresses.filter(function (a) { return a % _this.mem[type].BYTES_PER_ELEMENT === 0; });
resultAddr.forEach(function (addr) {
_this.sizeList[addr] = type;
});
return resultAddr;
};
ASM_Memory.prototype.free = function (addr, type) {
var _this = this;
if (type === void 0) { type = 40; }
var freeAlloc = function (start, end) {
while (start < end) {
_this.allocList[start] = false;
start++;
}
};
if (Array.isArray(addr)) {
addr.forEach(function (a) {
_this.mem[type][Math.floor(a / _this.mem[type].BYTES_PER_ELEMENT)] = 0;
});
freeAlloc(addr[0], addr[addr.length - 1] + this.mem[type].BYTES_PER_ELEMENT);
}
else {
addr._keys.forEach(function (key) {
if (typeof addr[key] === "number") {
_this.mem[type][addr[key] / _this.mem[type].BYTES_PER_ELEMENT] = 0;
}
else {
_this.free(addr[key], type);
}
});
freeAlloc(addr._addr, addr._addr + (addr._length * this.mem[type].BYTES_PER_ELEMENT));
}
return this;
};
return ASM_Memory;
}());