/** NB! Must be called in correct order! */ public void addArg(String name, PhantomType type) throws PlcException { if (type == null) { // Object a = null; a.getClass(); throw new PlcException("Method add_arg", "null type of arg", name); } args_def.add(new ArgDefinition(name, type)); svars.add_stack_var(new PhantomVariable(name, type)); }
public void generate_code(CodeGeneratorState s) throws PlcException, IOException { if (code == null) { c.emitRet(); // empty function code return; } // ------------------------------------------ // traverse tree to allocate automatic vars? // ------------------------------------------ int n_auto_vars = svars.getUsedSlots(); int n_int_auto_vars = isvars.getUsedSlots(); // ------------------------------------------ // ------------------------------------------ // generate prologue code here // ------------------------------------------ // check number of args int n_args = args_def.size(); String good_args_label = c.getLabel(); c.emitIConst_32bit(n_args); c.emitISubLU(); c.emitJz(good_args_label); // wrong count - throw string // BUG! Need less consuming way of reporting this. Maybe by // calling class object Method? Or by summoning something? c.emitString("arg count: " + name + " in " + s.get_class().getName()); c.emitThrow(); c.markLabel(good_args_label); if (requestDebug) c.emitDebug((byte) 0x1, "Enabled debug"); // push nulls to reserve stack space for autovars // BUG! We can execute vars initialization code here, can we? // We can if code does not depend on auto vars itself, or depends only on // previous ones. // TODO: BUG! autovars in arguments are already on stack, we don't have to reserve space for (int i = n_auto_vars; i > 0; i--) c.emitPushNull(); // TODO introduce instruction to reserve o+i space in one step // Reserve integer stack place for int vars for (int i = n_int_auto_vars; i > 0; i--) c.emitIConst_0(); // ------------------------------------------ // ------------------------------------------ // generate main code by descending the tree // ------------------------------------------ code.generate_code(c, s); // ------------------------------------------ // ------------------------------------------ // generate epilogue code here // ------------------------------------------ if (requestDebug) c.emitDebug((byte) 0x2, "Disabled debug"); c.emitRet(); // catch the fall-out // ------------------------------------------ }