static int GREENLET_NOINLINE(slp_save_state)(char* stackref) { /* must free all the C stack up to target_stop */ char* target_stop = ts_target->stack_stop; greenlet* owner = ts_current; assert(owner->stack_saved == 0); if (owner->stack_start == NULL) owner = owner->stack_prev; /* not saved if dying */ else owner->stack_start = stackref; while (owner->stack_stop < target_stop) { /* ts_current is entierely within the area to free */ if (g_save(owner, owner->stack_stop)) return -1; /* XXX */ owner = owner->stack_prev; } if (owner != ts_target) { if (g_save(owner, target_stop)) return -1; /* XXX */ } return 0; }
/* Save more of the C stack away, up to 'target_stop'. */ static void g_clear_stack(struct stacklet_s *g_target, struct stacklet_thread_s *thrd) { struct stacklet_s *current = thrd->g_stack_chain_head; char *target_stop = g_target->stack_stop; check_valid(g_target); /* save and unlink stacklets that are completely within the area to clear. */ while (current != NULL && current->stack_stop <= target_stop) { struct stacklet_s *prev = current->stack_prev; check_valid(current); current->stack_prev = NULL; if (current != g_target) { /* don't bother saving away g_target, because it would be immediately restored */ g_save(current, current->stack_stop #ifdef DEBUG_DUMP , 1 #endif ); } current = prev; } /* save a partial stack */ if (current != NULL && current->stack_start < target_stop) g_save(current, target_stop #ifdef DEBUG_DUMP , 1 #endif ); thrd->g_stack_chain_head = current; }
void g_read(char name[]) { const identifier* tp = getReadTableItem(name); if (tp == null) { error(49, lineNumber); //error : identifier undefined. return; } if (tp->datat == inttype) { g_add("$0", 5, "$v0"); g_gen("syscall", "", "", ""); g_save(name, "$v0"); } else if (tp->datat == chartype) { g_add("$0", 12, "$v0"); g_gen("syscall", "", "", ""); g_save(name, "$v0"); } }
/* This saves the current state in a new stacklet that gets stored in * 'g_source', but returns NULL, to not do any restoring yet. */ static void *g_initial_save_state(void *old_stack_pointer, void *rawthrd) { struct stacklet_thread_s *thrd = (struct stacklet_thread_s *)rawthrd; if (g_allocate_source_stacklet(old_stack_pointer, thrd) == 0) g_save(thrd->g_source, thrd->g_current_stack_marker #ifdef DEBUG_DUMP , 0 #endif ); return NULL; }
void g_save(char name[]) { g_save(name, "$t9"); }
static void F_RestoreRegVars (Function* F) /* Restore the register variables for the local function if there are any. */ { const SymEntry* Sym; /* If we don't have register variables in this function, bail out early */ if (F->RegOffs == RegisterSpace) { return; } /* Save the accumulator if needed */ if (!F_HasVoidReturn (F)) { g_save (CF_CHAR | CF_FORCECHAR); } /* Get the first symbol from the function symbol table */ Sym = F->FuncEntry->V.F.Func->SymTab->SymHead; /* Walk through all symbols checking for register variables */ while (Sym) { if (SymIsRegVar (Sym)) { /* Check for more than one variable */ int Offs = Sym->V.R.SaveOffs; unsigned Bytes = CheckedSizeOf (Sym->Type); while (1) { /* Find next register variable */ const SymEntry* NextSym = Sym->NextSym; while (NextSym && !SymIsRegVar (NextSym)) { NextSym = NextSym->NextSym; } /* If we have a next one, compare the stack offsets */ if (NextSym) { /* We have a following register variable. Get the size */ int Size = CheckedSizeOf (NextSym->Type); /* Adjacent variable? */ if (NextSym->V.R.SaveOffs + Size != Offs) { /* No */ break; } /* Adjacent variable */ Bytes += Size; Offs -= Size; Sym = NextSym; } else { break; } } /* Restore the memory range */ g_restore_regvars (Offs, Sym->V.R.RegOffs, Bytes); } /* Check next symbol */ Sym = Sym->NextSym; } /* Restore the accumulator if needed */ if (!F_HasVoidReturn (F)) { g_restore (CF_CHAR | CF_FORCECHAR); } }
void prop_kv_config::save(stream_writer * writer, abort_callback & abort) const { g_save(m_map, writer, abort); }