about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--026call.cc2
-rw-r--r--071scheduler.cc53
2 files changed, 54 insertions, 1 deletions
diff --git a/026call.cc b/026call.cc
index dd240936..dd3b5968 100644
--- a/026call.cc
+++ b/026call.cc
@@ -161,7 +161,7 @@ while (current_step_index() >= SIZE(Current_routine->steps())) {
     assert(Trace_stream->callstack_depth >= 0);
   }
   Current_routine->calls.pop_front();
-  if (Current_routine->calls.empty()) return;
+  if (Current_routine->calls.empty()) goto stop_running_current_routine;
   // Complete Call Fallthrough
   // todo: fail if no products returned
   ++current_step_index();
diff --git a/071scheduler.cc b/071scheduler.cc
index edf05c26..d70dff88 100644
--- a/071scheduler.cc
+++ b/071scheduler.cc
@@ -532,6 +532,43 @@ case LIMIT_TIME: {
   break;
 }
 
+
+:(before "End routine Fields")
+int ninstrs;
+:(before "End routine Constructor")
+ninstrs = 0;
+:(after "stop_running_current_routine:")
+Current_routine->ninstrs = ninstrs;
+:(before "End Primitive Recipe Declarations")
+NUMBER_OF_INSTRUCTIONS,
+:(before "End Primitive Recipe Numbers")
+put(Recipe_ordinal, "number-of-instructions", NUMBER_OF_INSTRUCTIONS);
+:(before "End Primitive Recipe Checks")
+case NUMBER_OF_INSTRUCTIONS: {
+  if (SIZE(inst.ingredients) != 1) {
+    raise << maybe(get(Recipe, r).name) << "'number-of-instructions' requires exactly one ingredient, but got '" << to_original_string(inst) << "'\n" << end();
+    break;
+  }
+  if (!is_mu_number(inst.ingredients.at(0))) {
+    raise << maybe(get(Recipe, r).name) << "first ingredient of 'number-of-instructions' should be a routine id generated by 'start-running', but got '" << inst.ingredients.at(0).original_string << "'\n" << end();
+    break;
+  }
+  break;
+}
+:(before "End Primitive Recipe Implementations")
+case NUMBER_OF_INSTRUCTIONS: {
+  int id = ingredients.at(0).at(0);
+  int result = -1;
+  for (int i = 0; i < SIZE(Routines); ++i) {
+    if (Routines.at(i)->id == id) {
+      result = Routines.at(i)->ninstrs;
+      break;
+    }
+  }
+  products.resize(1);
+  products.at(0).push_back(result);
+  break;
+}
 //:: make sure that each routine gets a different alloc to start
 
 :(scenario new_concurrent)
@@ -551,3 +588,19 @@ def f2 [
   4:number/raw <- copy 1
 ]
 +mem: storing 0 in location 3
+
+:(scenario number_of_instructions)
+def f1 [
+  1:number/child-id <- start-running f2
+  {
+    loop-unless 3:number/raw
+  }
+  # Number of instructions returns visible number plus one due to the implicit reply added by
+  # Transform.push_back in the recipe header layer.
+  4:number <- number-of-instructions 1:number
+]
+def f2 [
+  2:address:number/raw <- new number:type
+  3:number <- copy 1
+]
++mem: storing 3 in location 4