test.inc \
test.sma \
example.inc \
-example.sma
+example.sma \
+recurse.inc \
+recurse.sma
EXTRA_DIST = $(files_DATA)
--- /dev/null
+#if defined EXAMPLE_INC
+#endinput
+#endif
+#define EXAMPLE_INC
+
+native printf(format[], ...);
+native native_rec(arg1, str[], arg2);
--- /dev/null
+#include "recurse.inc"
+
+/* To compile:
+ * embryo_cc ./recurse.sma -orecurse.amx
+ *
+ * To test run:
+ * embryo ./recurse.amx
+ */
+
+main()
+{
+ new ret = 0;
+
+ ret = rec1(1, "Recurse Test", 123);
+ return ret;
+}
+
+public rec1(arg1, str[], arg2)
+{
+ new ret = 0;
+
+ printf("rec1(arg1=%i, str='%s', arg2=%i);\n", arg1, str, arg2);
+ ret = native_rec(arg1, str, arg2 * 2);
+ return ret;
+}
return EMBRYO_ERROR_NONE;
}
+static Embryo_Cell
+exported_rec(Embryo_Program *ep, Embryo_Cell *params)
+{
+ Embryo_Cell *cptr;
+ Embryo_Function fn;
+ Embryo_Cell ret, arg1, arg2;
+
+ // params[0] = number of bytes of params passed
+ if (params[0] != 3 * sizeof(Embryo_Cell)) return -1;
+ arg1 = params[1];
+ arg2 = params[3];
+ arg1++;
+
+ if (arg1 > 7)
+ {
+ printf("arg1 == %i\n", arg1);
+ return arg1;
+ }
+
+ // call the rec1 again
+ fn = embryo_program_function_find(ep, "rec1");
+ if (fn != EMBRYO_FUNCTION_NONE)
+ {
+ char buf[128];
+
+ printf("... recurse!\n");
+ snprintf(buf, sizeof(buf), "SMELLY %i", arg1);
+ embryo_parameter_cell_push(ep, arg1);
+ embryo_parameter_string_push(ep, buf);
+ embryo_parameter_cell_push(ep, arg2);
+ while (embryo_program_run(ep, fn) == EMBRYO_PROGRAM_SLEEP);
+ ret = embryo_program_return_value_get(ep);
+ }
+ return ret + 1;
+}
+
/* another example native call */
/*
static Embryo_Cell
exit(-1);
}
embryo_program_native_call_add(ep, "printf", exported_printf);
+ embryo_program_native_call_add(ep, "native_rec", exported_rec);
embryo_program_vm_push(ep);
if (args > 0)
#ifndef _EMBRYO_H
#define _EMBRYO_H
-/*
- * FIXME:
- * handle the case where:
- * [C] -> [vm] -> [native call] -> [same or other func in same vm]
- */
#ifdef __cplusplus
extern "C" {
Embryo_Header *hdr;
Embryo_Func_Stub *func;
unsigned char *code, *data;
- Embryo_Cell pri, alt, stk, frm, hea;
+ Embryo_Cell pri, alt, stk, frm, hea, hea_start;
Embryo_Cell reset_stk, reset_hea, *cip;
Embryo_UCell codesize;
int i;
int num;
if (!ep) return EMBRYO_PROGRAM_FAIL;
- if (ep->run_count > 0) return EMBRYO_PROGRAM_BUSY;
if (!(ep->flags & EMBRYO_FLAG_RELOC))
{
-
ep->error = EMBRYO_ERROR_INIT;
return EMBRYO_PROGRAM_FAIL;
}
ep->error = EMBRYO_ERROR_INIT;
return EMBRYO_PROGRAM_FAIL;
}
+ if (ep->run_count > 0)
+ {
+ /* return EMBRYO_PROGRAM_BUSY; */
+ /* FIXME: test C->vm->C->vm recursion more fully */
+ /* it seems to work... just fine!!! - strange! */
+ }
/* set up the registers */
hdr = (Embryo_Header *)ep->base;
codesize = (Embryo_UCell)(hdr->dat - hdr->cod);
code = ep->base + (int)hdr->cod;
data = ep->base + (int)hdr->dat;
- hea = ep->hea;
+ hea_start = hea = ep->hea;
stk = ep->stk;
reset_stk = stk;
reset_hea = hea;
/* check stack/heap before starting to run */
CHKMARGIN();
+ /* track recursion depth */
ep->run_count++;
/* start running */
}
}
ep->run_count--;
+
+ //
+ ep->hea = hea_start;
+
return EMBRYO_PROGRAM_OK;
}