blob: 07cfbd89874514d151368c5972374f4cf30679b1 [file] [edit]
#if SAFE_HEAP
function getSafeHeapType(bytes, isFloat) {
switch (bytes) {
case 1: return 'i8';
case 2: return 'i16';
case 4: return isFloat ? 'float' : 'i32';
case 8: return 'double';
default: assert(0);
}
}
#if SAFE_HEAP_LOG
var SAFE_HEAP_COUNTER = 0;
#endif
function SAFE_HEAP_STORE(dest, value, bytes, isFloat) {
#if SAFE_HEAP_LOG
out('SAFE_HEAP store: ' + [dest, value, bytes, isFloat, SAFE_HEAP_COUNTER++]);
#endif
if (dest <= 0) abort('segmentation fault storing ' + bytes + ' bytes to address ' + dest);
if (dest % bytes !== 0) abort('alignment error storing to address ' + dest + ', which was expected to be aligned to a multiple of ' + bytes);
if (dest + bytes > HEAP32[DYNAMICTOP_PTR>>2]) abort('segmentation fault, exceeded the top of the available dynamic heap when storing ' + bytes + ' bytes to address ' + dest + '. DYNAMICTOP=' + HEAP32[DYNAMICTOP_PTR>>2]);
assert(DYNAMICTOP_PTR);
assert(HEAP32[DYNAMICTOP_PTR>>2] <= TOTAL_MEMORY);
setValue(dest, value, getSafeHeapType(bytes, isFloat), 1);
}
function SAFE_HEAP_STORE_D(dest, value, bytes) {
SAFE_HEAP_STORE(dest, value, bytes, true);
}
function SAFE_HEAP_LOAD(dest, bytes, unsigned, isFloat) {
if (dest <= 0) abort('segmentation fault loading ' + bytes + ' bytes from address ' + dest);
if (dest % bytes !== 0) abort('alignment error loading from address ' + dest + ', which was expected to be aligned to a multiple of ' + bytes);
if (dest + bytes > HEAP32[DYNAMICTOP_PTR>>2]) abort('segmentation fault, exceeded the top of the available dynamic heap when loading ' + bytes + ' bytes from address ' + dest + '. DYNAMICTOP=' + HEAP32[DYNAMICTOP_PTR>>2]);
assert(DYNAMICTOP_PTR);
assert(HEAP32[DYNAMICTOP_PTR>>2] <= TOTAL_MEMORY);
var type = getSafeHeapType(bytes, isFloat);
var ret = getValue(dest, type, 1);
if (unsigned) ret = unSign(ret, parseInt(type.substr(1)), 1);
#if SAFE_HEAP_LOG
out('SAFE_HEAP load: ' + [dest, ret, bytes, isFloat, unsigned, SAFE_HEAP_COUNTER++]);
#endif
return ret;
}
function SAFE_HEAP_LOAD_D(dest, bytes, unsigned) {
return SAFE_HEAP_LOAD(dest, bytes, unsigned, true);
}
function SAFE_FT_MASK(value, mask) {
var ret = value & mask;
if (ret !== value) {
abort('Function table mask error: function pointer is ' + value + ' which is masked by ' + mask + ', the likely cause of this is that the function pointer is being called by the wrong type.');
}
return ret;
}
function segfault() {
abort('segmentation fault');
}
function alignfault() {
abort('alignment fault');
}
function ftfault() {
abort('Function table mask error');
}
#endif