|
|
@ -26,6 +26,14 @@ |
|
|
|
#define min(x, y) ((x) > (y) ? (y) : (x)) |
|
|
|
#define max(x, y) ((x) < (y) ? (y) : (x)) |
|
|
|
|
|
|
|
#ifdef __GNUC__ |
|
|
|
#define likely(x) __builtin_expect(!!(x), 1) |
|
|
|
#define unlikely(x) __builtin_expect(!!(x), 0) |
|
|
|
#else |
|
|
|
#define likely(x) (!!(x)) |
|
|
|
#define unlikely(x) (!!(x)) |
|
|
|
#endif |
|
|
|
|
|
|
|
struct label { |
|
|
|
int active; |
|
|
|
int dest; |
|
|
@ -1071,35 +1079,41 @@ int ink_can_run(struct context* pContext) { |
|
|
|
} |
|
|
|
|
|
|
|
int ink_step_everyone(struct context* pContext) { |
|
|
|
int out; |
|
|
|
pContext->routine_current = -1; |
|
|
|
for(;;) { |
|
|
|
/* Increment to next runnable routine */ |
|
|
|
do{ |
|
|
|
++(pContext->routine_current); |
|
|
|
} while( |
|
|
|
pContext->routine_current < pContext->routines_top |
|
|
|
&& pContext->routines[pContext->routine_current].panic != 0 |
|
|
|
&& pContext->routines[pContext->routine_current].parse_error.is_set |
|
|
|
&& pContext->routines[pContext->routine_current].runtime_error.is_set |
|
|
|
); |
|
|
|
/* Exit condition */ |
|
|
|
if(pContext->routine_current >= pContext->routines_top) break; |
|
|
|
|
|
|
|
/* Kill? */ |
|
|
|
if(pContext->routines[pContext->routine_current].panic == INK_ROUTINE_SUCCESS) { |
|
|
|
ink_kill_routine(pContext, pContext->routine_current); |
|
|
|
} |
|
|
|
|
|
|
|
/* Step! */ |
|
|
|
out = ink_step(pContext); |
|
|
|
if(out == 0) { |
|
|
|
pContext->routines[pContext->routine_current].panic = INK_ROUTINE_SUCCESS; |
|
|
|
} else if(out < 0) { |
|
|
|
pContext->routines[pContext->routine_current].panic = out; |
|
|
|
} |
|
|
|
} |
|
|
|
return 0; |
|
|
|
int idx; |
|
|
|
int out; |
|
|
|
pContext->routine_current = -1; |
|
|
|
for(;;) { |
|
|
|
top_label: |
|
|
|
/* Increment to next runnable routine */ |
|
|
|
do{ |
|
|
|
++(pContext->routine_current); |
|
|
|
} while( |
|
|
|
pContext->routine_current < pContext->routines_top |
|
|
|
&& pContext->routines[pContext->routine_current].panic != 0 |
|
|
|
&& pContext->routines[pContext->routine_current].parse_error.is_set |
|
|
|
&& pContext->routines[pContext->routine_current].runtime_error.is_set |
|
|
|
); |
|
|
|
/* Exit condition */ |
|
|
|
if(pContext->routine_current >= pContext->routines_top) break; |
|
|
|
|
|
|
|
/* Kill? */ |
|
|
|
if(pContext->routines[pContext->routine_current].panic == INK_ROUTINE_SUCCESS) { |
|
|
|
ink_kill_routine(pContext, pContext->routine_current); |
|
|
|
} |
|
|
|
|
|
|
|
/* Step! */ |
|
|
|
for(idx = 0; idx < INK_STEP_BATCH_COUNT; ++idx) { |
|
|
|
out = ink_step(pContext); |
|
|
|
if (unlikely(out == 0)) { |
|
|
|
pContext->routines[pContext->routine_current].panic = INK_ROUTINE_SUCCESS; |
|
|
|
goto top_label; |
|
|
|
} else if (unlikely(out < 0)) { |
|
|
|
pContext->routines[pContext->routine_current].panic = out; |
|
|
|
goto top_label; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
int ink_new_type( |
|
|
|