Commit fce659b3 authored by Laszlo Domoszlai's avatar Laszlo Domoszlai
Browse files

inline eval when an argument is returned in the spine such tail call elimination

can be applied.
parent 2920cde0
......@@ -170,12 +170,42 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
}
case CT_VAR:
if (expr->local_type == VAR_LOCAL) {
Thunk* thunk = forward_to(get_dst(root_frame_ptr), local(frame_ptr, ((VarEntry*) expr)->index));
Thunk* thunk = local(frame_ptr, ((VarEntry*) expr)->index);
while (thunk->desc == (Desc*) __FORWARD_PTR__) {
thunk = thunk->_forward_ptr;
}
forward_to(get_dst(root_frame_ptr), thunk);
set_return(root_frame_ptr, thunk);
if (thunk->desc->type == FT_FUN) {
// Destroy stack frame before eval, it is not needed any more
// Greatly reduces stack usage
destroy_stack_frame(root_frame_ptr);
frame_ptr = stack_top_a;
// Here frame_ptr == root_frame_ptr
for (int i = 0; i < thunk->desc->arity; i++) {
// TODO: handle strictness
push_a(thunk->_args[i]);
}
expr = ((FunEntry*) thunk->desc)->body;
continue;
}
else if(thunk->desc->type == FT_PRIM) {
for (int i = 0; i < thunk->desc->arity; i++) {
// TODO: handle strictness
push_a(thunk->_args[i]);
}
((PrimEntry*) thunk->desc)->exec(root_frame_ptr);
}
// Destroy stack frame before eval, it is not needed any more
// Greatly reduces stack usage
destroy_stack_frame(root_frame_ptr);
set_return(root_frame_ptr, eval(thunk));
return;
}else{
// Safe to destroy, the next call has no arguments
......
......@@ -92,8 +92,10 @@ void init_desc() {
__REAL__ = alloc_prim("REAL");
__STRING__ = alloc_prim("STRING");
__ARRAY__ = alloc_prim("ARRAY");
__FORWARD_PTR__ = alloc_prim("FWD");
}
struct FunEntry* __FORWARD_PTR__;
struct FunEntry* __INT__;
struct FunEntry* __BOOL__;
struct FunEntry* __CHAR__;
......
......@@ -69,6 +69,7 @@ bool is_strict_fun_arg(FunEntry* f, int nr_arg);
int printDesc(Desc* f);
extern struct FunEntry* __FORWARD_PTR__;
extern struct FunEntry* __INT__;
extern struct FunEntry* __BOOL__;
extern struct FunEntry* __CHAR__;
......
......@@ -17,12 +17,11 @@ Thunk* forward_to(Thunk* target, Thunk* thunk) {
assert(thunk != NULL);
if (target != NULL) {
target->desc = NULL;
target->desc = (Desc*) __FORWARD_PTR__;
target->_forward_ptr = thunk;
return thunk;
} else {
return thunk;
}
}
return thunk;
}
int thunk_size(Thunk* thunk) {
......@@ -117,7 +116,7 @@ struct Thunk* updateF(Thunk* target, Desc* f) {
struct Thunk* eval(Thunk* thunk) {
assert(thunk != NULL);
while (thunk->desc == NULL) {
while (thunk->desc == (Desc*) __FORWARD_PTR__) {
thunk = thunk->_forward_ptr;
}
......@@ -150,7 +149,7 @@ struct Thunk* eval(Thunk* thunk) {
}
void print(Thunk* thunk, bool force) {
while (thunk->desc == NULL) {
while (thunk->desc == (Desc*) __FORWARD_PTR__) {
thunk = thunk->_forward_ptr;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment