Commit 0768038c authored by Ondrej Zajicek (work)'s avatar Ondrej Zajicek (work)
Browse files

Filter: Clean up function call instruction

Pass instructions of function call arguments as vararg arguments to
FI_CALL instruction constructor and move necessary magic from parser
code to interpreter / instruction code.
parent fcb4dd0c
Loading
Loading
Loading
Loading
+9 −14
Original line number Diff line number Diff line
@@ -700,27 +700,22 @@ var_list: /* EMPTY */ { $$ = NULL; }
 | var_list ',' term { $$ = $3; $$->next = $1; }

function_call:
   CF_SYM_KNOWN '(' var_list ')' {
   CF_SYM_KNOWN '(' var_list ')'
   {
     if ($1->class != SYM_FUNCTION)
       cf_error("You can't call something which is not a function. Really.");

     struct f_inst *fc = f_new_inst(FI_CALL, $1);
     uint args = 0;
     /* Revert the var_list */
     struct f_inst *args = NULL;
     while ($3) {
       args++;
       struct f_inst *tmp = $3->next;
       $3->next = fc;
       struct f_inst *tmp = $3;
       $3 = $3->next;

       fc = $3;
       $3 = tmp;
       tmp->next = args;
       args = tmp;
     }

     if (args != $1->function->args)
       cf_error("Function call '%s' got %u arguments, need %u arguments.",
	   $1->name, args, $1->function->args);

     $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_VOID });
     $$->next = fc;
     $$ = f_new_inst(FI_CALL, args, $1);
   }
 ;

+17 −7
Original line number Diff line number Diff line
@@ -1079,8 +1079,22 @@

  INST(FI_CALL, 0, 1) {
    NEVER_CONSTANT;
    VARARG;
    SYMBOL;

    FID_NEW_BODY()
    ASSERT(sym->class == SYM_FUNCTION);

    if (whati->varcount != sym->function->args)
      cf_error("Function '%s' expects %u arguments, got %u arguments",
	       sym->name, sym->function->args, whati->varcount);

    /* Add implicit void slot for the return value */
    struct f_inst *tmp = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_VOID });
    tmp->next = whati->fvar;
    whati->fvar = tmp;
    what->size += tmp->size;

    FID_SAME_BODY()
      if (!(f1->sym->flags & SYM_FLAG_SAME))
	return 0;
@@ -1092,15 +1106,11 @@

    /* Push the body on stack */
    LINEX(sym->function);
    curline.vbase = curline.ventry;
    curline.emask |= FE_RETURN;

    /* Before this instruction was called, there was the T_VOID
     * automatic return value pushed on value stack and also
     * sym->function->args function arguments. Setting the
     * vbase to point to first argument. */
    ASSERT(curline.ventry >= sym->function->args);
    curline.ventry -= sym->function->args;
    curline.vbase = curline.ventry;
    /* Arguments on stack */
    fstk->vcnt += sym->function->args;

    /* Storage for local variables */
    memset(&(fstk->vstk[fstk->vcnt]), 0, sizeof(struct f_val) * sym->function->vars);