Skip to content

Commit 8373cfa

Browse files
authored
Move getValue/setValue to library functions (#16852)
Previously these two runtime functions lived in `runtime_safe_heap.js`. This change makes them into library functions and splits other parts of `runtime_safe_heap.js` into `runtime_asan.js` so that `runtime_safe_heap.js` not only contains code that is included/needed when SAFE_HEAP is enabled. One of the main effects of this change is that getValue/setValue are not potentially available in MINIMAL_RUNTIME, although I've left using them this mode as a followup.
1 parent 4c1dcf8 commit 8373cfa

File tree

7 files changed

+189
-165
lines changed

7 files changed

+189
-165
lines changed

emcc.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,6 +1819,8 @@ def phase_linker_setup(options, state, newargs, user_settings):
18191819
if not settings.BOOTSTRAPPING_STRUCT_INFO:
18201820
# Include the internal library function since they are used by runtime functions.
18211821
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$getWasmTableEntry', '$setWasmTableEntry']
1822+
if settings.SAFE_HEAP or not settings.MINIMAL_RUNTIME:
1823+
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$getValue', '$setValue']
18221824

18231825
if settings.MAIN_MODULE:
18241826
assert not settings.SIDE_MODULE

src/library_getvalue.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/**
2+
* @license
3+
* Copyright 2022 The Emscripten Authors
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
var LibraryMemOps = {
8+
$setValue__docs: `
9+
/** @param {number} ptr
10+
@param {number} value
11+
@param {string} type
12+
@param {number|boolean=} noSafe */`,
13+
$setValue: function(ptr, value, type = 'i8', noSafe) {
14+
if (type.endsWith('*')) type = '{{{ POINTER_TYPE }}}';
15+
#if SAFE_HEAP
16+
if (noSafe) {
17+
switch (type) {
18+
case 'i1': {{{ makeSetValue('ptr', '0', 'value', 'i1', undefined, undefined, undefined, /*noSafe=*/true) }}}; break;
19+
case 'i8': {{{ makeSetValue('ptr', '0', 'value', 'i8', undefined, undefined, undefined, /*noSafe=*/true) }}}; break;
20+
case 'i16': {{{ makeSetValue('ptr', '0', 'value', 'i16', undefined, undefined, undefined, /*noSafe=*/true) }}}; break;
21+
case 'i32': {{{ makeSetValue('ptr', '0', 'value', 'i32', undefined, undefined, undefined, /*noSafe=*/true) }}}; break;
22+
case 'i64': {{{ makeSetValue('ptr', '0', 'value', 'i64', undefined, undefined, undefined, /*noSafe=*/true) }}}; break;
23+
case 'float': {{{ makeSetValue('ptr', '0', 'value', 'float', undefined, undefined, undefined, /*noSafe=*/true) }}}; break;
24+
case 'double': {{{ makeSetValue('ptr', '0', 'value', 'double', undefined, undefined, undefined, /*noSafe=*/true) }}}; break;
25+
default: abort('invalid type for setValue: ' + type);
26+
}
27+
return;
28+
}
29+
#endif
30+
switch (type) {
31+
case 'i1': {{{ makeSetValue('ptr', '0', 'value', 'i1') }}}; break;
32+
case 'i8': {{{ makeSetValue('ptr', '0', 'value', 'i8') }}}; break;
33+
case 'i16': {{{ makeSetValue('ptr', '0', 'value', 'i16') }}}; break;
34+
case 'i32': {{{ makeSetValue('ptr', '0', 'value', 'i32') }}}; break;
35+
case 'i64': {{{ makeSetValue('ptr', '0', 'value', 'i64') }}}; break;
36+
case 'float': {{{ makeSetValue('ptr', '0', 'value', 'float') }}}; break;
37+
case 'double': {{{ makeSetValue('ptr', '0', 'value', 'double') }}}; break;
38+
default: abort('invalid type for setValue: ' + type);
39+
}
40+
},
41+
42+
$getValue__docs: `
43+
/** @param {number} ptr
44+
@param {string} type
45+
@param {number|boolean=} noSafe */`,
46+
$getValue: function(ptr, type = 'i8', noSafe) {
47+
if (type.endsWith('*')) type = '{{{ POINTER_TYPE }}}';
48+
#if SAFE_HEAP
49+
if (noSafe) {
50+
switch (type) {
51+
case 'i1': return {{{ makeGetValue('ptr', '0', 'i1', undefined, undefined, undefined, undefined, /*noSafe=*/true) }}};
52+
case 'i8': return {{{ makeGetValue('ptr', '0', 'i8', undefined, undefined, undefined, undefined, /*noSafe=*/true) }}};
53+
case 'i16': return {{{ makeGetValue('ptr', '0', 'i16', undefined, undefined, undefined, undefined, /*noSafe=*/true) }}};
54+
case 'i32': return {{{ makeGetValue('ptr', '0', 'i32', undefined, undefined, undefined, undefined, /*noSafe=*/true) }}};
55+
case 'i64': return {{{ makeGetValue('ptr', '0', 'i64', undefined, undefined, undefined, undefined, /*noSafe=*/true) }}};
56+
case 'float': return {{{ makeGetValue('ptr', '0', 'float', undefined, undefined, undefined, undefined, /*noSafe=*/true) }}};
57+
case 'double': return {{{ makeGetValue('ptr', '0', 'double', undefined, undefined, undefined, undefined, /*noSafe=*/true) }}};
58+
default: abort('invalid type for getValue: ' + type);
59+
}
60+
return;
61+
}
62+
#endif
63+
switch (type) {
64+
case 'i1': return {{{ makeGetValue('ptr', '0', 'i1') }}};
65+
case 'i8': return {{{ makeGetValue('ptr', '0', 'i8') }}};
66+
case 'i16': return {{{ makeGetValue('ptr', '0', 'i16') }}};
67+
case 'i32': return {{{ makeGetValue('ptr', '0', 'i32') }}};
68+
case 'i64': return {{{ makeGetValue('ptr', '0', 'i64') }}};
69+
case 'float': return {{{ makeGetValue('ptr', '0', 'float') }}};
70+
case 'double': return {{{ makeGetValue('ptr', '0', 'double') }}};
71+
default: abort('invalid type for getValue: ' + type);
72+
}
73+
return null;
74+
},
75+
};
76+
77+
mergeInto(LibraryManager.library, LibraryMemOps);

src/modules.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ global.LibraryManager = {
3737
let libraries = [
3838
'library.js',
3939
'library_formatString.js',
40+
'library_getvalue.js',
4041
'library_math.js',
4142
'library_path.js',
4243
'library_syscall.js',
@@ -388,8 +389,6 @@ function exportRuntime() {
388389
let runtimeElements = [
389390
'ccall',
390391
'cwrap',
391-
'setValue',
392-
'getValue',
393392
'allocate',
394393
'UTF8ArrayToString',
395394
'UTF8ToString',

src/preamble.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,13 @@ if (typeof WebAssembly != 'object') {
4242
}
4343
#endif
4444

45+
#if SAFE_HEAP
4546
#include "runtime_safe_heap.js"
47+
#endif
48+
49+
#if USE_ASAN
50+
#include "runtime_asan.js"
51+
#endif
4652

4753
// Wasm globals
4854

src/preamble_minimal.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@
44
* SPDX-License-Identifier: MIT
55
*/
66

7+
#if SAFE_HEAP
78
#include "runtime_safe_heap.js"
9+
#endif
10+
11+
#if USE_ASAN
12+
#include "runtime_asan.js"
13+
#endif
814

915
#if ASSERTIONS || SAFE_HEAP
1016
/** @type {function(*, string=)} */

src/runtime_asan.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* @license
3+
* Copyright 2019 The Emscripten Authors
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
#if !USE_ASAN
8+
#error "should only be inclded in USE_ASAN mode"
9+
#endif
10+
11+
// C versions of asan_js_{load|store}_* will be used from compiled code, which have
12+
// ASan instrumentation on them. However, until the wasm module is ready, we
13+
// must access things directly.
14+
15+
/** @suppress{duplicate} */
16+
function _asan_js_load_1(ptr) {
17+
if (runtimeInitialized) return _asan_c_load_1(ptr);
18+
return HEAP8[ptr];
19+
}
20+
/** @suppress{duplicate} */
21+
function _asan_js_load_1u(ptr) {
22+
if (runtimeInitialized) return _asan_c_load_1u(ptr);
23+
return HEAPU8[ptr];
24+
}
25+
/** @suppress{duplicate} */
26+
function _asan_js_load_2(ptr) {
27+
if (runtimeInitialized) return _asan_c_load_2(ptr);
28+
return HEAP16[ptr];
29+
}
30+
/** @suppress{duplicate} */
31+
function _asan_js_load_2u(ptr) {
32+
if (runtimeInitialized) return _asan_c_load_2u(ptr);
33+
return HEAPU16[ptr];
34+
}
35+
/** @suppress{duplicate} */
36+
function _asan_js_load_4(ptr) {
37+
if (runtimeInitialized) return _asan_c_load_4(ptr);
38+
return HEAP32[ptr];
39+
}
40+
/** @suppress{duplicate} */
41+
function _asan_js_load_4u(ptr) {
42+
if (runtimeInitialized) return _asan_c_load_4u(ptr) >>> 0;
43+
return HEAPU32[ptr];
44+
}
45+
/** @suppress{duplicate} */
46+
function _asan_js_load_f(ptr) {
47+
if (runtimeInitialized) return _asan_c_load_f(ptr);
48+
return HEAPF32[ptr];
49+
}
50+
/** @suppress{duplicate} */
51+
function _asan_js_load_d(ptr) {
52+
if (runtimeInitialized) return _asan_c_load_d(ptr);
53+
return HEAPF64[ptr];
54+
}
55+
56+
/** @suppress{duplicate} */
57+
function _asan_js_store_1(ptr, val) {
58+
if (runtimeInitialized) return _asan_c_store_1(ptr, val);
59+
return HEAP8[ptr] = val;
60+
}
61+
/** @suppress{duplicate} */
62+
function _asan_js_store_1u(ptr, val) {
63+
if (runtimeInitialized) return _asan_c_store_1u(ptr, val);
64+
return HEAPU8[ptr] = val;
65+
}
66+
/** @suppress{duplicate} */
67+
function _asan_js_store_2(ptr, val) {
68+
if (runtimeInitialized) return _asan_c_store_2(ptr, val);
69+
return HEAP16[ptr] = val;
70+
}
71+
/** @suppress{duplicate} */
72+
function _asan_js_store_2u(ptr, val) {
73+
if (runtimeInitialized) return _asan_c_store_2u(ptr, val);
74+
return HEAPU16[ptr] = val;
75+
}
76+
/** @suppress{duplicate} */
77+
function _asan_js_store_4(ptr, val) {
78+
if (runtimeInitialized) return _asan_c_store_4(ptr, val);
79+
return HEAP32[ptr] = val;
80+
}
81+
/** @suppress{duplicate} */
82+
function _asan_js_store_4u(ptr, val) {
83+
if (runtimeInitialized) return _asan_c_store_4u(ptr, val) >>> 0;
84+
return HEAPU32[ptr] = val;
85+
}
86+
/** @suppress{duplicate} */
87+
function _asan_js_store_f(ptr, val) {
88+
if (runtimeInitialized) return _asan_c_store_f(ptr, val);
89+
return HEAPF32[ptr] = val;
90+
}
91+
/** @suppress{duplicate} */
92+
function _asan_js_store_d(ptr, val) {
93+
if (runtimeInitialized) return _asan_c_store_d(ptr, val);
94+
return HEAPF64[ptr] = val;
95+
}

0 commit comments

Comments
 (0)