forked from emscripten-core/emscripten
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathruntime_safe_heap.js
107 lines (100 loc) · 3.7 KB
/
runtime_safe_heap.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/**
* @license
* Copyright 2019 The Emscripten Authors
* SPDX-License-Identifier: MIT
*/
#if !SAFE_HEAP
#error "should only be inclded in SAFE_HEAP mode"
#endif
/** @param {number|boolean=} isFloat */
function getSafeHeapType(bytes, isFloat) {
switch (bytes) {
case 1: return 'i8';
case 2: return 'i16';
case 4: return isFloat ? 'float' : 'i32';
case 8: return isFloat ? 'double' : 'i64';
default: assert(0);
}
}
#if SAFE_HEAP_LOG
var SAFE_HEAP_COUNTER = 0;
#endif
/** @param {number|boolean=} isFloat */
function SAFE_HEAP_STORE(dest, value, bytes, isFloat) {
#if CAN_ADDRESS_2GB
dest >>>= 0;
#endif
#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 SAFE_HEAP == 1
if (dest % bytes !== 0) abort('alignment error storing to address ' + dest + ', which was expected to be aligned to a multiple of ' + bytes);
#else
if (dest % bytes !== 0) warnOnce('alignment error in a memory store operation, alignment was a multiple of ' + (((dest ^ (dest-1)) >> 1) + 1) + ', but was was expected to be aligned to a multiple of ' + bytes);
#endif
#if EXIT_RUNTIME
if (runtimeInitialized && !runtimeExited) {
#else
if (runtimeInitialized) {
#endif
var brk = _sbrk() >>> 0;
if (dest + bytes > brk) abort('segmentation fault, exceeded the top of the available dynamic heap when storing ' + bytes + ' bytes to address ' + dest + '. DYNAMICTOP=' + brk);
assert(brk >= _emscripten_stack_get_base()); // sbrk-managed memory must be above the stack
assert(brk <= HEAP8.length);
}
setValue_safe(dest, value, getSafeHeapType(bytes, isFloat));
return value;
}
function SAFE_HEAP_STORE_D(dest, value, bytes) {
return SAFE_HEAP_STORE(dest, value, bytes, true);
}
/** @param {number|boolean=} isFloat */
function SAFE_HEAP_LOAD(dest, bytes, unsigned, isFloat) {
#if CAN_ADDRESS_2GB
dest >>>= 0;
#endif
if (dest <= 0) abort('segmentation fault loading ' + bytes + ' bytes from address ' + dest);
#if SAFE_HEAP == 1
if (dest % bytes !== 0) abort('alignment error loading from address ' + dest + ', which was expected to be aligned to a multiple of ' + bytes);
#else
if (dest % bytes !== 0) warnOnce('alignment error in a memory load operation, alignment was a multiple of ' + (((dest ^ (dest-1)) >> 1) + 1) + ', but was was expected to be aligned to a multiple of ' + bytes);
#endif
#if EXIT_RUNTIME
if (runtimeInitialized && !runtimeExited) {
#else
if (runtimeInitialized) {
#endif
var brk = _sbrk() >>> 0;
if (dest + bytes > brk) abort('segmentation fault, exceeded the top of the available dynamic heap when loading ' + bytes + ' bytes from address ' + dest + '. DYNAMICTOP=' + brk);
assert(brk >= _emscripten_stack_get_base()); // sbrk-managed memory must be above the stack
assert(brk <= HEAP8.length);
}
var type = getSafeHeapType(bytes, isFloat);
var ret = getValue_safe(dest, type);
if (unsigned) ret = unSign(ret, parseInt(type.substr(1), 10));
#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() {
#if SAFE_HEAP == 1
abort('alignment fault');
#else
warnOnce('alignment fault');
#endif
}