The R Project SVN R

Rev

Rev 87901 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 r 1
/*
1016 maechler 2
 *  R : A Computer Language for Statistical Data Analysis
2 r 3
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
87740 ripley 4
 *  Copyright (C) 1998-2025   The R Core Team.
2 r 5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
42307 ripley 17
 *  along with this program; if not, a copy is available at
68947 ripley 18
 *  https://www.R-project.org/Licenses/
1839 ihaka 19
 *
20
 *
21
 *  Contexts:
22
 *
23
 *  A linked-list of execution contexts is kept so that control-flow
24
 *  constructs like "next", "break" and "return" will work.  It is also
25
 *  used for error returns to top-level.
26
 *
27
 *	context[k] -> context[k-1] -> ... -> context[0]
28
 *	^				     ^
29
 *	R_GlobalContext			     R_ToplevelContext
30
 *
31
 *  Contexts are allocated on the stack as the evaluator invokes itself
32
 *  recursively.  The memory is reclaimed naturally on return through
33
 *  the recursions (the R_GlobalContext pointer needs adjustment).
34
 *
37654 ripley 35
 *  A context contains the following information (and more):
1839 ihaka 36
 *
37
 *	nextcontext	the next level context
38
 *	cjmpbuf		longjump information for non-local return
39
 *	cstacktop	the current level of the pointer protection stack
40
 *	callflag	the context "type"
45446 ripley 41
 *	call		the call (name of function, or expression to
37654 ripley 42
 *			get the function) that effected this
43
 *			context if a closure, otherwise often NULL.
44
 *	callfun		the function, if this was a closure.
1839 ihaka 45
 *	cloenv		for closures, the environment of the closure.
46
 *	sysparent	the environment the closure was called from
47
 *	conexit		code for on.exit calls, to be executed in cloenv
48
 *			at exit from the closure (normal or abnormal).
49
 *	cend		a pointer to function which executes if there is
50
 *			non-local return (i.e. an error)
20170 duncan 51
 *	cenddata	a void pointer to data for cend to use
14480 luke 52
 *	vmax		the current setting of the R_alloc stack
48623 murdoch 53
 *	srcref		the srcref at the time of the call
1839 ihaka 54
 *
55
 *  Context types can be one of:
56
 *
57
 *	CTXT_TOPLEVEL	The toplevel context
58
 *	CTXT_BREAK	target for "break"
59
 *	CTXT_NEXT	target for "next"
60
 *	CTXT_LOOP	target for either "break" or "next"
61
 *	CTXT_RETURN	target for "return" (i.e. a closure)
6191 maechler 62
 *	CTXT_BROWSER	target for "return" to exit from browser
1839 ihaka 63
 *	CTXT_CCODE	other functions that need clean up if an error occurs
6191 maechler 64
 *	CTXT_RESTART	a function call to restart was made inside the
65
 *			closure.
1839 ihaka 66
 *
6191 maechler 67
 *	Code (such as the sys.xxx) that looks for CTXT_RETURN must also
68
 *	look for a CTXT_RESTART and CTXT_GENERIC.
69
 *	The mechanism used by restart is to change
70
 *	the context type; error/errorcall then looks for a RESTART and does
71
 *	a long jump there if it finds one.
6008 rgentlem 72
 *
1839 ihaka 73
 *  A context is created with a call to
74
 *
75
 *	void begincontext(RCNTXT *cptr, int flags,
6191 maechler 76
 *			  SEXP syscall, SEXP env, SEXP
23486 luke 77
 *			  sysp, SEXP promargs, SEXP callfun)
1839 ihaka 78
 *
79
 *  which sets up the context pointed to by cptr in the appropriate way.
80
 *  When the context goes "out-of-scope" a call to
81
 *
82
 *	void endcontext(RCNTXT *cptr)
83
 *
84
 *  restores the previous context (i.e. it adjusts the R_GlobalContext
85
 *  pointer).
86
 *
87
 *  The non-local jump to a given context takes place in a call to
88
 *
89
 *	void findcontext(int mask, SEXP env, SEXP val)
90
 *
84246 maechler 91
 *  This causes "val" to be stuffed into a globally accessible place and
1839 ihaka 92
 *  then a search to take place back through the context list for an
93
 *  appropriate context.  The kind of context sort is determined by the
94
 *  value of "mask".  The value of mask should be the logical OR of all
95
 *  the context types desired.
96
 *
97
 *  The value of "mask" is returned as the value of the setjump call at
98
 *  the level longjumped to.  This is used to distinguish between break
99
 *  and next actions.
100
 *
101
 *  Contexts can be used as a wrapper around functions that create windows
102
 *  or open files. These can then be shut/closed gracefully if an error
103
 *  occurs.
2 r 104
 */
105
 
5187 hornik 106
#ifdef HAVE_CONFIG_H
7701 hornik 107
#include <config.h>
5187 hornik 108
#endif
109
 
57538 ripley 110
#define R_USE_SIGNALS 1
111
#include <Defn.h>
60667 ripley 112
#include <Internal.h>
2 r 113
 
14478 luke 114
/* R_run_onexits - runs the conexit/cend code for all contexts from
115
   R_GlobalContext down to but not including the argument context.
116
   This routine does not stop at a CTXT_TOPLEVEL--the code that
117
   determines the argument is responsible for making sure
118
   CTXT_TOPLEVEL's are not crossed unless appropriate. */
119
 
83446 ripley 120
attribute_hidden void R_run_onexits(RCNTXT *cptr)
1895 ihaka 121
{
14443 luke 122
    RCNTXT *c;
123
 
124
    for (c = R_GlobalContext; c != cptr; c = c->nextcontext) {
68923 ripley 125
	// a user embedding R incorrectly triggered this (PR#15420)
14478 luke 126
	if (c == NULL)
63535 ripley 127
	    error("bad target context--should NEVER happen if R was called correctly");
14478 luke 128
	if (c->cend != NULL) {
14561 luke 129
	    void (*cend)(void *) = c->cend;
14443 luke 130
	    c->cend = NULL; /* prevent recursion */
25523 luke 131
	    R_HandlerStack = c->handlerstack;
132
	    R_RestartStack = c->restartstack;
14561 luke 133
	    cend(c->cenddata);
14443 luke 134
	}
135
	if (c->cloenv != R_NilValue && c->conexit != R_NilValue) {
136
	    SEXP s = c->conexit;
66393 murdoch 137
	    RCNTXT* savecontext = R_ExitContext;
138
	    R_ExitContext = c;
14443 luke 139
	    c->conexit = R_NilValue; /* prevent recursion */
73111 kalibera 140
	    /* we are in intermediate jump, so returnValue is undefined */
86113 luke 141
	    c->returnValue = SEXP_TO_STACKVAL(NULL);
25523 luke 142
	    R_HandlerStack = c->handlerstack;
143
	    R_RestartStack = c->restartstack;
14443 luke 144
	    PROTECT(s);
42875 luke 145
	    /* Since these are run before any jumps rather than after
146
	       jumping to the context where the exit handler was set
147
	       we need to make sure there is enough room on the
148
	       evaluation stack in case the jump is from handling a
149
	       stack overflow. To be safe it is good to also call
150
	       R_CheckStack. LT */
151
	    R_Expressions = R_Expressions_keep + 500;
152
	    R_CheckStack();
73181 luke 153
	    for (; s != R_NilValue; s = CDR(s)) {
154
		c->conexit = CDR(s);
155
		eval(CAR(s), c->cloenv);
156
	    }
14443 luke 157
	    UNPROTECT(1);
66393 murdoch 158
	    R_ExitContext = savecontext;
14443 luke 159
	}
66393 murdoch 160
	if (R_ExitContext == c)
161
	    R_ExitContext = NULL; /* Not necessary?  Better safe than sorry. */
14443 luke 162
    }
14478 luke 163
}
164
 
165
 
14479 luke 166
/* R_restore_globals - restore global variables from a target context
167
   before a LONGJMP.  The target context itself is not restored here
70324 luke 168
   since this is done in R_jumpctxt below. */
14479 luke 169
 
70324 luke 170
static void R_restore_globals(RCNTXT *cptr)
14479 luke 171
{
172
    R_PPStackTop = cptr->cstacktop;
68755 luke 173
    R_GCEnabled = cptr->gcenabled;
71390 luke 174
    R_BCIntActive = cptr->bcintactive;
175
    R_BCpc = cptr->bcpc;
176
    R_BCbody = cptr->bcbody;
86189 luke 177
    R_BCFrame = cptr->bcframe;
14479 luke 178
    R_EvalDepth = cptr->evaldepth;
14480 luke 179
    vmaxset(cptr->vmax);
87816 ripley 180
    R_interrupts_suspended = (Rboolean) cptr->intsusp;
25523 luke 181
    R_HandlerStack = cptr->handlerstack;
182
    R_RestartStack = cptr->restartstack;
41992 luke 183
    while (R_PendingPromises != cptr->prstack) {
42875 luke 184
	/* The value 2 installed in PRSEEN 2 allows forcePromise in
41992 luke 185
	   eval.c to signal a warning when asked to evaluate a promise
186
	   whose evaluation has been interrupted by a jump. */
187
	SET_PRSEEN(R_PendingPromises->promise, 2);
188
	R_PendingPromises = R_PendingPromises->next;
189
    }
42875 luke 190
    /* Need to reset R_Expressions in case we are jumping after
191
       handling a stack overflow. */
192
    R_Expressions = R_Expressions_keep;
26026 luke 193
    R_BCNodeStackTop = cptr->nodestack;
48623 murdoch 194
    R_Srcref = cptr->srcref;
77275 luke 195
    R_BCProtReset(cptr->bcprottop);
14479 luke 196
}
197
 
70325 luke 198
static RCNTXT *first_jump_target(RCNTXT *cptr, int mask)
199
{
200
    RCNTXT *c;
201
 
202
    for (c = R_GlobalContext; c && c != cptr; c = c->nextcontext) {
73866 luke 203
	if ((c->cloenv != R_NilValue && c->conexit != R_NilValue) ||
204
	    c->callflag == CTXT_UNWIND) {
70325 luke 205
	    c->jumptarget = cptr;
206
	    c->jumpmask = mask;
207
	    return c;
208
	}
209
    }
210
    return cptr;
211
}
212
 
70324 luke 213
/* R_jumpctxt - jump to the named context */
14479 luke 214
 
87740 ripley 215
NORET attribute_hidden void R_jumpctxt(RCNTXT * targetcptr, int mask, SEXP val)
14478 luke 216
{
40068 ripley 217
    Rboolean savevis = R_Visible;
70325 luke 218
    RCNTXT *cptr;
14478 luke 219
 
70325 luke 220
    /* find the target for the first jump -- either an intermediate
221
       context with an on.exit action to run or the final target if
222
       there are no intermediate on.exit actions */
223
    cptr = first_jump_target(targetcptr, mask);
224
 
225
    /* run cend code for all contexts down to but not including
226
       the first jump target */
14478 luke 227
    R_run_onexits(cptr);
14443 luke 228
    R_Visible = savevis;
229
 
1895 ihaka 230
    R_ReturnedValue = val;
70324 luke 231
    R_GlobalContext = cptr;
19318 luke 232
    R_restore_globals(R_GlobalContext);
233
 
70324 luke 234
    /* if we are in the process of handling a C stack overflow we need
235
       to restore the C stack limit before the jump */
236
    if (R_OldCStackLimit != 0) {
237
	R_CStackLimit = R_OldCStackLimit;
238
	R_OldCStackLimit = 0;
239
    }
240
 
87015 luke 241
    if (mask == 0)
242
	mask = 1; // make sure the return value for SETJMP is not zero
243
 
86210 luke 244
    LONGJMP(cptr->cjmpbuf, mask);
1895 ihaka 245
}
246
 
247
 
2 r 248
/* begincontext - begin an execution context */
1839 ihaka 249
 
38662 ripley 250
/* begincontext and endcontext are used in dataentry.c and modules */
1839 ihaka 251
void begincontext(RCNTXT * cptr, int flags,
23463 luke 252
		  SEXP syscall, SEXP env, SEXP sysp,
253
		  SEXP promargs, SEXP callfun)
2 r 254
{
1839 ihaka 255
    cptr->cstacktop = R_PPStackTop;
68755 luke 256
    cptr->gcenabled = R_GCEnabled;
86233 luke 257
    cptr->relpc = R_BCRelPC(R_BCbody, R_BCpc);
71390 luke 258
    cptr->bcpc = R_BCpc;
259
    cptr->bcbody = R_BCbody;
86189 luke 260
    cptr->bcframe = R_BCFrame;
71390 luke 261
    cptr->bcintactive = R_BCIntActive;
8230 rgentlem 262
    cptr->evaldepth = R_EvalDepth;
1839 ihaka 263
    cptr->callflag = flags;
264
    cptr->call = syscall;
265
    cptr->cloenv = env;
266
    cptr->sysparent = sysp;
267
    cptr->conexit = R_NilValue;
268
    cptr->cend = NULL;
269
    cptr->promargs = promargs;
23463 luke 270
    cptr->callfun = callfun;
14480 luke 271
    cptr->vmax = vmaxget();
25200 luke 272
    cptr->intsusp = R_interrupts_suspended;
25523 luke 273
    cptr->handlerstack = R_HandlerStack;
274
    cptr->restartstack = R_RestartStack;
41992 luke 275
    cptr->prstack = R_PendingPromises;
26026 luke 276
    cptr->nodestack = R_BCNodeStackTop;
77275 luke 277
    cptr->bcprottop = R_BCProtTop;
68923 ripley 278
    cptr->srcref = R_Srcref;
63400 murdoch 279
    cptr->browserfinish = R_GlobalContext->browserfinish;
62867 luke 280
    cptr->nextcontext = R_GlobalContext;
86113 luke 281
    cptr->returnValue = SEXP_TO_STACKVAL(NULL);
70325 luke 282
    cptr->jumptarget = NULL;
283
    cptr->jumpmask = 0;
63400 murdoch 284
 
1839 ihaka 285
    R_GlobalContext = cptr;
2 r 286
}
287
 
1839 ihaka 288
 
2 r 289
/* endcontext - end an execution context */
1839 ihaka 290
 
2 r 291
void endcontext(RCNTXT * cptr)
292
{
79542 luke 293
    void R_FixupExitingHandlerResult(SEXP); /* defined in error.c */
294
    SEXP R_UnwindHandlerStack(SEXP); /* defined in error.c */
295
    R_HandlerStack = R_UnwindHandlerStack(cptr->handlerstack);
25523 luke 296
    R_RestartStack = cptr->restartstack;
73133 luke 297
    RCNTXT *jumptarget = cptr->jumptarget;
14878 luke 298
    if (cptr->cloenv != R_NilValue && cptr->conexit != R_NilValue ) {
15299 luke 299
	SEXP s = cptr->conexit;
40090 ripley 300
	Rboolean savevis = R_Visible;
66393 murdoch 301
	RCNTXT* savecontext = R_ExitContext;
73111 kalibera 302
	SEXP saveretval = R_ReturnedValue;
66393 murdoch 303
	R_ExitContext = cptr;
15299 luke 304
	cptr->conexit = R_NilValue; /* prevent recursion */
73133 luke 305
	cptr->jumptarget = NULL; /* in case on.exit expr calls return() */
73111 kalibera 306
	PROTECT(saveretval);
15299 luke 307
	PROTECT(s);
73853 luke 308
	R_FixupExitingHandlerResult(saveretval);
86113 luke 309
	SEXP cptr_retval =
310
	    cptr->returnValue.tag == 0 ? cptr->returnValue.u.sxpval : NULL;
311
	if (cptr_retval) // why is this needed???
312
	    INCREMENT_LINKS(cptr_retval);
73181 luke 313
	for (; s != R_NilValue; s = CDR(s)) {
314
	    cptr->conexit = CDR(s);
315
	    eval(CAR(s), cptr->cloenv);
316
	}
86113 luke 317
	if (cptr_retval) // why is this needed???
318
	    DECREMENT_LINKS(cptr_retval);
73111 kalibera 319
	R_ReturnedValue = saveretval;
320
	UNPROTECT(2);
66393 murdoch 321
	R_ExitContext = savecontext;
15299 luke 322
	R_Visible = savevis;
14878 luke 323
    }
66393 murdoch 324
    if (R_ExitContext == cptr)
68923 ripley 325
	R_ExitContext = NULL;
84246 maechler 326
    /* continue jumping if this was reached as an intermediate jump */
73133 luke 327
    if (jumptarget)
73111 kalibera 328
	/* cptr->returnValue is undefined */
73133 luke 329
	R_jumpctxt(jumptarget, cptr->jumpmask, R_ReturnedValue);
70325 luke 330
 
1839 ihaka 331
    R_GlobalContext = cptr->nextcontext;
2 r 332
}
333
 
1839 ihaka 334
 
2 r 335
/* findcontext - find the correct context */
1839 ihaka 336
 
87740 ripley 337
NORET attribute_hidden void findcontext(int mask, SEXP env, SEXP val)
2 r 338
{
1839 ihaka 339
    RCNTXT *cptr;
340
    cptr = R_GlobalContext;
341
    if (mask & CTXT_LOOP) {		/* break/next */
14633 luke 342
	for (cptr = R_GlobalContext;
343
	     cptr != NULL && cptr->callflag != CTXT_TOPLEVEL;
344
	     cptr = cptr->nextcontext)
13793 rgentlem 345
	    if (cptr->callflag & CTXT_LOOP && cptr->cloenv == env )
70324 luke 346
		R_jumpctxt(cptr, mask, val);
55024 murdoch 347
	error(_("no loop for break/next, jumping to top level"));
1839 ihaka 348
    }
349
    else {				/* return; or browser */
14633 luke 350
	for (cptr = R_GlobalContext;
351
	     cptr != NULL && cptr->callflag != CTXT_TOPLEVEL;
352
	     cptr = cptr->nextcontext)
4089 rgentlem 353
	    if ((cptr->callflag & mask) && cptr->cloenv == env)
70324 luke 354
		R_jumpctxt(cptr, mask, val);
33297 ripley 355
	error(_("no function to return from, jumping to top level"));
1839 ihaka 356
    }
357
}
2 r 358
 
87740 ripley 359
NORET attribute_hidden void R_JumpToContext(RCNTXT *target, int mask, SEXP val)
25520 luke 360
{
361
    RCNTXT *cptr;
362
    for (cptr = R_GlobalContext;
363
	 cptr != NULL && cptr->callflag != CTXT_TOPLEVEL;
66393 murdoch 364
	 cptr = cptr->nextcontext) {
25520 luke 365
	if (cptr == target)
70324 luke 366
	    R_jumpctxt(cptr, mask, val);
68923 ripley 367
	if (cptr == R_ExitContext)
66393 murdoch 368
	    R_ExitContext = NULL;
369
    }
33297 ripley 370
    error(_("target context is not on the stack"));
25520 luke 371
}
2 r 372
 
25520 luke 373
 
1839 ihaka 374
/* R_sysframe - look back up the context stack until the */
375
/* nth closure context and return that cloenv. */
376
/* R_sysframe(0) means the R_GlobalEnv environment */
377
/* negative n counts back from the current frame */
378
/* positive n counts up from the globalEnv */
379
 
83446 ripley 380
attribute_hidden SEXP R_sysframe(int n, RCNTXT *cptr)
2 r 381
{
1839 ihaka 382
    if (n == 0)
383
	return(R_GlobalEnv);
2 r 384
 
70927 ripley 385
    if (n == NA_INTEGER) error(_("NA argument is invalid"));
386
 
1839 ihaka 387
    if (n > 0)
388
	n = framedepth(cptr) - n;
389
    else
390
	n = -n;
2 r 391
 
1839 ihaka 392
    if(n < 0)
71390 luke 393
	error(_("not that many frames on the stack"));
2 r 394
 
1839 ihaka 395
    while (cptr->nextcontext != NULL) {
6188 rgentlem 396
	if (cptr->callflag & CTXT_FUNCTION ) {
1839 ihaka 397
	    if (n == 0) {  /* we need to detach the enclosing env */
398
		return cptr->cloenv;
399
	    }
400
	    else
401
		n--;
2 r 402
	}
1839 ihaka 403
	cptr = cptr->nextcontext;
404
    }
405
    if(n == 0 && cptr->nextcontext == NULL)
406
	return R_GlobalEnv;
407
    else
71390 luke 408
	error(_("not that many frames on the stack"));
6191 maechler 409
    return R_NilValue;	   /* just for -Wall */
2 r 410
}
411
 
1016 maechler 412
 
1839 ihaka 413
/* We need to find the environment that can be returned by sys.frame */
414
/* (so it needs to be on the cloenv pointer of a context) that matches */
415
/* the environment where the closure arguments are to be evaluated. */
416
/* It would be much simpler if sysparent just returned cptr->sysparent */
417
/* but then we wouldn't be compatible with S. */
2 r 418
 
87901 ripley 419
attribute_hidden int R_sysparent(int n, RCNTXT *cptr)
2 r 420
{
1839 ihaka 421
    int j;
422
    SEXP s;
423
    if(n <= 0)
32861 ripley 424
	errorcall(R_ToplevelContext->call,
33531 ripley 425
		  _("only positive values of 'n' are allowed"));
1839 ihaka 426
    while (cptr->nextcontext != NULL && n > 1) {
6188 rgentlem 427
	if (cptr->callflag & CTXT_FUNCTION )
1839 ihaka 428
	    n--;
429
	cptr = cptr->nextcontext;
430
    }
431
    /* make sure we're looking at a return context */
6188 rgentlem 432
    while (cptr->nextcontext != NULL && !(cptr->callflag & CTXT_FUNCTION) )
1839 ihaka 433
	cptr = cptr->nextcontext;
434
    s = cptr->sysparent;
435
    if(s == R_GlobalEnv)
436
	return 0;
437
    j = 0;
438
    while (cptr != NULL ) {
6188 rgentlem 439
	if (cptr->callflag & CTXT_FUNCTION) {
1839 ihaka 440
	    j++;
441
	    if( cptr->cloenv == s )
442
		n=j;
443
	}
444
	cptr = cptr->nextcontext;
445
    }
446
    n = j - n + 1;
447
    if (n < 0)
6098 pd 448
	n = 0;
1839 ihaka 449
    return n;
2 r 450
}
451
 
87901 ripley 452
attribute_hidden int framedepth(RCNTXT *cptr)
2 r 453
{
1839 ihaka 454
    int nframe = 0;
455
    while (cptr->nextcontext != NULL) {
6188 rgentlem 456
	if (cptr->callflag & CTXT_FUNCTION )
1839 ihaka 457
	    nframe++;
458
	cptr = cptr->nextcontext;
459
    }
460
    return nframe;
2 r 461
}
462
 
71390 luke 463
static SEXP getCallWithSrcref(RCNTXT *cptr)
464
{
465
    SEXP result;
466
 
467
    PROTECT(result = shallow_duplicate(cptr->call));
468
    if (cptr->srcref && !isNull(cptr->srcref)) {
469
	SEXP sref;
470
	if (cptr->srcref == R_InBCInterpreter)
471
	    /* FIXME: this is expensive, it might be worth changing sys.call */
472
	    /* to return srcrefs only on request (add `with.source` option) */
473
	    sref = R_findBCInterpreterSrcref(cptr);
474
	else
475
	    sref = cptr->srcref;
476
	setAttrib(result, R_SrcrefSymbol, duplicate(sref));
477
    }
478
    UNPROTECT(1);
479
    return result;
480
}
481
 
83446 ripley 482
attribute_hidden SEXP R_syscall(int n, RCNTXT *cptr)
2 r 483
{
1839 ihaka 484
    /* negative n counts back from the current frame */
485
    /* positive n counts up from the globalEnv */
486
    if (n > 0)
33531 ripley 487
	n = framedepth(cptr) - n;
1839 ihaka 488
    else
489
	n = - n;
33531 ripley 490
    if(n < 0)
71390 luke 491
	error(_("not that many frames on the stack"));
1839 ihaka 492
    while (cptr->nextcontext != NULL) {
6188 rgentlem 493
	if (cptr->callflag & CTXT_FUNCTION ) {
71390 luke 494
	    if (n == 0)
495
		return getCallWithSrcref(cptr);
496
	    else
1839 ihaka 497
		n--;
498
	}
499
	cptr = cptr->nextcontext;
500
    }
71390 luke 501
    if (n == 0 && cptr->nextcontext == NULL)
502
	return getCallWithSrcref(cptr);
503
    error(_("not that many frames on the stack"));
6191 maechler 504
    return R_NilValue;	/* just for -Wall */
2 r 505
}
506
 
83446 ripley 507
attribute_hidden SEXP R_sysfunction(int n, RCNTXT *cptr)
2 r 508
{
1839 ihaka 509
    if (n > 0)
1864 ihaka 510
	n = framedepth(cptr) - n;
1839 ihaka 511
    else
512
	n = - n;
33531 ripley 513
    if (n < 0)
71390 luke 514
	error(_("not that many frames on the stack"));
1839 ihaka 515
    while (cptr->nextcontext != NULL) {
6188 rgentlem 516
	if (cptr->callflag & CTXT_FUNCTION ) {
23463 luke 517
	    if (n == 0)
518
		return duplicate(cptr->callfun);  /***** do we need to DUP? */
1839 ihaka 519
	    else
520
		n--;
2 r 521
	}
1839 ihaka 522
	cptr = cptr->nextcontext;
523
    }
23463 luke 524
    if (n == 0 && cptr->nextcontext == NULL)
525
	return duplicate(cptr->callfun);  /***** do we need to DUP? */
71390 luke 526
    error(_("not that many frames on the stack"));
6191 maechler 527
    return R_NilValue;	/* just for -Wall */
2 r 528
}
1016 maechler 529
 
48598 rgentlem 530
/* count how many contexts of the specified type are present on the stack */
48600 rgentlem 531
/* browser contexts are a bit special because they are transient and for  */
532
/* any closure context with the debug bit set one will be created; so we  */
533
/* need to count those as well                                            */
86648 luke 534
attribute_hidden int countContexts(int ctxttype, int browser) {
48598 rgentlem 535
    int n=0;
536
    RCNTXT *cptr;
537
 
538
    cptr = R_GlobalContext;
539
    while( cptr != R_ToplevelContext) {
68923 ripley 540
	if( cptr->callflag == ctxttype )
541
	    n++;
542
	else if( browser ) {
543
	   if(cptr->callflag & CTXT_FUNCTION && RDEBUG(cptr->cloenv) )
544
	      n++;
545
	}
546
	cptr = cptr->nextcontext;
48598 rgentlem 547
    }
548
    return n;
549
}
68923 ripley 550
 
551
 
48437 rgentlem 552
/* functions to support looking up information about the browser */
553
/* contexts that are in the evaluation stack */
554
 
83446 ripley 555
attribute_hidden SEXP do_sysbrowser(SEXP call, SEXP op, SEXP args, SEXP rho)
48437 rgentlem 556
{
48459 rgentlem 557
    SEXP rval=R_NilValue;
48437 rgentlem 558
    RCNTXT *cptr;
71390 luke 559
    RCNTXT *prevcptr = NULL;
48551 rgentlem 560
    int n;
48437 rgentlem 561
 
562
    checkArity(op, args);
48551 rgentlem 563
    n = asInteger(CAR(args));
564
    if(n < 1 ) error(_("number of contexts must be positive"));
565
 
48437 rgentlem 566
    /* first find the closest  browser context */
567
    cptr = R_GlobalContext;
568
    while (cptr != R_ToplevelContext) {
68923 ripley 569
	if (cptr->callflag == CTXT_BROWSER) {
570
		break;
571
	}
572
	cptr = cptr->nextcontext;
48437 rgentlem 573
    }
48452 rgentlem 574
    /* error if not a browser context */
48437 rgentlem 575
 
48599 rgentlem 576
    if( !(cptr->callflag == CTXT_BROWSER) )
68923 ripley 577
	error(_("no browser context to query"));
48452 rgentlem 578
 
48437 rgentlem 579
    switch (PRIMVAL(op)) {
580
    case 1: /* text */
581
    case 2: /* condition */
68923 ripley 582
	/* first rewind to the right place if needed */
583
	/* note we want n>1, as we have already      */
584
	/* rewound to the first context              */
585
	if( n > 1 ) {
586
	   while (cptr != R_ToplevelContext && n > 0 ) {
587
	       if (cptr->callflag == CTXT_BROWSER) {
588
		   n--;
589
		   break;
590
	       }
591
	       cptr = cptr->nextcontext;
592
	   }
593
	}
594
	if( !(cptr->callflag == CTXT_BROWSER) )
595
	   error(_("not that many calls to browser are active"));
48551 rgentlem 596
 
68923 ripley 597
	if( PRIMVAL(op) == 1 )
598
	    rval = CAR(cptr->promargs);
599
	else
600
	    rval = CADR(cptr->promargs);
601
	break;
48551 rgentlem 602
    case 3: /* turn on debugging n levels up */
68923 ripley 603
	while ( (cptr != R_ToplevelContext) && n > 0 ) {
604
	    if (cptr->callflag & CTXT_FUNCTION)
605
		  n--;
71390 luke 606
	    prevcptr = cptr;
68923 ripley 607
	    cptr = cptr->nextcontext;
608
	}
609
	if( !(cptr->callflag & CTXT_FUNCTION) )
71390 luke 610
	    error(_("not that many functions on the call stack"));
611
	if( prevcptr && prevcptr->srcref == R_InBCInterpreter ) {
612
	    if ( TYPEOF(cptr->callfun) == CLOSXP &&
613
		    TYPEOF(BODY(cptr->callfun)) == BCODESXP )
614
		warning(_("debug flag in compiled function has no effect"));
615
	    else
616
		warning(_("debug will apply when function leaves "
617
			  "compiled code"));
618
	}
619
	SET_RDEBUG(cptr->cloenv, 1);
68923 ripley 620
	break;
48437 rgentlem 621
    }
622
    return(rval);
623
}
624
 
4857 rgentlem 625
/* An implementation of S's frame access functions. They usually count */
626
/* up from the globalEnv while we like to count down from the currentEnv. */
627
/* So if the argument is negative count down if positive count up. */
40192 ripley 628
/* We don't want to count the closure that do_sys is contained in, so the */
4857 rgentlem 629
/* indexing is adjusted to handle this. */
630
 
83979 luke 631
/* Return first `CTXT_FUNCTION` context whose execution
632
   env matches `rho` */
633
attribute_hidden RCNTXT *getLexicalContext(SEXP rho)
634
{
635
    RCNTXT *cptr = R_GlobalContext;
636
 
637
    while (cptr && cptr != R_ToplevelContext) {
638
	if (cptr->callflag & CTXT_FUNCTION && cptr->cloenv == rho)
639
	    break;
640
	cptr = cptr->nextcontext;
641
    }
642
 
643
    return cptr;
644
}
645
 
646
/* Return call of the first `CTXT_FUNCTION` context whose
647
   execution env matches `rho` */
648
attribute_hidden SEXP getLexicalCall(SEXP rho)
649
{
650
    RCNTXT *cptr = getLexicalContext(rho);
651
    if (cptr)
652
	return cptr->call;
653
    else
654
	return R_NilValue;
655
}
656
 
83446 ripley 657
attribute_hidden SEXP do_sys(SEXP call, SEXP op, SEXP args, SEXP rho)
2 r 658
{
40192 ripley 659
    int i, n  = -1, nframe;
83979 luke 660
    SEXP rval;
40192 ripley 661
 
662
    checkArity(op, args);
83979 luke 663
 
1839 ihaka 664
    /* first find the context that sys.xxx needs to be evaluated in */
83979 luke 665
    SEXP t = R_GlobalContext->sysparent;
666
    RCNTXT *cptr = getLexicalContext(t);
2 r 667
 
40192 ripley 668
    if (length(args) == 1) n = asInteger(CAR(args));
2 r 669
 
1839 ihaka 670
    switch (PRIMVAL(op)) {
671
    case 1: /* parent */
33531 ripley 672
	if(n == NA_INTEGER)
44512 ripley 673
	    error(_("invalid '%s' argument"), "n");
41894 ripley 674
	i = nframe = framedepth(cptr);
6098 pd 675
	/* This is a pretty awful kludge, but the alternative would be
676
	   a major redesign of everything... -pd */
677
	while (n-- > 0)
678
	    i = R_sysparent(nframe - i + 1, cptr);
41894 ripley 679
	return ScalarInteger(i);
1839 ihaka 680
    case 2: /* call */
33531 ripley 681
	if(n == NA_INTEGER)
44512 ripley 682
	    error(_("invalid '%s' argument"), "which");
1839 ihaka 683
	return R_syscall(n, cptr);
684
    case 3: /* frame */
33531 ripley 685
	if(n == NA_INTEGER)
44512 ripley 686
	    error(_("invalid '%s' argument"), "which");
1839 ihaka 687
	return R_sysframe(n, cptr);
688
    case 4: /* sys.nframe */
41894 ripley 689
	return ScalarInteger(framedepth(cptr));
1839 ihaka 690
    case 5: /* sys.calls */
33531 ripley 691
	nframe = framedepth(cptr);
692
	PROTECT(rval = allocList(nframe));
1839 ihaka 693
	t=rval;
33531 ripley 694
	for(i = 1; i <= nframe; i++, t = CDR(t))
695
	    SETCAR(t, R_syscall(i, cptr));
1839 ihaka 696
	UNPROTECT(1);
697
	return rval;
698
    case 6: /* sys.frames */
33531 ripley 699
	nframe = framedepth(cptr);
700
	PROTECT(rval = allocList(nframe));
701
	t = rval;
702
	for(i = 1; i <= nframe; i++, t = CDR(t))
703
	    SETCAR(t, R_sysframe(i, cptr));
1839 ihaka 704
	UNPROTECT(1);
705
	return rval;
706
    case 7: /* sys.on.exit */
73310 luke 707
	{
708
	    SEXP conexit = cptr->conexit;
73181 luke 709
	    if (conexit == R_NilValue)
710
		return R_NilValue;
711
	    else if (CDR(conexit) == R_NilValue)
712
		return CAR(conexit);
713
	    else
714
		return LCONS(R_BraceSymbol, conexit);
715
	}
1839 ihaka 716
    case 8: /* sys.parents */
33531 ripley 717
	nframe = framedepth(cptr);
718
	rval = allocVector(INTSXP, nframe);
719
	for(i = 0; i < nframe; i++)
720
	    INTEGER(rval)[i] = R_sysparent(nframe - i, cptr);
1839 ihaka 721
	return rval;
722
    case 9: /* sys.function */
33531 ripley 723
	if(n == NA_INTEGER)
44512 ripley 724
	    error(_("invalid '%s' value"), "which");
1839 ihaka 725
	return(R_sysfunction(n, cptr));
726
    default:
33531 ripley 727
	error(_("internal error in 'do_sys'"));
1839 ihaka 728
	return R_NilValue;/* just for -Wall */
729
    }
2 r 730
}
10583 pd 731
 
83446 ripley 732
attribute_hidden SEXP do_parentframe(SEXP call, SEXP op, SEXP args, SEXP rho)
10583 pd 733
{
40192 ripley 734
    checkArity(op, args);
10583 pd 735
 
78036 luke 736
    int n = asInteger(CAR(args));
10583 pd 737
    if(n == NA_INTEGER || n < 1 )
44512 ripley 738
	error(_("invalid '%s' value"), "n");
10583 pd 739
 
78036 luke 740
    RCNTXT *cptr = R_findParentContext(R_GlobalContext, n);
741
 
742
    if (cptr)
743
	return cptr->sysparent;
744
    else
745
	return R_GlobalEnv;
746
}
747
 
748
/* R_findExecContext - Find a context frame older than `cptr` that has
749
   `envir` as execution environment (the `cloenv` field). */
750
attribute_hidden
751
RCNTXT *R_findExecContext(RCNTXT *cptr, SEXP envir)
752
{
753
    while (cptr->nextcontext != NULL) {
754
	if ((cptr->callflag & CTXT_FUNCTION) != 0 && cptr->cloenv == envir)
755
	    return cptr;
10586 pd 756
	cptr = cptr->nextcontext;
10583 pd 757
    }
78036 luke 758
    return NULL;
10583 pd 759
}
10586 pd 760
 
78036 luke 761
/* R_findParentContext - Find a context frame older than `cptr` whose
762
   execution environment (`cloenv` field) is the same as cptr's
763
   calling environment (`sysparent` field). In other words, find the
764
   frame where `cptr->syscall` was (seemingly) called. This algorithm
765
   powers `parent.frame()`. */
766
attribute_hidden
767
RCNTXT *R_findParentContext(RCNTXT *cptr, int n)
768
{
769
    while ((cptr = R_findExecContext(cptr, cptr->sysparent)) != NULL) {
770
	if (n == 1)
771
	    return cptr;
772
	n--;
773
    }
774
    return NULL;
775
}
776
 
14634 luke 777
/* R_ToplevelExec - call fun(data) within a top level context to
84246 maechler 778
   insure that this function cannot be left by a LONGJMP.  R errors in
14634 luke 779
   the call to fun will result in a jump to top level. The return
780
   value is TRUE if fun returns normally, FALSE if it results in a
781
   jump to top level. */
782
 
38196 ripley 783
Rboolean R_ToplevelExec(void (*fun)(void *), void *data)
14634 luke 784
{
785
    RCNTXT thiscontext;
786
    RCNTXT * volatile saveToplevelContext;
73171 luke 787
    volatile SEXP topExp, oldHStack, oldRStack, oldRVal;
788
    volatile Rboolean oldvis;
14634 luke 789
    Rboolean result;
790
 
791
 
792
    PROTECT(topExp = R_CurrentExpr);
52909 luke 793
    PROTECT(oldHStack = R_HandlerStack);
73171 luke 794
    PROTECT(oldRStack = R_RestartStack);
795
    PROTECT(oldRVal = R_ReturnedValue);
796
    oldvis = R_Visible;
52909 luke 797
    R_HandlerStack = R_NilValue;
73171 luke 798
    R_RestartStack = R_NilValue;
14634 luke 799
    saveToplevelContext = R_ToplevelContext;
800
 
801
    begincontext(&thiscontext, CTXT_TOPLEVEL, R_NilValue, R_GlobalEnv,
37654 ripley 802
		 R_BaseEnv, R_NilValue, R_NilValue);
14634 luke 803
    if (SETJMP(thiscontext.cjmpbuf))
804
	result = FALSE;
805
    else {
806
	R_GlobalContext = R_ToplevelContext = &thiscontext;
807
	fun(data);
808
	result = TRUE;
809
    }
810
    endcontext(&thiscontext);
811
 
812
    R_ToplevelContext = saveToplevelContext;
813
    R_CurrentExpr = topExp;
52909 luke 814
    R_HandlerStack = oldHStack;
73171 luke 815
    R_RestartStack = oldRStack;
816
    R_ReturnedValue = oldRVal;
817
    R_Visible = oldvis;
818
    UNPROTECT(4);
14634 luke 819
 
820
    return result;
821
}
17021 duncan 822
 
76368 urbaneks 823
/* Return the current environment. */
88921 luke 824
/* The _current environment_ is taken to be the top closure call
825
   environment on the context stack, or .GlobalEnv if there is none.
826
   An alternative would be the environment in which a .Call or similar
827
   expression is evaluated. This is currently not recorded; doing so
828
   would incur some overhead that does not seem warranted.
829
 */
82931 ripley 830
SEXP R_GetCurrentEnv(void) {
88921 luke 831
    RCNTXT *cptr = R_GlobalContext;
832
    while (cptr->nextcontext != NULL) {
833
	if ((cptr->callflag & CTXT_FUNCTION) != 0)
834
	    return cptr->cloenv;
835
	else cptr = cptr->nextcontext;
836
    }
837
    return R_GlobalEnv;
76368 urbaneks 838
}
17021 duncan 839
 
840
 
841
/*
842
  This is a simple interface for evaluating R expressions
45446 ripley 843
  from C with a guarantee that one will return to the
40779 ripley 844
  point in the code from which the call was made (if it does
845
  return at all).
17021 duncan 846
  This uses R_TopleveExec to do this.  It is important
45446 ripley 847
  in applications that embed R or wish to make general
17021 duncan 848
  callbacks to R with error handling.
849
 
850
  It is currently hidden with a data structure definition
851
  and C routine visible only here. The R_tryEval() is the
852
  only visible aspect. This can be lifted into the header
853
  files if necessary. (DTL)
40779 ripley 854
 
855
  R_tryEval is in Rinternals.h (so public), but not in the API.
17021 duncan 856
 */
857
typedef struct {
858
    SEXP expression;
859
    SEXP val;
860
    SEXP env;
861
} ProtectedEvalData;
862
 
863
static void
864
protectedEval(void *d)
865
{
866
    ProtectedEvalData *data = (ProtectedEvalData *)d;
867
    SEXP env = R_GlobalEnv;
868
    if(data->env) {
869
	env = data->env;
870
    }
45446 ripley 871
    data->val = eval(data->expression, env);
78127 kalibera 872
    R_PreserveObject(data->val);
17021 duncan 873
}
874
 
875
SEXP
876
R_tryEval(SEXP e, SEXP env, int *ErrorOccurred)
877
{
25523 luke 878
    Rboolean ok;
879
    ProtectedEvalData data;
17021 duncan 880
 
25523 luke 881
    data.expression = e;
882
    data.val = NULL;
883
    data.env = env;
17021 duncan 884
 
25523 luke 885
    ok = R_ToplevelExec(protectedEval, &data);
886
    if (ErrorOccurred) {
887
	*ErrorOccurred = (ok == FALSE);
888
    }
889
    if (ok == FALSE)
890
	data.val = NULL;
891
    else
78127 kalibera 892
	R_ReleaseObject(data.val);
17021 duncan 893
 
25523 luke 894
    return(data.val);
17021 duncan 895
}
52910 luke 896
 
897
/* Temporary hack to suppress error message printing around a
898
   R_tryEval call for use in methods_list_dispatch.c; should be
899
   replaced once we have a way of establishing error handlers from C
900
   code (probably would want a calling handler if we want to allow
901
   user-defined calling handlers to enter a debugger, for
902
   example). LT */
903
SEXP R_tryEvalSilent(SEXP e, SEXP env, int *ErrorOccurred)
904
{
905
    SEXP val;
87816 ripley 906
    int oldshow = R_ShowErrorMessages;
52910 luke 907
    R_ShowErrorMessages = FALSE;
908
    val = R_tryEval(e, env, ErrorOccurred);
909
    R_ShowErrorMessages = oldshow;
910
    return val;
911
}
64091 luke 912
 
913
SEXP R_ExecWithCleanup(SEXP (*fun)(void *), void *data,
914
		       void (*cleanfun)(void *), void *cleandata)
915
{
916
    RCNTXT cntxt;
917
    SEXP result;
918
 
919
    begincontext(&cntxt, CTXT_CCODE, R_NilValue, R_BaseEnv, R_BaseEnv,
920
		 R_NilValue, R_NilValue);
921
    cntxt.cend = cleanfun;
922
    cntxt.cenddata = cleandata;
923
 
78063 luke 924
    PROTECT(result = fun(data));
64091 luke 925
    cleanfun(cleandata);
78127 kalibera 926
    endcontext(&cntxt);
78063 luke 927
    UNPROTECT(1);
64091 luke 928
 
929
    return result;
930
}
73866 luke 931
 
932
 
933
/* Unwind-protect mechanism to support C++ stack unwinding. */
934
 
935
typedef struct {
936
    int jumpmask;
937
    RCNTXT *jumptarget;
938
} unwind_cont_t;
939
 
82931 ripley 940
SEXP R_MakeUnwindCont(void)
73866 luke 941
{
942
    return CONS(R_NilValue, allocVector(RAWSXP, sizeof(unwind_cont_t)));
943
}
944
 
74412 luke 945
#define RAWDATA(x) ((void *) RAW0(x))
73866 luke 946
 
83454 ripley 947
NORET void R_ContinueUnwind(SEXP cont)
73866 luke 948
{
949
    SEXP retval = CAR(cont);
74412 luke 950
    unwind_cont_t *u = RAWDATA(CDR(cont));
73866 luke 951
    R_jumpctxt(u->jumptarget, u->jumpmask, retval);
952
}
953
 
954
SEXP R_UnwindProtect(SEXP (*fun)(void *data), void *data,
955
		     void (*cleanfun)(void *data, Rboolean jump),
956
		     void *cleandata, SEXP cont)
957
{
958
    RCNTXT thiscontext;
86217 luke 959
    volatile SEXP result;
73866 luke 960
    Rboolean jump;
961
 
84246 maechler 962
    /* Allow simple usage with a NULL continuation token. This _could_
74256 luke 963
       result in a failure in allocation or exceeding the PROTECT
964
       stack limit before calling fun(), so fun() and cleanfun should
965
       be written accordingly. */
966
    if (cont == NULL) {
967
	PROTECT(cont = R_MakeUnwindCont());
968
	result = R_UnwindProtect(fun, data, cleanfun, cleandata, cont);
969
	UNPROTECT(1);
970
	return result;
971
    }
972
 
73866 luke 973
    begincontext(&thiscontext, CTXT_UNWIND, R_NilValue, R_GlobalEnv,
974
		 R_BaseEnv, R_NilValue, R_NilValue);
975
    if (SETJMP(thiscontext.cjmpbuf)) {
976
	jump = TRUE;
977
	SETCAR(cont, R_ReturnedValue);
74412 luke 978
	unwind_cont_t *u = RAWDATA(CDR(cont));
73866 luke 979
	u->jumpmask = thiscontext.jumpmask;
980
	u->jumptarget = thiscontext.jumptarget;
981
	thiscontext.jumptarget = NULL;
982
    }
983
    else {
984
	result = fun(data);
985
	SETCAR(cont, result);
986
	jump = FALSE;
987
    }
988
    endcontext(&thiscontext);
989
 
990
    cleanfun(cleandata, jump);
991
 
992
    if (jump)
993
	R_ContinueUnwind(cont);	
994
 
995
    return result;
996
}