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

use function table for create_thunk functions instead of one big function + switch

parent 4bfb088d
......@@ -38,79 +38,83 @@
} \
else \
{ \
push_a(create_thunk(arg, frame_ptr)); \
push_a(create_thunk_funs[arg->type](arg, frame_ptr)); \
} \
argmask <<= 1;
Thunk* (*create_thunk_funs[9]) (Code* expr, int frame_ptr);
struct Thunk* create_thunk(Code* expr, int frame_ptr)
struct Thunk* create_thunk_app_static(Code* expr, int frame_ptr)
{
assert(expr != NULL);
// TODO: check over application
// TODO: enforce strictness in ADT/Record
// TODO: CAS
switch (expr->type) {
case CT_APP_PRIM:
case CT_APP_FUN:
case CT_APP_THUNK:
{
Thunk* thunk = createF(((AppEntry*) expr)->f);
Thunk* thunk = createF(((AppEntry*) expr)->f);
assert(thunk->desc->arity == expr->nr_args);
for (int i = 0; i < expr->nr_args; i++) {
thunk->_args[i] = create_thunk(((AppEntry*) expr)->args[i], frame_ptr);
}
assert(thunk->desc->arity == expr->nr_args);
return thunk;
for (int i = 0; i < expr->nr_args; i++) {
thunk->_args[i] = create_thunk_funs[((AppEntry*) expr)->args[i]->type](((AppEntry*) expr)->args[i], frame_ptr);
}
case CT_APP_DYN:
{
Thunk* basethunk = local(frame_ptr, ((AppEntry*)expr)->var.index);
if(!basethunk->desc->hnf) basethunk = eval(basethunk);
Desc* slice =
get_slice(basethunk->desc->type == FT_SLICE ?
((SliceEntry*) basethunk->desc)->forward_ptr : basethunk->desc, basethunk->desc->arity + expr->nr_args);
return thunk;
}
Thunk* thunk = createF(slice);
struct Thunk* create_thunk_app_dyn(Code* expr, int frame_ptr)
{
Thunk* basethunk = local(frame_ptr, ((AppEntry*)expr)->var.index);
if(!basethunk->desc->hnf) basethunk = eval(basethunk);
assert(thunk->desc->arity == basethunk->desc->arity + expr->nr_args);
Desc* slice =
get_slice(basethunk->desc->type == FT_SLICE ?
((SliceEntry*) basethunk->desc)->forward_ptr : basethunk->desc, basethunk->desc->arity + expr->nr_args);
memcpy(&thunk->_args, &basethunk->_args, sizeof(Thunk*) * basethunk->desc->arity);
for (int i = 0; i < expr->nr_args; i++) {
thunk->_args[basethunk->desc->arity + i]
= create_thunk(((AppEntry*) expr)->args[i], frame_ptr);
}
Thunk* thunk = createF(slice);
return thunk;
assert(thunk->desc->arity == basethunk->desc->arity + expr->nr_args);
memcpy(&thunk->_args, &basethunk->_args, sizeof(Thunk*) * basethunk->desc->arity);
for (int i = 0; i < expr->nr_args; i++) {
thunk->_args[basethunk->desc->arity + i]
= create_thunk_funs[((AppEntry*) expr)->args[i]->type](((AppEntry*) expr)->args[i], frame_ptr);
}
return thunk;
}
struct Thunk* create_thunk_var(Code* expr, int frame_ptr)
{
return local(frame_ptr, ((VarEntry*) expr)->index);
}
struct Thunk* create_thunk_var_strict(Code* expr, int frame_ptr)
{
Thunk* arg = local(frame_ptr, ((VarEntry*) expr)->index);
if(arg->desc->unboxable)
{
return createT(arg);
}
case CT_VAR:
return local(frame_ptr, ((VarEntry*) expr)->index);
case CT_VAR_STRICT:
else
{
Thunk* arg = local(frame_ptr, ((VarEntry*) expr)->index);
if(arg->desc->unboxable)
{
return createT(arg);
}
else
{
return arg;
}
return arg;
}
case CT_THUNK:
return &((ThunkEntry*) expr)->thunk;
case CT_SELECT:
case CT_IF:
// Only here to avoid intervalum check at switch
abort("Unexpected code type");
return NULL;
}
}
struct Thunk* create_thunk_thunk(Code* expr, int frame_ptr)
{
return &((ThunkEntry*) expr)->thunk;
}
void init_code()
{
create_thunk_funs[CT_VAR] = create_thunk_var;
create_thunk_funs[CT_VAR_STRICT] = create_thunk_var_strict;
create_thunk_funs[CT_APP_THUNK] = create_thunk_app_static;
create_thunk_funs[CT_APP_PRIM] = create_thunk_app_static;
create_thunk_funs[CT_APP_FUN] = create_thunk_app_static;
create_thunk_funs[CT_APP_DYN] = create_thunk_app_dyn;
create_thunk_funs[CT_SELECT] = NULL;
create_thunk_funs[CT_IF] = NULL;
create_thunk_funs[CT_THUNK] = create_thunk_thunk;
}
void exec(Code* expr, int frame_ptr, int root_frame_ptr)
......@@ -128,7 +132,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
switch (expr->type) {
case CT_APP_PRIM:
{
{
Desc* slice = ((AppEntry*) expr)->f;
for (int i = 0; i < expr->nr_args; i++) {
......@@ -142,7 +146,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
return;
}
case CT_APP_FUN:
{
{
Desc* slice = ((AppEntry*) expr)->f;
int new_frame_ptr = stack_top_a;
......@@ -166,7 +170,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
for (int i = 0; i < expr->nr_args; i++) {
thunk->_args[i]
= create_thunk(((AppEntry*) expr)->args[i], frame_ptr);
= create_thunk_funs[((AppEntry*) expr)->args[i]->type](((AppEntry*) expr)->args[i], frame_ptr);
}
set_return(root_frame_ptr, thunk);
......@@ -236,7 +240,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
for (int i = 0; i < expr->nr_args; i++) {
thunk->_args[basethunk->desc->arity + i]
= create_thunk(((AppEntry*) expr)->args[i], frame_ptr);
= create_thunk_funs[((AppEntry*) expr)->args[i]->type](((AppEntry*) expr)->args[i], frame_ptr);
}
set_return(root_frame_ptr, thunk);
......@@ -395,7 +399,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
struct Thunk* eval(Thunk* thunk) {
assert(thunk != NULL);
follow_thunk(thunk);
switch(thunk->desc->type) {
......
......@@ -63,6 +63,8 @@ struct IfEntry {
struct Code* fexpr;
};
void init_code();
void exec(Code* expr, int frame_ptr, int root_frame_ptr);
struct Thunk* eval(Thunk* thunk);
......
......@@ -28,6 +28,7 @@ int main ( int argc, char *argv[] )
init_mem();
init_desc();
init_prim();
init_code();
char* input = "..\\tests\\Braun.bsapl";
......@@ -100,7 +101,7 @@ int main ( int argc, char *argv[] )
// compute and print the elapsed time in millisec
double elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0; // sec to ms
elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0; // us to ms
printf("\n\nexecution time: %G ms\n", elapsedTime);
printf("\n\nExecution time: %G ms\n", elapsedTime);
#endif
#ifdef DEBUG
......
Supports Markdown
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