txlyre 1 dzień temu
rodzic
commit
d03ba0edd0
2 zmienionych plików z 29 dodań i 3 usunięć
  1. 27 3
      qirt.c
  2. 2 0
      qirt.h

+ 27 - 3
qirt.c

@@ -559,7 +559,24 @@ void qi_add_defer(qi_state_t *state, qi_ssize_t index, qi_defer_t defer) {
   if (qi_list_empty(state->scopes))
     return;
 
-  qi_scope_t *scope = qi_list_last(state->scopes);
+  qi_scope_t *scope = NULL;
+
+  for (ssize_t i = state->scopes->length - 1; i >= 0; i--) {
+    qi_scope_t *tmp = qi_list_index(state->scopes, i);
+
+    if (i == 0 || tmp->is_sticky) {
+      scope = tmp;
+
+      break;
+    } else if (tmp->is_barrier)
+      break;
+
+    scope = tmp;
+  }
+
+  if (!scope)
+    scope = qi_list_last(state->scopes);
+
   qi_list_insert(scope->defers, index, (void *)defer);
 }
 
@@ -582,12 +599,19 @@ void qi_new_scope(qi_state_t *state) {
   scope->defers = qi_list_make();
 
   scope->is_barrier = false;
+  scope->is_sticky = false;
 
   scope->mutex = qi_mutex_create();
 
   qi_list_push(state->scopes, scope);
 }
 
+void qi_new_sticky_scope(qi_state_t *state) {
+  qi_new_scope(state);
+
+  ((qi_scope_t *)qi_list_last(state->scopes))->is_sticky = true;
+}
+
 static void qi_scope_run_defers(qi_state_t *state, qi_scope_t *scope) {
   qi_mutex_lock(scope->mutex);
 
@@ -2141,7 +2165,7 @@ static qi_value_t *_qi_call(qi_state_t *state, qi_value_t *value,
     qi_push_trace(state, value, debug_data);
 
   if (!value->value.function.is_builtin) {
-    qi_new_scope(state);
+    qi_new_sticky_scope(state);
 
     qi_decl_const(state, "it", value);
     qi_decl(state, "arguments",
@@ -4062,7 +4086,7 @@ static void qi_state_setup(qi_state_t *state) {
 
   state->traps = qi_list_make();
   state->scopes = qi_list_make();
-  qi_new_scope(state);
+  qi_new_sticky_scope(state);
 
   if (__debug_enabled)
     state->calltrace = qi_list_make();

+ 2 - 0
qirt.h

@@ -188,6 +188,7 @@ struct _qi_scope_t {
   qi_list_t *defers;
 
   qi_bool is_barrier;
+  qi_bool is_sticky;
 
   void *mutex;
 };
@@ -367,6 +368,7 @@ qi_table_t *qi_table_copy(qi_table_t *table);
 void qi_add_defer(qi_state_t *state, qi_ssize_t index, qi_defer_t defer);
 qi_defer_t qi_pop_defer(qi_state_t *state, qi_ssize_t index);
 void qi_new_scope(qi_state_t *state);
+void qi_new_sticky_scope(qi_state_t *state);
 qi_bool qi_old_scope(qi_state_t *state);
 qi_value_t *qi_make_value(qi_type_t type);
 #define qi_make_boolean(state, x) ((x) ? (state)->_true : (state)->_false)