Esempio n. 1
0
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;
}
Esempio n. 2
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");
    }
}
Esempio n. 4
0
/* 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");
}
Esempio n. 6
0
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);
    }
}
Esempio n. 7
0
void prop_kv_config::save(stream_writer * writer, abort_callback & abort) const
{
	g_save(m_map, writer, abort);
}