The R Project SVN R

Rev

Rev 77275 | Rev 78063 | Go to most recent revision | 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
75956 ripley 4
 *  Copyright (C) 1998-2019   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
 *
91
 *  This causes "val" to be stuffed into a globally accessable place and
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
 
37001 ripley 120
void attribute_hidden 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 */
141
	    c->returnValue = 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;
14479 luke 177
    R_EvalDepth = cptr->evaldepth;
14480 luke 178
    vmaxset(cptr->vmax);
25200 luke 179
    R_interrupts_suspended = cptr->intsusp;
25523 luke 180
    R_HandlerStack = cptr->handlerstack;
181
    R_RestartStack = cptr->restartstack;
41992 luke 182
    while (R_PendingPromises != cptr->prstack) {
42875 luke 183
	/* The value 2 installed in PRSEEN 2 allows forcePromise in
41992 luke 184
	   eval.c to signal a warning when asked to evaluate a promise
185
	   whose evaluation has been interrupted by a jump. */
186
	SET_PRSEEN(R_PendingPromises->promise, 2);
187
	R_PendingPromises = R_PendingPromises->next;
188
    }
42875 luke 189
    /* Need to reset R_Expressions in case we are jumping after
190
       handling a stack overflow. */
191
    R_Expressions = R_Expressions_keep;
26026 luke 192
    R_BCNodeStackTop = cptr->nodestack;
48623 murdoch 193
    R_Srcref = cptr->srcref;
77275 luke 194
    R_BCProtReset(cptr->bcprottop);
14479 luke 195
}
196
 
70325 luke 197
static RCNTXT *first_jump_target(RCNTXT *cptr, int mask)
198
{
199
    RCNTXT *c;
200
 
201
    for (c = R_GlobalContext; c && c != cptr; c = c->nextcontext) {
73866 luke 202
	if ((c->cloenv != R_NilValue && c->conexit != R_NilValue) ||
203
	    c->callflag == CTXT_UNWIND) {
70325 luke 204
	    c->jumptarget = cptr;
205
	    c->jumpmask = mask;
206
	    return c;
207
	}
208
    }
209
    return cptr;
210
}
211
 
70324 luke 212
/* R_jumpctxt - jump to the named context */
14479 luke 213
 
70325 luke 214
void attribute_hidden NORET R_jumpctxt(RCNTXT * targetcptr, int mask, SEXP val)
14478 luke 215
{
40068 ripley 216
    Rboolean savevis = R_Visible;
70325 luke 217
    RCNTXT *cptr;
14478 luke 218
 
70325 luke 219
    /* find the target for the first jump -- either an intermediate
220
       context with an on.exit action to run or the final target if
221
       there are no intermediate on.exit actions */
222
    cptr = first_jump_target(targetcptr, mask);
223
 
224
    /* run cend code for all contexts down to but not including
225
       the first jump target */
14478 luke 226
    R_run_onexits(cptr);
14443 luke 227
    R_Visible = savevis;
228
 
1895 ihaka 229
    R_ReturnedValue = val;
70324 luke 230
    R_GlobalContext = cptr;
19318 luke 231
    R_restore_globals(R_GlobalContext);
232
 
70324 luke 233
    /* if we are in the process of handling a C stack overflow we need
234
       to restore the C stack limit before the jump */
235
    if (R_OldCStackLimit != 0) {
236
	R_CStackLimit = R_OldCStackLimit;
237
	R_OldCStackLimit = 0;
238
    }
239
 
3090 ihaka 240
    LONGJMP(cptr->cjmpbuf, mask);
1895 ihaka 241
}
242
 
243
 
2 r 244
/* begincontext - begin an execution context */
1839 ihaka 245
 
38662 ripley 246
/* begincontext and endcontext are used in dataentry.c and modules */
1839 ihaka 247
void begincontext(RCNTXT * cptr, int flags,
23463 luke 248
		  SEXP syscall, SEXP env, SEXP sysp,
249
		  SEXP promargs, SEXP callfun)
2 r 250
{
1839 ihaka 251
    cptr->cstacktop = R_PPStackTop;
68755 luke 252
    cptr->gcenabled = R_GCEnabled;
71390 luke 253
    cptr->bcpc = R_BCpc;
254
    cptr->bcbody = R_BCbody;
255
    cptr->bcintactive = R_BCIntActive;
8230 rgentlem 256
    cptr->evaldepth = R_EvalDepth;
1839 ihaka 257
    cptr->callflag = flags;
258
    cptr->call = syscall;
259
    cptr->cloenv = env;
260
    cptr->sysparent = sysp;
261
    cptr->conexit = R_NilValue;
262
    cptr->cend = NULL;
263
    cptr->promargs = promargs;
23463 luke 264
    cptr->callfun = callfun;
14480 luke 265
    cptr->vmax = vmaxget();
25200 luke 266
    cptr->intsusp = R_interrupts_suspended;
25523 luke 267
    cptr->handlerstack = R_HandlerStack;
268
    cptr->restartstack = R_RestartStack;
41992 luke 269
    cptr->prstack = R_PendingPromises;
26026 luke 270
    cptr->nodestack = R_BCNodeStackTop;
77275 luke 271
    cptr->bcprottop = R_BCProtTop;
68923 ripley 272
    cptr->srcref = R_Srcref;
63400 murdoch 273
    cptr->browserfinish = R_GlobalContext->browserfinish;
62867 luke 274
    cptr->nextcontext = R_GlobalContext;
66393 murdoch 275
    cptr->returnValue = NULL;
70325 luke 276
    cptr->jumptarget = NULL;
277
    cptr->jumpmask = 0;
63400 murdoch 278
 
1839 ihaka 279
    R_GlobalContext = cptr;
2 r 280
}
281
 
1839 ihaka 282
 
2 r 283
/* endcontext - end an execution context */
1839 ihaka 284
 
2 r 285
void endcontext(RCNTXT * cptr)
286
{
73853 luke 287
    void R_FixupExitingHandlerResult(SEXP); /* defined in error.x */
25523 luke 288
    R_HandlerStack = cptr->handlerstack;
289
    R_RestartStack = cptr->restartstack;
73133 luke 290
    RCNTXT *jumptarget = cptr->jumptarget;
14878 luke 291
    if (cptr->cloenv != R_NilValue && cptr->conexit != R_NilValue ) {
15299 luke 292
	SEXP s = cptr->conexit;
40090 ripley 293
	Rboolean savevis = R_Visible;
66393 murdoch 294
	RCNTXT* savecontext = R_ExitContext;
73111 kalibera 295
	SEXP saveretval = R_ReturnedValue;
66393 murdoch 296
	R_ExitContext = cptr;
15299 luke 297
	cptr->conexit = R_NilValue; /* prevent recursion */
73133 luke 298
	cptr->jumptarget = NULL; /* in case on.exit expr calls return() */
73111 kalibera 299
	PROTECT(saveretval);
15299 luke 300
	PROTECT(s);
73853 luke 301
	R_FixupExitingHandlerResult(saveretval);
77380 luke 302
	if (cptr->returnValue) // why is this needed???
303
	    INCREMENT_LINKS(cptr->returnValue);
73181 luke 304
	for (; s != R_NilValue; s = CDR(s)) {
305
	    cptr->conexit = CDR(s);
306
	    eval(CAR(s), cptr->cloenv);
307
	}
77380 luke 308
	if (cptr->returnValue) // why is this needed???
309
	    DECREMENT_LINKS(cptr->returnValue);
73111 kalibera 310
	R_ReturnedValue = saveretval;
311
	UNPROTECT(2);
66393 murdoch 312
	R_ExitContext = savecontext;
15299 luke 313
	R_Visible = savevis;
14878 luke 314
    }
66393 murdoch 315
    if (R_ExitContext == cptr)
68923 ripley 316
	R_ExitContext = NULL;
70325 luke 317
    /* continue jumping if this was reached as an intermetiate jump */
73133 luke 318
    if (jumptarget)
73111 kalibera 319
	/* cptr->returnValue is undefined */
73133 luke 320
	R_jumpctxt(jumptarget, cptr->jumpmask, R_ReturnedValue);
70325 luke 321
 
1839 ihaka 322
    R_GlobalContext = cptr->nextcontext;
2 r 323
}
324
 
1839 ihaka 325
 
2 r 326
/* findcontext - find the correct context */
1839 ihaka 327
 
67181 luke 328
void attribute_hidden NORET findcontext(int mask, SEXP env, SEXP val)
2 r 329
{
1839 ihaka 330
    RCNTXT *cptr;
331
    cptr = R_GlobalContext;
332
    if (mask & CTXT_LOOP) {		/* break/next */
14633 luke 333
	for (cptr = R_GlobalContext;
334
	     cptr != NULL && cptr->callflag != CTXT_TOPLEVEL;
335
	     cptr = cptr->nextcontext)
13793 rgentlem 336
	    if (cptr->callflag & CTXT_LOOP && cptr->cloenv == env )
70324 luke 337
		R_jumpctxt(cptr, mask, val);
55024 murdoch 338
	error(_("no loop for break/next, jumping to top level"));
1839 ihaka 339
    }
340
    else {				/* return; or browser */
14633 luke 341
	for (cptr = R_GlobalContext;
342
	     cptr != NULL && cptr->callflag != CTXT_TOPLEVEL;
343
	     cptr = cptr->nextcontext)
4089 rgentlem 344
	    if ((cptr->callflag & mask) && cptr->cloenv == env)
70324 luke 345
		R_jumpctxt(cptr, mask, val);
33297 ripley 346
	error(_("no function to return from, jumping to top level"));
1839 ihaka 347
    }
348
}
2 r 349
 
67181 luke 350
void attribute_hidden NORET R_JumpToContext(RCNTXT *target, int mask, SEXP val)
25520 luke 351
{
352
    RCNTXT *cptr;
353
    for (cptr = R_GlobalContext;
354
	 cptr != NULL && cptr->callflag != CTXT_TOPLEVEL;
66393 murdoch 355
	 cptr = cptr->nextcontext) {
25520 luke 356
	if (cptr == target)
70324 luke 357
	    R_jumpctxt(cptr, mask, val);
68923 ripley 358
	if (cptr == R_ExitContext)
66393 murdoch 359
	    R_ExitContext = NULL;
360
    }
33297 ripley 361
    error(_("target context is not on the stack"));
25520 luke 362
}
2 r 363
 
25520 luke 364
 
1839 ihaka 365
/* R_sysframe - look back up the context stack until the */
366
/* nth closure context and return that cloenv. */
367
/* R_sysframe(0) means the R_GlobalEnv environment */
368
/* negative n counts back from the current frame */
369
/* positive n counts up from the globalEnv */
370
 
37001 ripley 371
SEXP attribute_hidden R_sysframe(int n, RCNTXT *cptr)
2 r 372
{
1839 ihaka 373
    if (n == 0)
374
	return(R_GlobalEnv);
2 r 375
 
70927 ripley 376
    if (n == NA_INTEGER) error(_("NA argument is invalid"));
377
 
1839 ihaka 378
    if (n > 0)
379
	n = framedepth(cptr) - n;
380
    else
381
	n = -n;
2 r 382
 
1839 ihaka 383
    if(n < 0)
71390 luke 384
	error(_("not that many frames on the stack"));
2 r 385
 
1839 ihaka 386
    while (cptr->nextcontext != NULL) {
6188 rgentlem 387
	if (cptr->callflag & CTXT_FUNCTION ) {
1839 ihaka 388
	    if (n == 0) {  /* we need to detach the enclosing env */
389
		return cptr->cloenv;
390
	    }
391
	    else
392
		n--;
2 r 393
	}
1839 ihaka 394
	cptr = cptr->nextcontext;
395
    }
396
    if(n == 0 && cptr->nextcontext == NULL)
397
	return R_GlobalEnv;
398
    else
71390 luke 399
	error(_("not that many frames on the stack"));
6191 maechler 400
    return R_NilValue;	   /* just for -Wall */
2 r 401
}
402
 
1016 maechler 403
 
1839 ihaka 404
/* We need to find the environment that can be returned by sys.frame */
405
/* (so it needs to be on the cloenv pointer of a context) that matches */
406
/* the environment where the closure arguments are to be evaluated. */
407
/* It would be much simpler if sysparent just returned cptr->sysparent */
408
/* but then we wouldn't be compatible with S. */
2 r 409
 
37001 ripley 410
int attribute_hidden R_sysparent(int n, RCNTXT *cptr)
2 r 411
{
1839 ihaka 412
    int j;
413
    SEXP s;
414
    if(n <= 0)
32861 ripley 415
	errorcall(R_ToplevelContext->call,
33531 ripley 416
		  _("only positive values of 'n' are allowed"));
1839 ihaka 417
    while (cptr->nextcontext != NULL && n > 1) {
6188 rgentlem 418
	if (cptr->callflag & CTXT_FUNCTION )
1839 ihaka 419
	    n--;
420
	cptr = cptr->nextcontext;
421
    }
422
    /* make sure we're looking at a return context */
6188 rgentlem 423
    while (cptr->nextcontext != NULL && !(cptr->callflag & CTXT_FUNCTION) )
1839 ihaka 424
	cptr = cptr->nextcontext;
425
    s = cptr->sysparent;
426
    if(s == R_GlobalEnv)
427
	return 0;
428
    j = 0;
429
    while (cptr != NULL ) {
6188 rgentlem 430
	if (cptr->callflag & CTXT_FUNCTION) {
1839 ihaka 431
	    j++;
432
	    if( cptr->cloenv == s )
433
		n=j;
434
	}
435
	cptr = cptr->nextcontext;
436
    }
437
    n = j - n + 1;
438
    if (n < 0)
6098 pd 439
	n = 0;
1839 ihaka 440
    return n;
2 r 441
}
442
 
37001 ripley 443
int attribute_hidden framedepth(RCNTXT *cptr)
2 r 444
{
1839 ihaka 445
    int nframe = 0;
446
    while (cptr->nextcontext != NULL) {
6188 rgentlem 447
	if (cptr->callflag & CTXT_FUNCTION )
1839 ihaka 448
	    nframe++;
449
	cptr = cptr->nextcontext;
450
    }
451
    return nframe;
2 r 452
}
453
 
71390 luke 454
static SEXP getCallWithSrcref(RCNTXT *cptr)
455
{
456
    SEXP result;
457
 
458
    PROTECT(result = shallow_duplicate(cptr->call));
459
    if (cptr->srcref && !isNull(cptr->srcref)) {
460
	SEXP sref;
461
	if (cptr->srcref == R_InBCInterpreter)
462
	    /* FIXME: this is expensive, it might be worth changing sys.call */
463
	    /* to return srcrefs only on request (add `with.source` option) */
464
	    sref = R_findBCInterpreterSrcref(cptr);
465
	else
466
	    sref = cptr->srcref;
467
	setAttrib(result, R_SrcrefSymbol, duplicate(sref));
468
    }
469
    UNPROTECT(1);
470
    return result;
471
}
472
 
37001 ripley 473
SEXP attribute_hidden R_syscall(int n, RCNTXT *cptr)
2 r 474
{
1839 ihaka 475
    /* negative n counts back from the current frame */
476
    /* positive n counts up from the globalEnv */
477
    if (n > 0)
33531 ripley 478
	n = framedepth(cptr) - n;
1839 ihaka 479
    else
480
	n = - n;
33531 ripley 481
    if(n < 0)
71390 luke 482
	error(_("not that many frames on the stack"));
1839 ihaka 483
    while (cptr->nextcontext != NULL) {
6188 rgentlem 484
	if (cptr->callflag & CTXT_FUNCTION ) {
71390 luke 485
	    if (n == 0)
486
		return getCallWithSrcref(cptr);
487
	    else
1839 ihaka 488
		n--;
489
	}
490
	cptr = cptr->nextcontext;
491
    }
71390 luke 492
    if (n == 0 && cptr->nextcontext == NULL)
493
	return getCallWithSrcref(cptr);
494
    error(_("not that many frames on the stack"));
6191 maechler 495
    return R_NilValue;	/* just for -Wall */
2 r 496
}
497
 
37001 ripley 498
SEXP attribute_hidden R_sysfunction(int n, RCNTXT *cptr)
2 r 499
{
1839 ihaka 500
    if (n > 0)
1864 ihaka 501
	n = framedepth(cptr) - n;
1839 ihaka 502
    else
503
	n = - n;
33531 ripley 504
    if (n < 0)
71390 luke 505
	error(_("not that many frames on the stack"));
1839 ihaka 506
    while (cptr->nextcontext != NULL) {
6188 rgentlem 507
	if (cptr->callflag & CTXT_FUNCTION ) {
23463 luke 508
	    if (n == 0)
509
		return duplicate(cptr->callfun);  /***** do we need to DUP? */
1839 ihaka 510
	    else
511
		n--;
2 r 512
	}
1839 ihaka 513
	cptr = cptr->nextcontext;
514
    }
23463 luke 515
    if (n == 0 && cptr->nextcontext == NULL)
516
	return duplicate(cptr->callfun);  /***** do we need to DUP? */
71390 luke 517
    error(_("not that many frames on the stack"));
6191 maechler 518
    return R_NilValue;	/* just for -Wall */
2 r 519
}
1016 maechler 520
 
48598 rgentlem 521
/* count how many contexts of the specified type are present on the stack */
48600 rgentlem 522
/* browser contexts are a bit special because they are transient and for  */
523
/* any closure context with the debug bit set one will be created; so we  */
524
/* need to count those as well                                            */
525
int countContexts(int ctxttype, int browser) {
48598 rgentlem 526
    int n=0;
527
    RCNTXT *cptr;
528
 
529
    cptr = R_GlobalContext;
530
    while( cptr != R_ToplevelContext) {
68923 ripley 531
	if( cptr->callflag == ctxttype )
532
	    n++;
533
	else if( browser ) {
534
	   if(cptr->callflag & CTXT_FUNCTION && RDEBUG(cptr->cloenv) )
535
	      n++;
536
	}
537
	cptr = cptr->nextcontext;
48598 rgentlem 538
    }
539
    return n;
540
}
68923 ripley 541
 
542
 
48437 rgentlem 543
/* functions to support looking up information about the browser */
544
/* contexts that are in the evaluation stack */
545
 
546
SEXP attribute_hidden do_sysbrowser(SEXP call, SEXP op, SEXP args, SEXP rho)
547
{
48459 rgentlem 548
    SEXP rval=R_NilValue;
48437 rgentlem 549
    RCNTXT *cptr;
71390 luke 550
    RCNTXT *prevcptr = NULL;
48551 rgentlem 551
    int n;
48437 rgentlem 552
 
553
    checkArity(op, args);
48551 rgentlem 554
    n = asInteger(CAR(args));
555
    if(n < 1 ) error(_("number of contexts must be positive"));
556
 
48437 rgentlem 557
    /* first find the closest  browser context */
558
    cptr = R_GlobalContext;
559
    while (cptr != R_ToplevelContext) {
68923 ripley 560
	if (cptr->callflag == CTXT_BROWSER) {
561
		break;
562
	}
563
	cptr = cptr->nextcontext;
48437 rgentlem 564
    }
48452 rgentlem 565
    /* error if not a browser context */
48437 rgentlem 566
 
48599 rgentlem 567
    if( !(cptr->callflag == CTXT_BROWSER) )
68923 ripley 568
	error(_("no browser context to query"));
48452 rgentlem 569
 
48437 rgentlem 570
    switch (PRIMVAL(op)) {
571
    case 1: /* text */
572
    case 2: /* condition */
68923 ripley 573
	/* first rewind to the right place if needed */
574
	/* note we want n>1, as we have already      */
575
	/* rewound to the first context              */
576
	if( n > 1 ) {
577
	   while (cptr != R_ToplevelContext && n > 0 ) {
578
	       if (cptr->callflag == CTXT_BROWSER) {
579
		   n--;
580
		   break;
581
	       }
582
	       cptr = cptr->nextcontext;
583
	   }
584
	}
585
	if( !(cptr->callflag == CTXT_BROWSER) )
586
	   error(_("not that many calls to browser are active"));
48551 rgentlem 587
 
68923 ripley 588
	if( PRIMVAL(op) == 1 )
589
	    rval = CAR(cptr->promargs);
590
	else
591
	    rval = CADR(cptr->promargs);
592
	break;
48551 rgentlem 593
    case 3: /* turn on debugging n levels up */
68923 ripley 594
	while ( (cptr != R_ToplevelContext) && n > 0 ) {
595
	    if (cptr->callflag & CTXT_FUNCTION)
596
		  n--;
71390 luke 597
	    prevcptr = cptr;
68923 ripley 598
	    cptr = cptr->nextcontext;
599
	}
600
	if( !(cptr->callflag & CTXT_FUNCTION) )
71390 luke 601
	    error(_("not that many functions on the call stack"));
602
	if( prevcptr && prevcptr->srcref == R_InBCInterpreter ) {
603
	    if ( TYPEOF(cptr->callfun) == CLOSXP &&
604
		    TYPEOF(BODY(cptr->callfun)) == BCODESXP )
605
		warning(_("debug flag in compiled function has no effect"));
606
	    else
607
		warning(_("debug will apply when function leaves "
608
			  "compiled code"));
609
	}
610
	SET_RDEBUG(cptr->cloenv, 1);
68923 ripley 611
	break;
48437 rgentlem 612
    }
613
    return(rval);
614
}
615
 
4857 rgentlem 616
/* An implementation of S's frame access functions. They usually count */
617
/* up from the globalEnv while we like to count down from the currentEnv. */
618
/* So if the argument is negative count down if positive count up. */
40192 ripley 619
/* We don't want to count the closure that do_sys is contained in, so the */
4857 rgentlem 620
/* indexing is adjusted to handle this. */
621
 
36990 ripley 622
SEXP attribute_hidden do_sys(SEXP call, SEXP op, SEXP args, SEXP rho)
2 r 623
{
40192 ripley 624
    int i, n  = -1, nframe;
625
    SEXP rval, t;
1839 ihaka 626
    RCNTXT *cptr;
40192 ripley 627
 
628
    checkArity(op, args);
1839 ihaka 629
    /* first find the context that sys.xxx needs to be evaluated in */
630
    cptr = R_GlobalContext;
631
    t = cptr->sysparent;
632
    while (cptr != R_ToplevelContext) {
6188 rgentlem 633
	if (cptr->callflag & CTXT_FUNCTION )
1839 ihaka 634
	    if (cptr->cloenv == t)
635
		break;
636
	cptr = cptr->nextcontext;
637
    }
2 r 638
 
40192 ripley 639
    if (length(args) == 1) n = asInteger(CAR(args));
2 r 640
 
1839 ihaka 641
    switch (PRIMVAL(op)) {
642
    case 1: /* parent */
33531 ripley 643
	if(n == NA_INTEGER)
44512 ripley 644
	    error(_("invalid '%s' argument"), "n");
41894 ripley 645
	i = nframe = framedepth(cptr);
6098 pd 646
	/* This is a pretty awful kludge, but the alternative would be
647
	   a major redesign of everything... -pd */
648
	while (n-- > 0)
649
	    i = R_sysparent(nframe - i + 1, cptr);
41894 ripley 650
	return ScalarInteger(i);
1839 ihaka 651
    case 2: /* call */
33531 ripley 652
	if(n == NA_INTEGER)
44512 ripley 653
	    error(_("invalid '%s' argument"), "which");
1839 ihaka 654
	return R_syscall(n, cptr);
655
    case 3: /* frame */
33531 ripley 656
	if(n == NA_INTEGER)
44512 ripley 657
	    error(_("invalid '%s' argument"), "which");
1839 ihaka 658
	return R_sysframe(n, cptr);
659
    case 4: /* sys.nframe */
41894 ripley 660
	return ScalarInteger(framedepth(cptr));
1839 ihaka 661
    case 5: /* sys.calls */
33531 ripley 662
	nframe = framedepth(cptr);
663
	PROTECT(rval = allocList(nframe));
1839 ihaka 664
	t=rval;
33531 ripley 665
	for(i = 1; i <= nframe; i++, t = CDR(t))
666
	    SETCAR(t, R_syscall(i, cptr));
1839 ihaka 667
	UNPROTECT(1);
668
	return rval;
669
    case 6: /* sys.frames */
33531 ripley 670
	nframe = framedepth(cptr);
671
	PROTECT(rval = allocList(nframe));
672
	t = rval;
673
	for(i = 1; i <= nframe; i++, t = CDR(t))
674
	    SETCAR(t, R_sysframe(i, cptr));
1839 ihaka 675
	UNPROTECT(1);
676
	return rval;
677
    case 7: /* sys.on.exit */
73310 luke 678
	{
679
	    SEXP conexit = cptr->conexit;
73181 luke 680
	    if (conexit == R_NilValue)
681
		return R_NilValue;
682
	    else if (CDR(conexit) == R_NilValue)
683
		return CAR(conexit);
684
	    else
685
		return LCONS(R_BraceSymbol, conexit);
686
	}
1839 ihaka 687
    case 8: /* sys.parents */
33531 ripley 688
	nframe = framedepth(cptr);
689
	rval = allocVector(INTSXP, nframe);
690
	for(i = 0; i < nframe; i++)
691
	    INTEGER(rval)[i] = R_sysparent(nframe - i, cptr);
1839 ihaka 692
	return rval;
693
    case 9: /* sys.function */
33531 ripley 694
	if(n == NA_INTEGER)
44512 ripley 695
	    error(_("invalid '%s' value"), "which");
1839 ihaka 696
	return(R_sysfunction(n, cptr));
697
    default:
33531 ripley 698
	error(_("internal error in 'do_sys'"));
1839 ihaka 699
	return R_NilValue;/* just for -Wall */
700
    }
2 r 701
}
10583 pd 702
 
36990 ripley 703
SEXP attribute_hidden do_parentframe(SEXP call, SEXP op, SEXP args, SEXP rho)
10583 pd 704
{
10586 pd 705
    int n;
706
    SEXP t;
10583 pd 707
    RCNTXT *cptr;
708
 
40192 ripley 709
    checkArity(op, args);
710
    t = CAR(args);
10583 pd 711
    n = asInteger(t);
712
 
713
    if(n == NA_INTEGER || n < 1 )
44512 ripley 714
	error(_("invalid '%s' value"), "n");
10583 pd 715
 
716
    cptr = R_GlobalContext;
717
    t = cptr->sysparent;
10586 pd 718
    while (cptr->nextcontext != NULL){
719
	if (cptr->callflag & CTXT_FUNCTION ) {
720
	    if (cptr->cloenv == t)
721
	    {
45446 ripley 722
		if (n == 1)
10586 pd 723
		    return cptr->sysparent;
724
		n--;
725
		t = cptr->sysparent;
726
	    }
10583 pd 727
	}
10586 pd 728
	cptr = cptr->nextcontext;
10583 pd 729
    }
10586 pd 730
    return R_GlobalEnv;
10583 pd 731
}
10586 pd 732
 
14634 luke 733
/* R_ToplevelExec - call fun(data) within a top level context to
734
   insure that this functin cannot be left by a LONGJMP.  R errors in
735
   the call to fun will result in a jump to top level. The return
736
   value is TRUE if fun returns normally, FALSE if it results in a
737
   jump to top level. */
738
 
38196 ripley 739
Rboolean R_ToplevelExec(void (*fun)(void *), void *data)
14634 luke 740
{
741
    RCNTXT thiscontext;
742
    RCNTXT * volatile saveToplevelContext;
73171 luke 743
    volatile SEXP topExp, oldHStack, oldRStack, oldRVal;
744
    volatile Rboolean oldvis;
14634 luke 745
    Rboolean result;
746
 
747
 
748
    PROTECT(topExp = R_CurrentExpr);
52909 luke 749
    PROTECT(oldHStack = R_HandlerStack);
73171 luke 750
    PROTECT(oldRStack = R_RestartStack);
751
    PROTECT(oldRVal = R_ReturnedValue);
752
    oldvis = R_Visible;
52909 luke 753
    R_HandlerStack = R_NilValue;
73171 luke 754
    R_RestartStack = R_NilValue;
14634 luke 755
    saveToplevelContext = R_ToplevelContext;
756
 
757
    begincontext(&thiscontext, CTXT_TOPLEVEL, R_NilValue, R_GlobalEnv,
37654 ripley 758
		 R_BaseEnv, R_NilValue, R_NilValue);
14634 luke 759
    if (SETJMP(thiscontext.cjmpbuf))
760
	result = FALSE;
761
    else {
762
	R_GlobalContext = R_ToplevelContext = &thiscontext;
763
	fun(data);
764
	result = TRUE;
765
    }
766
    endcontext(&thiscontext);
767
 
768
    R_ToplevelContext = saveToplevelContext;
769
    R_CurrentExpr = topExp;
52909 luke 770
    R_HandlerStack = oldHStack;
73171 luke 771
    R_RestartStack = oldRStack;
772
    R_ReturnedValue = oldRVal;
773
    R_Visible = oldvis;
774
    UNPROTECT(4);
14634 luke 775
 
776
    return result;
777
}
17021 duncan 778
 
76368 urbaneks 779
/* Return the current environment. */
780
SEXP R_GetCurrentEnv() {
781
    return R_GlobalContext->sysparent;
782
}
17021 duncan 783
 
784
 
785
/*
786
  This is a simple interface for evaluating R expressions
45446 ripley 787
  from C with a guarantee that one will return to the
40779 ripley 788
  point in the code from which the call was made (if it does
789
  return at all).
17021 duncan 790
  This uses R_TopleveExec to do this.  It is important
45446 ripley 791
  in applications that embed R or wish to make general
17021 duncan 792
  callbacks to R with error handling.
793
 
794
  It is currently hidden with a data structure definition
795
  and C routine visible only here. The R_tryEval() is the
796
  only visible aspect. This can be lifted into the header
797
  files if necessary. (DTL)
40779 ripley 798
 
799
  R_tryEval is in Rinternals.h (so public), but not in the API.
17021 duncan 800
 */
801
typedef struct {
802
    SEXP expression;
803
    SEXP val;
804
    SEXP env;
805
} ProtectedEvalData;
806
 
807
static void
808
protectedEval(void *d)
809
{
810
    ProtectedEvalData *data = (ProtectedEvalData *)d;
811
    SEXP env = R_GlobalEnv;
812
    if(data->env) {
813
	env = data->env;
814
    }
45446 ripley 815
    data->val = eval(data->expression, env);
17021 duncan 816
    PROTECT(data->val);
817
}
818
 
819
SEXP
820
R_tryEval(SEXP e, SEXP env, int *ErrorOccurred)
821
{
25523 luke 822
    Rboolean ok;
823
    ProtectedEvalData data;
17021 duncan 824
 
25523 luke 825
    data.expression = e;
826
    data.val = NULL;
827
    data.env = env;
17021 duncan 828
 
25523 luke 829
    ok = R_ToplevelExec(protectedEval, &data);
830
    if (ErrorOccurred) {
831
	*ErrorOccurred = (ok == FALSE);
832
    }
833
    if (ok == FALSE)
834
	data.val = NULL;
835
    else
836
	UNPROTECT(1);
17021 duncan 837
 
25523 luke 838
    return(data.val);
17021 duncan 839
}
52910 luke 840
 
841
/* Temporary hack to suppress error message printing around a
842
   R_tryEval call for use in methods_list_dispatch.c; should be
843
   replaced once we have a way of establishing error handlers from C
844
   code (probably would want a calling handler if we want to allow
845
   user-defined calling handlers to enter a debugger, for
846
   example). LT */
847
SEXP R_tryEvalSilent(SEXP e, SEXP env, int *ErrorOccurred)
848
{
849
    SEXP val;
850
    Rboolean oldshow = R_ShowErrorMessages;
851
    R_ShowErrorMessages = FALSE;
852
    val = R_tryEval(e, env, ErrorOccurred);
853
    R_ShowErrorMessages = oldshow;
854
    return val;
855
}
64091 luke 856
 
857
SEXP R_ExecWithCleanup(SEXP (*fun)(void *), void *data,
858
		       void (*cleanfun)(void *), void *cleandata)
859
{
860
    RCNTXT cntxt;
861
    SEXP result;
862
 
863
    begincontext(&cntxt, CTXT_CCODE, R_NilValue, R_BaseEnv, R_BaseEnv,
864
		 R_NilValue, R_NilValue);
865
    cntxt.cend = cleanfun;
866
    cntxt.cenddata = cleandata;
867
 
868
    result = fun(data);
869
    cleanfun(cleandata);
870
 
871
    endcontext(&cntxt);
872
    return result;
873
}
73866 luke 874
 
875
 
876
/* Unwind-protect mechanism to support C++ stack unwinding. */
877
 
878
typedef struct {
879
    int jumpmask;
880
    RCNTXT *jumptarget;
881
} unwind_cont_t;
882
 
883
SEXP R_MakeUnwindCont()
884
{
885
    return CONS(R_NilValue, allocVector(RAWSXP, sizeof(unwind_cont_t)));
886
}
887
 
74412 luke 888
#define RAWDATA(x) ((void *) RAW0(x))
73866 luke 889
 
890
void NORET R_ContinueUnwind(SEXP cont)
891
{
892
    SEXP retval = CAR(cont);
74412 luke 893
    unwind_cont_t *u = RAWDATA(CDR(cont));
73866 luke 894
    R_jumpctxt(u->jumptarget, u->jumpmask, retval);
895
}
896
 
897
SEXP R_UnwindProtect(SEXP (*fun)(void *data), void *data,
898
		     void (*cleanfun)(void *data, Rboolean jump),
899
		     void *cleandata, SEXP cont)
900
{
901
    RCNTXT thiscontext;
902
    SEXP result;
903
    Rboolean jump;
904
 
74256 luke 905
    /* Allow simple usage with a NULL continuotion token. This _could_
906
       result in a failure in allocation or exceeding the PROTECT
907
       stack limit before calling fun(), so fun() and cleanfun should
908
       be written accordingly. */
909
    if (cont == NULL) {
910
	PROTECT(cont = R_MakeUnwindCont());
911
	result = R_UnwindProtect(fun, data, cleanfun, cleandata, cont);
912
	UNPROTECT(1);
913
	return result;
914
    }
915
 
73866 luke 916
    begincontext(&thiscontext, CTXT_UNWIND, R_NilValue, R_GlobalEnv,
917
		 R_BaseEnv, R_NilValue, R_NilValue);
918
    if (SETJMP(thiscontext.cjmpbuf)) {
919
	jump = TRUE;
920
	SETCAR(cont, R_ReturnedValue);
74412 luke 921
	unwind_cont_t *u = RAWDATA(CDR(cont));
73866 luke 922
	u->jumpmask = thiscontext.jumpmask;
923
	u->jumptarget = thiscontext.jumptarget;
924
	thiscontext.jumptarget = NULL;
925
    }
926
    else {
927
	result = fun(data);
928
	SETCAR(cont, result);
929
	jump = FALSE;
930
    }
931
    endcontext(&thiscontext);
932
 
933
    cleanfun(cleandata, jump);
934
 
935
    if (jump)
936
	R_ContinueUnwind(cont);	
937
 
938
    return result;
939
}