Skip to content

Commit 24bc0cc

Browse files
authored
Add import/export mutable globals (#329)
* feat: shared mutable globals * chore: clang format * feat: prevent global.set of immutable global * fix: add non-void return after FATAL in resolve_external_global * chore: clang format * test: add spec tests for globals * Add missing f64 global tests * fix: remove redundant mutability check Checking whether the global.set target is mutable is a validation check that is therefore redundant to perform at runtime (and only slows down execution). * Fix incorrect default number of arduino globals
1 parent ff45b86 commit 24bc0cc

File tree

14 files changed

+513
-57
lines changed

14 files changed

+513
-57
lines changed

src/Debug/debugger.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ void Debugger::inspect(Module *m, const uint16_t sizeStateArray,
844844
this->channel->write("%s\"globals\":[", addComma ? "," : "");
845845
addComma = true;
846846
for (uint32_t j = 0; j < m->global_count; j++) {
847-
auto v = m->globals + j;
847+
auto v = (*(m->globals + j))->value;
848848
printValue(v, j, j == (m->global_count - 1));
849849
}
850850
this->channel->write("]"); // closing globals
@@ -1063,15 +1063,15 @@ void Debugger::freeState(Module *m, uint8_t *interruptData) {
10631063
debug("globals freeing state and then allocating\n");
10641064
if (m->global_count > 0) free(m->globals);
10651065
if (amount > 0)
1066-
m->globals = static_cast<StackValue *>(
1067-
acalloc(amount, sizeof(StackValue), "globals"));
1066+
m->globals = static_cast<Global **>(
1067+
acalloc(amount, sizeof(Global *), "globals"));
10681068
} else {
10691069
debug("globals setting existing state to zero\n");
10701070
for (uint32_t i = 0; i < m->global_count; i++) {
10711071
debug("decreasing global_count\n");
1072-
StackValue *sv = &m->globals[i];
1073-
sv->value_type = 0;
1074-
sv->value.uint32 = 0;
1072+
Global *glob = m->globals[i];
1073+
glob->value->value_type = 0;
1074+
glob->value->value.uint32 = 0;
10751075
}
10761076
}
10771077
m->global_count = 0;
@@ -1221,7 +1221,7 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) {
12211221
if (type_index >= sizeof(valtypes)) {
12221222
FATAL("received unknown type %" PRIu8 "\n", type_index);
12231223
}
1224-
StackValue *sv = &m->globals[m->global_count++];
1224+
StackValue *sv = m->globals[m->global_count++]->value;
12251225
size_t qb = type_index == 0 || type_index == 2 ? 4 : 8;
12261226
debug("receiving type %" PRIu8 " and %d bytes \n",
12271227
type_index,
@@ -1539,7 +1539,7 @@ bool Debugger::handleUpdateGlobalValue(const Module *m, uint8_t *data) const {
15391539
if (index >= m->global_count) return false;
15401540

15411541
this->channel->write("Global %u being changed\n", index);
1542-
StackValue *v = &m->globals[index];
1542+
StackValue *v = m->globals[index]->value;
15431543
constexpr bool decodeType = false;
15441544
deserialiseStackValue(data, decodeType, v);
15451545
this->channel->write("Global %u changed to %u\n", index, v->value.uint32);

src/Interpreter/instructions.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,9 @@ bool i_instr_tee_local(Module *m) {
459459
bool i_instr_get_global(Module *m) {
460460
int32_t arg = read_LEB_32(&m->pc_ptr);
461461
#if TRACE
462-
debug(" - arg: 0x%x, got %s\n", arg, value_repr(&m->globals[arg]));
462+
debug(" - arg: 0x%x, got %s\n", arg, value_repr(m->globals[arg]));
463463
#endif
464-
m->stack[++m->sp] = m->globals[arg];
464+
m->stack[++m->sp] = *m->globals[arg]->value;
465465
return true;
466466
}
467467

@@ -470,7 +470,7 @@ bool i_instr_get_global(Module *m) {
470470
*/
471471
bool i_instr_set_global(Module *m) {
472472
uint32_t arg = read_LEB_32(&m->pc_ptr);
473-
m->globals[arg] = m->stack[m->sp--];
473+
*m->globals[arg]->value = m->stack[m->sp--];
474474
#if TRACE
475475
debug(" - arg: 0x%x, got %s\n", arg, value_repr(&m->stack[m->sp + 1]));
476476
#endif

src/Primitives/arduino.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,12 @@ int resolve_isr(int pin) {
136136

137137
#define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO)
138138

139-
// Global index for installing primitives
139+
#define NUM_GLOBALS 0
140+
#define ALL_GLOBALS NUM_GLOBALS
141+
142+
// Indices for installing primitives and globals
140143
int prim_index = 0;
144+
int global_index = 0;
141145

142146
/*
143147
Private macros to install a primitive
@@ -196,8 +200,25 @@ int prim_index = 0;
196200
#define arg8 get_arg(m, 8)
197201
#define arg9 get_arg(m, 9)
198202

203+
#define def_glob(name, type, mut, init_value) \
204+
StackValue name##_sv{.value_type = type, init_value}; \
205+
Global name = { \
206+
.mutability = mut, .import_field = #name, .value = &name##_sv};
207+
208+
#define install_global(global_name) \
209+
{ \
210+
dbg_info("installing global: %s\n", #global_name); \
211+
if (global_index < ALL_GLOBALS) { \
212+
globals[global_index++] = (global_name); \
213+
} else { \
214+
FATAL("global_index out of bounds"); \
215+
} \
216+
}
217+
199218
// The primitive table
200219
PrimitiveEntry primitives[ALL_PRIMITIVES];
220+
// The globals table
221+
Global globals[ALL_GLOBALS];
201222

202223
//
203224
uint32_t param_arr_len0[0] = {};
@@ -1076,6 +1097,19 @@ bool resolve_external_memory(char *symbol, Memory **val) {
10761097
return false;
10771098
}
10781099

1100+
bool resolve_external_global(char *symbol, Global **val) {
1101+
debug("Resolve external global for %s \n", symbol);
1102+
1103+
for (auto &global : globals) {
1104+
if (!strcmp(symbol, global.import_field)) {
1105+
*val = &global;
1106+
return true;
1107+
}
1108+
}
1109+
FATAL("Could not find global %s \n", symbol);
1110+
return false;
1111+
}
1112+
10791113
//------------------------------------------------------
10801114
// Restore external state when restoring a snapshot
10811115
//------------------------------------------------------

src/Primitives/emulated.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,12 @@
3232

3333
#define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO)
3434

35-
// Global index for installing primitives
35+
#define NUM_GLOBALS 0
36+
#define ALL_GLOBALS NUM_GLOBALS
37+
38+
// Indices for installing primitives and globals
3639
int prim_index = 0;
40+
int global_index = 0;
3741

3842
double sensor_emu = 0;
3943

@@ -94,8 +98,25 @@ double sensor_emu = 0;
9498
#define arg8 get_arg(m, 8)
9599
#define arg9 get_arg(m, 9)
96100

101+
#define def_glob(name, type, mut, init_value) \
102+
StackValue name##_sv{.value_type = type, init_value}; \
103+
Global name = { \
104+
.mutability = mut, .import_field = #name, .value = &name##_sv};
105+
106+
#define install_global(global_name) \
107+
{ \
108+
dbg_info("installing global: %s\n", #global_name); \
109+
if (global_index < ALL_GLOBALS) { \
110+
globals[global_index++] = (global_name); \
111+
} else { \
112+
FATAL("global_index out of bounds"); \
113+
} \
114+
}
115+
97116
// The primitive table
98117
PrimitiveEntry primitives[ALL_PRIMITIVES];
118+
// The globals table
119+
Global globals[ALL_GLOBALS];
99120

100121
//
101122
uint32_t param_arr_len0[0] = {};
@@ -728,6 +749,19 @@ bool resolve_external_memory(char *symbol, Memory **val) {
728749
// return false; // unreachable
729750
}
730751

752+
bool resolve_external_global(char *symbol, Global **val) {
753+
debug("Resolve external global for %s \n", symbol);
754+
755+
for (auto &global : globals) {
756+
if (!strcmp(symbol, global.import_field)) {
757+
*val = &global;
758+
return true;
759+
}
760+
}
761+
FATAL("Could not find global %s \n", symbol);
762+
// return false; // unreachable
763+
}
764+
731765
//------------------------------------------------------
732766
// Restore external state when restoring a snapshot
733767
//------------------------------------------------------

src/Primitives/idf.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,12 @@
3232

3333
#define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO)
3434

35-
// Global index for installing primitives
35+
#define NUM_GLOBALS 0
36+
#define ALL_GLOBALS NUM_GLOBALS
37+
38+
// Indices for installing primitives and globals
3639
int prim_index = 0;
40+
int global_index = 0;
3741

3842
double sensor_emu = 0;
3943

@@ -94,8 +98,25 @@ double sensor_emu = 0;
9498
#define arg8 get_arg(m, 8)
9599
#define arg9 get_arg(m, 9)
96100

101+
#define def_glob(name, type, mut, init_value) \
102+
StackValue name##_sv{.value_type = type, init_value}; \
103+
Global name = { \
104+
.mutability = mut, .import_field = #name, .value = &name##_sv};
105+
106+
#define install_global(global_name) \
107+
{ \
108+
dbg_info("installing global: %s\n", #global_name); \
109+
if (global_index < ALL_GLOBALS) { \
110+
globals[global_index++] = (global_name); \
111+
} else { \
112+
FATAL("global_index out of bounds"); \
113+
} \
114+
}
115+
97116
// The primitive table
98117
PrimitiveEntry primitives[ALL_PRIMITIVES];
118+
// The globals table
119+
Global globals[ALL_GLOBALS];
99120

100121
//
101122
uint32_t param_arr_len0[0] = {};
@@ -295,6 +316,19 @@ bool resolve_external_memory(char *symbol, Memory **val) {
295316
return false;
296317
}
297318

319+
bool resolve_external_global(char *symbol, Global **val) {
320+
debug("Resolve external global for %s \n", symbol);
321+
322+
for (auto &global : globals) {
323+
if (!strcmp(symbol, global.import_field)) {
324+
*val = &global;
325+
return true;
326+
}
327+
}
328+
FATAL("Could not find global %s \n", symbol);
329+
return false;
330+
}
331+
298332
//------------------------------------------------------
299333
// Restore external state when restoring a snapshot
300334
//------------------------------------------------------

src/Primitives/primitives.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ bool resolve_primitive(char *symbol, Primitive *val);
2525
*/
2626
bool resolve_external_memory(char *symbol, Memory **val);
2727

28+
bool resolve_external_global(char *symbol, Global **val);
29+
2830
void install_primitives();
2931

3032
std::vector<IOStateElement *> get_io_state(Module *m);

src/Primitives/zephyr.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,12 @@
3939
#endif
4040
#define ALL_PRIMITIVES OBB_PRIMITIVES + 7
4141

42-
// Global index for installing primitives
42+
#define NUM_GLOBALS 0
43+
#define ALL_GLOBALS NUM_GLOBALS
44+
45+
// Indices for installing primitives and globals
4346
int prim_index = 0;
47+
int global_index = 0;
4448

4549
double sensor_emu = 0;
4650

@@ -101,8 +105,25 @@ double sensor_emu = 0;
101105
#define arg8 get_arg(m, 8)
102106
#define arg9 get_arg(m, 9)
103107

108+
#define def_glob(name, type, mut, init_value) \
109+
StackValue name##_sv{.value_type = type, init_value}; \
110+
Global name = { \
111+
.mutability = mut, .import_field = #name, .value = &name##_sv};
112+
113+
#define install_global(global_name) \
114+
{ \
115+
dbg_info("installing global: %s\n", #global_name); \
116+
if (global_index < ALL_GLOBALS) { \
117+
globals[global_index++] = (global_name); \
118+
} else { \
119+
FATAL("global_index out of bounds"); \
120+
} \
121+
}
122+
104123
// The primitive table
105124
PrimitiveEntry primitives[ALL_PRIMITIVES];
125+
// The globals table
126+
Global globals[ALL_GLOBALS];
106127

107128
//
108129
uint32_t param_arr_len0[0] = {};
@@ -627,6 +648,19 @@ bool resolve_external_memory(char *symbol, Memory **val) {
627648
return false;
628649
}
629650

651+
bool resolve_external_global(char *symbol, Global **val) {
652+
debug("Resolve external global for %s \n", symbol);
653+
654+
for (auto &global : globals) {
655+
if (!strcmp(symbol, global.import_field)) {
656+
*val = &global;
657+
return true;
658+
}
659+
}
660+
FATAL("Could not find global %s \n", symbol);
661+
return false;
662+
}
663+
630664
//------------------------------------------------------
631665
// Restore external state when restoring a snapshot
632666
//------------------------------------------------------

src/WARDuino.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ class WARDuino {
112112

113113
uint32_t get_export_fidx(Module *m, const char *name);
114114

115+
uint32_t get_export_global_idx(Module *m, const char *name);
116+
115117
void handleInterrupt(size_t len, uint8_t *buff) const;
116118

117119
void instantiate_module(Module *m, uint8_t *bytes, uint32_t byte_count);

src/WARDuino/CallbackHandler.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,9 @@ Callback::Callback(Module *m, std::string id, uint32_t tidx) {
193193
}
194194

195195
void Callback::resolve_event(const Event &e) {
196-
dbg_trace("Callback(%s, %i): resolving Event(%s, \"%s\")\n", topic.c_str(),
197-
table_index, e.topic.c_str(), e.payload);
196+
dbg_trace("Callback(%s, %u): resolving Event(%s, \"%s\")\n", topic.c_str(),
197+
static_cast<unsigned int>(table_index), e.topic.c_str(),
198+
e.payload.c_str());
198199

199200
// Copy topic and payload to linear memory
200201
uint32_t start = 10000; // TODO use reserved area in linear memory

0 commit comments

Comments
 (0)