}
void GC_collect(void) {
- val_t **pointers;
val_t *pointer;
int i;
int j;
for (i = 0; i < staticObjects.size; i++) {
object = *(val_t*)(staticObject->pointer);
if (!ISNULL(object) && ISOBJ(object)) {
- *(staticObject->pointer) = (val_t)GC_evacuation((obj_t)object);
+ *(staticObject->pointer) = GC_evacuation((obj_t)object);
}
staticObject = staticObject->next;
}
while (frame != NULL) {
- pointers = frame->REG_pointer;
for (j = 0; j < frame->REG_size; j++) {
- object = (val_t)(pointers[j]);
+ object = frame->REG[j];
if (!ISNULL(object) && ISOBJ(object)) {
- pointers[j] = (val_t*)GC_evacuation((obj_t)object);
+ frame->REG[j] = GC_evacuation((obj_t)object);
}
}
if (frame == frame->prev) break;
extern int glob_argc;
extern char ** glob_argv;
-/* Stack frames */
+/* Stack frames.
+ * Are used to store local variables (REGS) of function and provide information for stack dump */
struct stack_frame_t {
struct stack_frame_t *prev; /* previous stack frame */
const char *file; /* source filename (.nit) */
int line; /* line number (in the source) */
const char *meth; /* human function name (usually the method name) */
int REG_size; /* number of local variables */
- val_t **REG_pointer; /* array of local variables */
+ val_t REG[1]; /* local variables (flexible array) */
};
extern struct stack_frame_t *stack_frame_head;
if not strs.has_key(i) then strs[i] = "closctx->variable[{i}]"
else
strs = once new HashMap[Int, String]
- if not strs.has_key(i) then strs[i] = "REG[{i}]"
+ if not strs.has_key(i) then strs[i] = "fra.me.REG[{i}]"
end
s = strs[i]
ids[e] = s
if location != null then
ll = location.line_start
end
- v.add_decl("struct stack_frame_t frame = \{NULL, NULL, {ll}, LOCATE_{v.basecname}, {std_slots_nb}\};")
- v.add_instr("frame.prev = stack_frame_head; stack_frame_head = &frame;")
- v.add_instr("frame.file = LOCATE_{v.visitor.module.name};")
- v.add_instr("frame.REG_pointer = (val_t **)®")
-
- # Add local variables
- if std_slots_nb == 0 then
- v.add_decl("val_t *REG = NULL;")
+ # Encapsulate the frame ('me') in a larger structure ('fra') that has enough space to store the local variables (REG)
+ if std_slots_nb > 1 then
+ v.add_decl("struct \{struct stack_frame_t me; val_t MORE_REG[{std_slots_nb-1}];\} fra;")
else
- var init_vals = new Buffer
- init_vals.append "val_t REG[{std_slots_nb}] = \{ NIT_NULL"
- for i in [1..std_slots_nb[ do init_vals.append(", NIT_NULL")
- init_vals.append " \};"
- v.add_decl(init_vals.to_s)
+ v.add_decl("struct \{struct stack_frame_t me;\} fra;")
+ end
+ v.add_instr("fra.me.prev = stack_frame_head; stack_frame_head = &fra.me;")
+ v.add_instr("fra.me.file = LOCATE_{v.visitor.module.name};")
+ v.add_instr("fra.me.line = {ll};")
+ v.add_instr("fra.me.meth = LOCATE_{v.basecname};")
+ v.add_instr("fra.me.REG_size = {std_slots_nb};")
+
+ # Declare/initialize local variables
+ for i in [0..std_slots_nb[ do
+ v.add_instr("fra.me.REG[{i}] = NIT_NULL;")
end
for i in [0..tag_slots_nb[ do
v.add_decl("val_t REGB{i};")
# Compile body
body.compile_to_c(v)
- v.add_instr("stack_frame_head = frame.prev;")
+ v.add_instr("stack_frame_head = fra.me.prev;")
v.return_label = old_rl
var r = result
if r != null then
v.add_instr("{closcnv}.variable = closctx->variable;")
v.add_instr("{closcnv}.closurevariable = closctx->closurevariable;")
else
- v.add_instr("{closcnv}.variable = REG;")
+ v.add_instr("{closcnv}.variable = fra.me.REG;")
v.add_instr("{closcnv}.closurevariable = CREG;")
end