Esempio n. 1
0
*/  REBSER *Make_Frame(REBINT len)
/*
**      Create a frame of a given size, allocating space for both
**		words and values. Normally used for global frames.
**
**		selfless means do not set SELF word
**
***********************************************************************/
{
	REBSER *frame;
	REBSER *words;
	REBVAL *value;

	//DISABLE_GC;
	words = Make_Block(len + 1); // size + room for SELF
	BARE_SERIES(words);
	frame = Make_Block(len + 1);
	//ENABLE_GC;
	// Note: cannot use Append_Frame for first word.
	value = Append_Value(frame);
	SET_FRAME(value, 0, words);
	value = Append_Value(words);
	Init_Frame_Word(value, SYM_SELF); // may get unset by selfless frames

	return frame;
}
Esempio n. 2
0
SEXP SmokeObject::fieldEnv() const {
  if (!_fieldEnv) {
    _fieldEnv = allocSExp(ENVSXP);
    SET_ENCLOS(_fieldEnv, R_EmptyEnv);
    SET_FRAME(_fieldEnv, R_NilValue);
    R_PreserveObject(_fieldEnv);
  }
  return _fieldEnv;
}
Esempio n. 3
0
*/	void Do_Closure(REBVAL *func)
/*
**		Do a closure by cloning its body and binding it to
**		a new frame of words/values.
**
**		This could be made faster by pre-binding the body,
**		then using Rebind_Block to rebind the words in it.
**
***********************************************************************/
{
	REBSER *body;
	REBSER *frame;
	REBVAL *result;
	REBVAL *ds;

	Eval_Functions++;
	//DISABLE_GC;

	// Clone the body of the function to allow rebinding to it:
	body = Clone_Block(VAL_FUNC_BODY(func));

	// Copy stack frame args as the closure object (one extra at head)
	frame = Copy_Values(BLK_SKIP(DS_Series, DS_ARG_BASE), SERIES_TAIL(VAL_FUNC_ARGS(func)));
	SET_FRAME(BLK_HEAD(frame), 0, VAL_FUNC_ARGS(func));

	// Rebind the body to the new context (deeply):
	//Rebind_Block(VAL_FUNC_ARGS(func), frame, body);
	Bind_Block(frame, BLK_HEAD(body), BIND_DEEP); // | BIND_NO_SELF);

	ds = DS_RETURN;
	SET_OBJECT(ds, body); // keep it GC safe
	result = Do_Blk(body, 0); // GC-OK - also, result returned on DS stack
	ds = DS_RETURN;

	if (IS_ERROR(result) && IS_RETURN(result)) {
		// Value below is kept safe from GC because no-allocation is
		// done between point of SET_THROW and here.
		if (VAL_ERR_VALUE(result))
			*ds = *VAL_ERR_VALUE(result);
		else
			SET_UNSET(ds);
	}
	else *ds = *result; // Set return value (atomic)
}
Esempio n. 4
0
*/  REBSER *Create_Frame(REBSER *words, REBSER *spec)
/*
**      Create a new frame from a word list.
**      The values of the frame are initialized to NONE.
**
***********************************************************************/
{
	REBINT len = SERIES_TAIL(words);
	REBSER *frame = Make_Block(len);
	REBVAL *value = BLK_HEAD(frame);

	SET_FRAME(value, spec, words);

	SERIES_TAIL(frame) = len;
	for (value++, len--; len > 0; len--, value++) SET_NONE(value); // skip first value (self)
	SET_END(value);

	return frame;
}
Esempio n. 5
0
*/  REBSER *Make_Frame(REBINT len, REBOOL has_self)
/*
**      Create a frame of a given size, allocating space for both
**		words and values. Normally used for global frames.
**
***********************************************************************/
{
	REBSER *frame;
	REBSER *words;
	REBVAL *value;

	words = Make_Array(len + 1); // size + room for SELF
	frame = Make_Array(len + 1);

	// Note: cannot use Append_Frame for first word.
	value = Alloc_Tail_Array(frame);
	SET_FRAME(value, 0, words);
	value = Alloc_Tail_Array(words);
	Val_Init_Word_Typed(
		value, REB_WORD, has_self ? SYM_SELF : SYM_NOT_USED, ALL_64
	);

	return frame;
}
Esempio n. 6
0
SEXP attribute_hidden matchPositionalArgsCreateEnv(SEXP formals, SEXP *supplied, int nsupplied, SEXP call, SEXP rho, SEXP* outActuals)
{
    SEXP *s;
    SEXP f, a;    
    SEXP actuals = R_NilValue;
    
    SEXP newrho = PROTECT(NewEnvironmentNR(rho));    
    
    SEXP *endSupplied = supplied + nsupplied;
    for (f = formals, s = supplied, a = actuals ; f != R_NilValue ; f = CDR(f), s++) {
    
        if (TAG(f) == R_DotsSymbol) {
            /* pack all remaining arguments into ... */
            
            SEXP *rs = endSupplied - 1;
            SEXP dotsContent = R_NilValue;
            for(; rs >= s; rs--) {
                dotsContent = CONS(*rs, dotsContent); /* FIXME: enabling refcnt? */
            }
            SEXP dots = CONS_NR(dotsContent, R_NilValue);
            SET_TAG(dots, R_DotsSymbol);
            if (dotsContent != R_NilValue) {
                SET_TYPEOF(dotsContent, DOTSXP);
            } else {
                SET_MISSING(dots, 1);
            }
            if (a == R_NilValue) {
                PROTECT(actuals = dots);
            } else {
                SETCDR(a, dots);
                ENABLE_REFCNT(a); /* dots are part of a protected list */
            }
            a = dots;
            f = CDR(f);
            s = endSupplied;
            /* falls through into noMoreSupplied branch below */
        }
            
        if (s == endSupplied) {
            /* possibly fewer supplied arguments than formals */
            SEXP ds;
            for(; f != R_NilValue ; f = CDR(f), a = ds) { 
                ds = CONS_NR(R_MissingArg, R_NilValue);
                SET_TAG(ds, TAG(f));
                if (a == R_NilValue) {
                    PROTECT(actuals = ds);
                } else {
                    SETCDR(a, ds);
                    ENABLE_REFCNT(a); /* ds is part of a protected list */
                }
                SEXP fdefault = CAR(f);
                if (fdefault != R_MissingArg) {
                    SET_MISSING(ds, 2);
                    SETCAR(ds, mkPROMISEorConst(fdefault, newrho));
                } else {
                    SET_MISSING(ds, 1);
                }
            }
            break;
        }
        
        /* normal case, the next supplied arg is available */
        
        SEXP arg = CONS_NR(*s, R_NilValue);
        SET_TAG(arg, TAG(f));

        if (a == R_NilValue) {
            PROTECT(actuals = arg);
        } else {
            SETCDR(a, arg);
            ENABLE_REFCNT(a);
        }
        a = arg;
    }

    if (s < endSupplied) {
        /* some arguments are not used */

        SEXP *rs = endSupplied - 1;
        SEXP unusedForError = R_NilValue;
        for(; rs >= s; rs--) {
            SEXP rsValue = *rs;
            if (TYPEOF(rsValue) == PROMSXP) {
                rsValue = PREXPR(rsValue);
            }
            unusedForError = CONS(rsValue, unusedForError);
        }
        PROTECT(unusedForError); /* needed? */
        errorcall(call /* R_GlobalContext->call */,
	   ngettext("unused argument %s",
	     "unused arguments %s",
	     (unsigned long) length(unusedForError)),
	     CHAR(STRING_ELT(deparse1line(unusedForError, 0), 0)) + 4);
                  /* '+ 4' is to remove 'list' from 'list(badTag1,...)' */
        UNPROTECT(1);
    }
        
    if (a != R_NilValue) {
        ENABLE_REFCNT(a);
    }
    
    SET_FRAME(newrho, actuals);
    ENABLE_REFCNT(newrho);
    UNPROTECT(1);  /* newrho */
    if (actuals != R_NilValue) {
        UNPROTECT(1); /* actuals */
    }    
    *outActuals = actuals;
    
    return(newrho);
}
Esempio n. 7
0
SEXP attribute_hidden matchUnnamedArgsCreateEnv(SEXP formals, SEXP supplied, SEXP call, SEXP rho, SEXP* outActuals)
{
    SEXP f, s;    
    SEXP actuals = PROTECT(supplied);
    SEXP newrho = PROTECT(NewEnvironmentNR(rho));
    SEXP prevS = R_NilValue;
    
    for (f = formals, s = supplied ; f != R_NilValue ; f = CDR(f), prevS = s, s = CDR(s)) {
        
        if (TAG(f) == R_DotsSymbol) {
            /* pack all arguments into ... */
            
            SEXP dots = CONS_NR(R_MissingArg, R_NilValue);
            SET_TAG(dots, R_DotsSymbol);
            if (prevS == R_NilValue) {
                UNPROTECT(1); /* old actuals */
                PROTECT(actuals = dots);
            } else {
                SETCDR(prevS, dots);
                ENABLE_REFCNT(prevS); /* dots are part of a protected list */
            }
            if (s != R_NilValue) {
                SET_TYPEOF(s, DOTSXP);
                SETCAR(dots, s);
                s = R_NilValue;
            } else {
                SET_MISSING(dots, 1);
            }
            prevS = dots;
            f = CDR(f);
            /* falls through into s == R_NilValue case */
        }
            
        if (s == R_NilValue) {
            /* fewer supplied arguments than formals */
            SEXP ds;
            for(; f != R_NilValue ; f = CDR(f), prevS = ds) { 
                ds = CONS_NR(R_MissingArg, R_NilValue);
                SET_TAG(ds, TAG(f));
                if (prevS == R_NilValue) {
                    UNPROTECT(1); /* old actuals */
                    PROTECT(actuals = ds);
                } else {
                    SETCDR(prevS, ds);
                    ENABLE_REFCNT(prevS); /* ds is part of a protected list */
                }
                SEXP fdefault = CAR(f);
                if (fdefault != R_MissingArg) {
                    SET_MISSING(ds, 2);
                    SETCAR(ds, mkPROMISEorConst(fdefault, newrho));
                } else {
                    SET_MISSING(ds, 1);
                }
            }
            break;
        }
        
        /* normal case, the next supplied arg is available */
        
        SET_TAG(s, TAG(f));
        if (CAR(s) == R_MissingArg) {
            SEXP fdefault = CAR(f);
            if (fdefault != R_MissingArg) {
                SET_MISSING(s, 2);
                SETCAR(s, mkPROMISEorConst(fdefault, newrho));
            } else {
                SET_MISSING(s, 1);
            }
        }
        if (prevS != R_NilValue) {
            ENABLE_REFCNT(prevS);
        }
    }

    if (s != R_NilValue) {
        /* some arguments are not used */
        SEXP unusedForError = PROTECT(s);
        SETCDR(prevS, R_NilValue); /* make sure they're not in the new environment */
            
        /* show bad arguments in call without evaluating them */
        for (; s != R_NilValue; s = CDR(s)) {
            SEXP carS = CAR(s);
            if (TYPEOF(carS) == PROMSXP) {
                SETCAR(s, PREXPR(carS));
            }
        }
        errorcall(call /* R_GlobalContext->call */,
	   ngettext("unused argument %s",
	     "unused arguments %s",
	     (unsigned long) length(unusedForError)),
	     CHAR(STRING_ELT(deparse1line(unusedForError, 0), 0)) + 4);
                  /* '+ 4' is to remove 'list' from 'list(badTag1,...)' */
        UNPROTECT(1);
    }
        
    if (prevS != R_NilValue) {
        ENABLE_REFCNT(prevS);
    }
    
    SET_FRAME(newrho, actuals);
    ENABLE_REFCNT(newrho);
    UNPROTECT(2); /* newrho, actuals */
    
    *outActuals = actuals;
    return(newrho);
}