Coverage Report

Created: 2026-09-14 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/r-source/src/main/envir.c
Line
Count
Source
1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
3
 *  Copyright (C) 1999--2026  The R Core Team.
4
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
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
17
 *  along with this program; if not, a copy is available at
18
 *  https://www.R-project.org/Licenses/
19
 *
20
 *
21
 *
22
 *  Environments:
23
 *
24
 *  All the action of associating values with symbols happens
25
 *  in this code.  An environment is (essentially) a list of
26
 *  environment "frames" of the form
27
 *
28
 *  FRAME(envir) = environment frame
29
 *  ENCLOS(envir) = parent environment
30
 *  HASHTAB(envir) = (optional) hash table
31
 *
32
 *  Each frame is a (tagged) list with
33
 *
34
 *  TAG(item) = symbol
35
 *  CAR(item) = value bound to symbol in this frame
36
 *  CDR(item) = next value on the list
37
 *
38
 *  When the value of a symbol is required, the environment is
39
 *  traversed frame-by-frame until a value is found.
40
 *
41
 *  If a value is not found during the traversal, the symbol's
42
 *  "value" slot is inspected for a value.  This "top-level"
43
 *  environment is where system functions and variables reside.
44
 *
45
 *  Environments with the NO_SPECIAL_SYMBOLS flag set are known to not
46
 *  contain any special symbols, as indicated by the IS_SPECIAL_SYMBOL
47
 *  macro.  Lookup for such a symbol can then bypass this environment
48
 *  without searching it.
49
 */
50
51
/* R 1.8.0: namespaces are no longer experimental, so the following
52
 *  are no longer 'experimental options', but rather three sections
53
 *  describing the API:
54
 *
55
 * NAMESPACES:
56
 *     R_BaseNamespace holds an environment that has R_GlobalEnv as
57
 *     its parent.  This environment does not actually contain any
58
 *     bindings of its own.  Instead, it redirects all fetches and
59
 *     assignments to the SYMVALUE fields of the base (R_BaseEnv)
60
 *     environment.  If evaluation occurs in R_BaseNamespace, then
61
 *     base is searched before R_GlobalEnv.
62
 *
63
 * ENVIRONMENT_LOCKING: Locking an environment prevents new bindings
64
 *     from being created and existing bindings from being removed.
65
 *
66
 * FANCY_BINDINGS: We have binding locking and "active bindings".
67
 *     When a binding is locked, its value cannot be changed.  It may
68
 *     still be removed from the environment if the environment is not
69
 *     locked.
70
 *
71
 *     Active bindings contain a function in their value cell.
72
 *     Getting the value of an active binding calls this function with
73
 *     no arguments and returns the result.  Assigning to an active
74
 *     binding calls this function with one argument, the new value.
75
 *     Active bindings may be useful for mapping external variables,
76
 *     such as C variables or data base entries, to R variables.  They
77
 *     may also be useful for making some globals thread-safe.
78
 *
79
 *     Bindings are marked as locked or active using bits 14 and 15 in
80
 *     their gp fields.  Since the save/load code writes out this
81
 *     field it means the value will be preserved across save/load.
82
 *     But older versions of R will interpret the entire gp field as
83
 *     the MISSING field, which may cause confusion.  If we keep this
84
 *     code, then we will need to make sure that there are no
85
 *     locked/active bindings in workspaces written for older versions
86
 *     of R to read.
87
 *
88
 * LT */
89
90
#ifdef HAVE_CONFIG_H
91
# include <config.h>
92
#endif
93
94
#define R_USE_SIGNALS 1
95
#include <Defn.h>
96
#include <Internal.h>
97
#include <R_ext/ObjectTable.h>
98
99
#define FAST_BASE_CACHE_LOOKUP  /* Define to enable fast lookups of symbols */
100
        /*    in global cache from base environment */
101
102
63.2M
#define IS_USER_DATABASE(rho)  (OBJECT((rho)) && inherits((rho), "UserDefinedDatabase"))
103
104
/* various definitions of macros/functions in Defn.h */
105
106
9.70M
#define FRAME_LOCK_MASK (1<<14)
107
9.70M
#define FRAME_IS_LOCKED(e) (ENVFLAGS(e) & FRAME_LOCK_MASK)
108
330
#define LOCK_FRAME(e) SET_ENVFLAGS(e, ENVFLAGS(e) | FRAME_LOCK_MASK)
109
/*#define UNLOCK_FRAME(e) SET_ENVFLAGS(e, ENVFLAGS(e) & (~ FRAME_LOCK_MASK))*/
110
111
/* use the same bits (15 and 14) in symbols and bindings */
112
static SEXP getActiveValue(SEXP);
113
static R_INLINE SEXP BINDING_VALUE(SEXP b)
114
6.69M
{
115
6.69M
    if (BNDCELL_TAG(b)) {
116
72
  R_expand_binding_value(b);
117
72
  return CAR0(b);
118
72
    }
119
6.69M
    if (IS_ACTIVE_BINDING(b)) return getActiveValue(CAR(b));
120
6.69M
    else return CAR(b);
121
6.69M
}
122
123
12.8M
#define SYMBOL_BINDING_VALUE(s) ((IS_ACTIVE_BINDING(s) ? getActiveValue(SYMVALUE(s)) : SYMVALUE(s)))
124
12
#define SYMBOL_HAS_BINDING(s) (IS_ACTIVE_BINDING(s) || (SYMVALUE(s) != R_UnboundValue))
125
126
644k
#define SET_BINDING_VALUE(b,val) do { \
127
644k
  SEXP __b__ = (b); \
128
644k
  SEXP __val__ = (val); \
129
644k
  if (BINDING_IS_LOCKED(__b__)) \
130
644k
    error(_("cannot change value of locked binding for '%s'"), \
131
0
    CHAR(PRINTNAME(TAG(__b__)))); \
132
644k
  if (IS_ACTIVE_BINDING(__b__)) { \
133
0
    PROTECT(__val__); \
134
0
    setActiveValue(CAR(__b__), __val__); \
135
0
    UNPROTECT(1); \
136
0
   } else \
137
644k
    SET_BNDCELL(__b__, __val__); \
138
644k
} while (0)
139
140
14.6k
#define SET_SYMBOL_BINDING_VALUE(sym, val) do { \
141
14.6k
  SEXP __sym__ = (sym); \
142
14.6k
  SEXP __val__ = (val); \
143
14.6k
  if (BINDING_IS_LOCKED(__sym__)) \
144
14.6k
    error(_("cannot change value of locked binding for '%s'"), \
145
0
    CHAR(PRINTNAME(__sym__))); \
146
14.6k
  if (IS_ACTIVE_BINDING(__sym__)) { \
147
36
    PROTECT(__val__); \
148
36
    setActiveValue(SYMVALUE(__sym__), __val__); \
149
36
    UNPROTECT(1); \
150
36
  } else \
151
14.6k
    SET_SYMVALUE(__sym__, __val__); \
152
14.6k
} while (0)
153
154
static void setActiveValue(SEXP fun, SEXP val)
155
36
{
156
36
    SEXP qfun = lang3(R_DoubleColonSymbol, R_BaseSymbol, R_QuoteSymbol);
157
36
    SEXP arg = lang2(qfun, val);
158
36
    SEXP expr = lang2(fun, arg);
159
36
    PROTECT(expr);
160
36
    eval(expr, R_BaseEnv);
161
36
    UNPROTECT(1);
162
36
}
163
164
static SEXP getActiveValue(SEXP fun)
165
72
{
166
72
    SEXP expr = LCONS(fun, R_NilValue);
167
72
    PROTECT(expr);
168
72
    expr = eval(expr, R_GlobalEnv);
169
72
    UNPROTECT(1);
170
    /* mark unmutable to prevent mutations in complex assignments */
171
72
    MARK_NOT_MUTABLE(expr);
172
72
    return expr;
173
72
}
174
175
/* Macro version of isNull for only the test against R_NilValue */
176
5.83M
#define ISNULL(x) ((x) == R_NilValue)
177
178
/* Function to determine whethr an environment contains special symbols */
179
attribute_hidden Rboolean R_envHasNoSpecialSymbols (SEXP env)
180
5.29M
{
181
5.29M
    SEXP frame;
182
183
5.29M
    if (HASHTAB(env) != R_NilValue)
184
0
  return FALSE;
185
186
18.0M
    for (frame = FRAME(env); frame != R_NilValue; frame = CDR(frame))
187
12.7M
  if (IS_SPECIAL_SYMBOL(TAG(frame)))
188
0
      return FALSE;
189
190
5.29M
    return TRUE;
191
5.29M
}
192
193
/*----------------------------------------------------------------------
194
195
  Hash Tables
196
197
  We use a basic separate chaining algorithm. A hash table consists
198
  of SEXP (vector) which contains a number of SEXPs (lists).
199
200
  The only non-static function is R_NewHashedEnv, which allows code to
201
  request a hashed environment.  All others are static to allow
202
  internal changes of implementation without affecting client code.
203
*/
204
205
5.17M
#define HASHSIZE(x)      ((int) STDVEC_LENGTH(x))
206
271k
#define HASHPRI(x)       ((int) STDVEC_TRUELENGTH(x))
207
3.54k
#define HASHTABLEGROWTHRATE  1.2
208
216
#define HASHMINSIZE      29
209
573k
#define SET_HASHPRI(x,v)     SET_TRUELENGTH(x,v)
210
4.10M
#define HASHCHAIN(table, i)  ((SEXP *) STDVEC_DATAPTR(table))[i]
211
212
335
#define IS_HASHED(x)       (HASHTAB(x) != R_NilValue)
213
214
/*----------------------------------------------------------------------
215
216
  String Hashing
217
218
  This is taken from the second edition of the "Dragon Book" by
219
  Aho, Ullman and Sethi.
220
221
*/
222
223
/* was extern: used in this file and names.c (for the symbol table).
224
225
   This hash function seems to work well enough for symbol tables,
226
   and hash tables get saved as part of environments so changing it
227
   is a major decision.
228
 */
229
attribute_hidden int R_Newhashpjw(const char *s)
230
5.55M
{
231
5.55M
    char *p;
232
5.55M
    unsigned h = 0, g;
233
57.0M
    for (p = (char *) s; *p; p++) {
234
51.5M
  h = (h << 4) + (*p);
235
51.5M
  if ((g = h & 0xf0000000) != 0) {
236
23.0M
      h = h ^ (g >> 24);
237
23.0M
      h = h ^ g;
238
23.0M
  }
239
51.5M
    }
240
5.55M
    return h;
241
5.55M
}
242
243
/*----------------------------------------------------------------------
244
245
  R_HashSet
246
247
  Hashtable set function.  Sets 'symbol' in 'table' to be 'value'.
248
  'hashcode' must be provided by user.  Allocates some memory for list
249
  entries.
250
251
*/
252
253
static void R_HashSet(int hashcode, SEXP symbol, SEXP table, SEXP value,
254
          Rboolean frame_locked)
255
119k
{
256
119k
    SEXP chain;
257
258
    /* Grab the chain from the hashtable */
259
119k
    chain = VECTOR_ELT(table, hashcode);
260
261
    /* Search for the value in the chain */
262
239k
    for (; !ISNULL(chain); chain = CDR(chain))
263
120k
  if (TAG(chain) == symbol) {
264
426
      SET_BINDING_VALUE(chain, value);
265
426
      SET_MISSING(chain, 0);  /* Over-ride for new value */
266
426
      return;
267
426
  }
268
119k
    if (frame_locked)
269
0
  error(_("cannot add bindings to a locked environment"));
270
119k
    if (ISNULL(chain))
271
119k
  SET_HASHPRI(table, HASHPRI(table) + 1);
272
    /* Add the value into the chain */
273
119k
    SET_VECTOR_ELT(table, hashcode, CONS(value, VECTOR_ELT(table, hashcode)));
274
119k
    SET_TAG(VECTOR_ELT(table, hashcode), symbol);
275
119k
    return;
276
119k
}
277
278
279
280
/*----------------------------------------------------------------------
281
282
  R_HashGet
283
284
  Hashtable get function.  Returns 'value' from 'table' indexed by
285
  'symbol'.  'hashcode' must be provided by user.  Returns
286
  'R_UnboundValue' if value is not present.
287
288
*/
289
290
static SEXP R_HashGet(int hashcode, SEXP symbol, SEXP table)
291
4.10M
{
292
4.10M
    SEXP chain;
293
294
    /* Grab the chain from the hashtable */
295
4.10M
    chain = HASHCHAIN(table, hashcode);
296
    /* Retrieve the value from the chain */
297
6.10M
    for (; chain != R_NilValue ; chain = CDR(chain))
298
2.54M
  if (TAG(chain) == symbol) return BINDING_VALUE(chain);
299
    /* If not found */
300
3.55M
    return R_UnboundValue;
301
4.10M
}
302
303
static Rboolean R_HashExists(int hashcode, SEXP symbol, SEXP table)
304
13.4k
{
305
13.4k
    SEXP chain;
306
307
    /* Grab the chain from the hashtable */
308
13.4k
    chain = VECTOR_ELT(table, hashcode);
309
    /* Find the binding in the chain */
310
23.5k
    for (; chain != R_NilValue ; chain = CDR(chain))
311
14.8k
  if (TAG(chain) == symbol) return TRUE;
312
    /* If not found */
313
8.65k
    return FALSE;
314
13.4k
}
315
316
317
318
/*----------------------------------------------------------------------
319
320
  R_HashGetLoc
321
322
  Hashtable get location function. Just like R_HashGet, but returns
323
  location of variable, rather than its value. Returns R_NilValue
324
  if not found.
325
326
*/
327
328
static SEXP R_HashGetLoc(int hashcode, SEXP symbol, SEXP table)
329
171k
{
330
171k
    SEXP chain;
331
332
    /* Grab the chain from the hashtable */
333
171k
    chain = VECTOR_ELT(table, hashcode);
334
    /* Retrieve the value from the chain */
335
233k
    for (; !ISNULL(chain); chain = CDR(chain))
336
200k
  if (TAG(chain) == symbol) return chain;
337
    /* If not found */
338
32.9k
    return R_NilValue;
339
171k
}
340
341
342
343
/*----------------------------------------------------------------------
344
345
  R_NewHashTable
346
347
  Hash table initialisation function.  Creates a table of size 'size'
348
  that increases in size by 'growth_rate' after a threshold is met.
349
350
*/
351
352
static SEXP R_NewHashTable(int size)
353
8.08k
{
354
8.08k
    SEXP table;
355
356
8.08k
    if (size <= 0) size = HASHMINSIZE;
357
358
    /* Allocate hash table in the form of a vector */
359
8.08k
    PROTECT(table = allocVector(VECSXP, size));
360
8.08k
    SET_HASHPRI(table, 0);
361
8.08k
    UNPROTECT(1);
362
8.08k
    return(table);
363
8.08k
}
364
365
/*----------------------------------------------------------------------
366
367
  R_NewHashedEnv
368
369
  Returns a new environment with a hash table initialized with default
370
  size.  The only non-static hash table function.
371
*/
372
373
SEXP R_NewHashedEnv(SEXP enclos, int size)
374
4.44k
{
375
4.44k
    SEXP s;
376
377
4.44k
    PROTECT(enclos);
378
4.44k
    PROTECT(s = NewEnvironment(R_NilValue, R_NilValue, enclos));
379
4.44k
    SET_HASHTAB(s, R_NewHashTable(size));
380
4.44k
    UNPROTECT(2);
381
4.44k
    return s;
382
4.44k
}
383
384
385
/*----------------------------------------------------------------------
386
387
  R_HashDelete
388
389
  Hash table delete function. Symbols are completely removed from the table;
390
  there is no way to mark a symbol as not present without actually removing
391
  it.
392
*/
393
394
static SEXP RemoveFromList(SEXP thing, SEXP list, int *found);
395
396
static void R_HashDelete(int hashcode, SEXP symbol, SEXP env, int *found)
397
12
{
398
12
    int idx;
399
12
    SEXP list, hashtab;
400
401
12
    hashtab = HASHTAB(env);
402
12
    idx = hashcode % HASHSIZE(hashtab);
403
12
    list = RemoveFromList(symbol, VECTOR_ELT(hashtab, idx), found);
404
12
    if (*found) {
405
12
  if (env == R_GlobalEnv)
406
12
      R_DirtyImage = 1;
407
12
  if (list == R_NilValue)
408
12
      SET_HASHPRI(hashtab, HASHPRI(hashtab) - 1);
409
12
  SET_VECTOR_ELT(hashtab, idx, list);
410
12
    }
411
12
}
412
413
414
415
416
/*----------------------------------------------------------------------
417
418
  R_HashResize
419
420
  Hash table resizing function Increase the size of the hash table by
421
  the growth_rate of the table.  The vector is reallocated, however
422
  the lists with in the hash table have their pointers shuffled around
423
  so that they are not reallocated.
424
425
*/
426
427
static SEXP R_HashResize(SEXP table)
428
3.54k
{
429
    /* Do some checking */
430
3.54k
    if (TYPEOF(table) != VECSXP)
431
0
  error("first argument ('table') not of type VECSXP, from R_HashResize");
432
433
    /* This may have to change.  The growth rate should
434
       be independent of the size (not implemented yet) */
435
    /* hash_grow = HASHSIZE(table); */
436
437
    /* Allocate the new hash table */
438
3.54k
    SEXP new_table = R_NewHashTable(1 + (int)(HASHSIZE(table) * HASHTABLEGROWTHRATE));
439
406k
    for (int counter = 0; counter < length(table); counter++) {
440
403k
  SEXP chain = VECTOR_ELT(table, counter);
441
892k
  while (!ISNULL(chain)) {
442
489k
      int new_hashcode = R_Newhashpjw(CHAR(PRINTNAME(TAG(chain)))) %
443
489k
    HASHSIZE(new_table);
444
489k
      SEXP new_chain = VECTOR_ELT(new_table, new_hashcode);
445
      /* If using a primary slot then increase HASHPRI */
446
489k
      if (ISNULL(new_chain))
447
307k
    SET_HASHPRI(new_table, HASHPRI(new_table) + 1);
448
489k
      SEXP tmp_chain = chain;
449
489k
      chain = CDR(chain);
450
489k
      SETCDR(tmp_chain, new_chain);
451
489k
      SET_VECTOR_ELT(new_table, new_hashcode,  tmp_chain);
452
#ifdef MIKE_DEBUG
453
      fprintf(stdout, "HASHSIZE = %d\nHASHPRI = %d\ncounter = %d\nHASHCODE = %d\n",
454
        HASHSIZE(table), HASHPRI(table), counter, new_hashcode);
455
#endif
456
489k
  }
457
403k
    }
458
    /* Some debugging statements */
459
#ifdef MIKE_DEBUG
460
    fprintf(stdout, "Resized O.K.\n");
461
    fprintf(stdout, "Old size: %d, New size: %d\n",
462
      HASHSIZE(table), HASHSIZE(new_table));
463
    fprintf(stdout, "Old pri: %d, New pri: %d\n",
464
      HASHPRI(table), HASHPRI(new_table));
465
#endif
466
3.54k
    return new_table;
467
3.54k
} /* end R_HashResize */
468
469
470
471
/*----------------------------------------------------------------------
472
473
  R_HashSizeCheck
474
475
  Hash table size rechecking function.  Compares the load factor
476
  (size/# of primary slots used)  to a particular threshold value.
477
  Returns true if the table needs to be resized.
478
479
*/
480
481
static int R_HashSizeCheck(SEXP table)
482
271k
{
483
271k
    int resize;
484
271k
    double thresh_val;
485
486
    /* Do some checking */
487
271k
    if (TYPEOF(table) != VECSXP)
488
0
  error("first argument ('table') not of type VECSXP, R_HashSizeCheck");
489
271k
    resize = 0; thresh_val = 0.85;
490
271k
    if ((double)HASHPRI(table) > (double)HASHSIZE(table) * thresh_val)
491
3.54k
  resize = 1;
492
271k
    return resize;
493
271k
}
494
495
496
497
/*----------------------------------------------------------------------
498
499
  R_HashFrame
500
501
  Hashing for environment frames.  This function ensures that the
502
  first frame in the given environment has been hashed.  Ultimately
503
  all enironments should be created in hashed form.  At that point
504
  this function will be redundant.
505
506
*/
507
508
static SEXP R_HashFrame(SEXP rho)
509
84
{
510
84
    int hashcode;
511
84
    SEXP frame, chain, tmp_chain, table;
512
513
    /* Do some checking */
514
84
    if (TYPEOF(rho) != ENVSXP)
515
0
  error("first argument ('table') not of type ENVSXP, from R_HashVector2Hash");
516
84
    table = HASHTAB(rho);
517
84
    frame = FRAME(rho);
518
84
    while (!ISNULL(frame)) {
519
0
  if( !HASHASH(PRINTNAME(TAG(frame))) ) {
520
0
      SET_HASHVALUE(PRINTNAME(TAG(frame)),
521
0
        R_Newhashpjw(CHAR(PRINTNAME(TAG(frame)))));
522
0
      SET_HASHASH(PRINTNAME(TAG(frame)), 1);
523
0
  }
524
0
  hashcode = HASHVALUE(PRINTNAME(TAG(frame))) % HASHSIZE(table);
525
0
  chain = VECTOR_ELT(table, hashcode);
526
  /* If using a primary slot then increase HASHPRI */
527
0
  if (ISNULL(chain)) SET_HASHPRI(table, HASHPRI(table) + 1);
528
0
  tmp_chain = frame;
529
0
  frame = CDR(frame);
530
0
  SETCDR(tmp_chain, chain);
531
0
  SET_VECTOR_ELT(table, hashcode, tmp_chain);
532
0
    }
533
84
    SET_FRAME(rho, R_NilValue);
534
84
    return rho;
535
84
}
536
537
538
/* ---------------------------------------------------------------------
539
540
   R_HashProfile
541
542
   Profiling tool for analyzing hash table performance.  Returns a
543
   three element list with components:
544
545
   size: the total size of the hash table
546
547
   nchains: the number of non-null chains in the table (as reported by
548
      HASHPRI())
549
550
   counts: an integer vector the same length as size giving the length of
551
     each chain (or zero if no chain is present).  This allows
552
     for assessing collisions in the hash table.
553
 */
554
555
static SEXP R_HashProfile(SEXP table)
556
0
{
557
0
    SEXP chain, ans, chain_counts, nms;
558
0
    int i, count;
559
560
0
    PROTECT(ans = allocVector(VECSXP, 3));
561
0
    PROTECT(nms = allocVector(STRSXP, 3));
562
0
    SET_STRING_ELT(nms, 0, mkChar("size"));    /* size of hashtable */
563
0
    SET_STRING_ELT(nms, 1, mkChar("nchains")); /* number of non-null chains */
564
0
    SET_STRING_ELT(nms, 2, mkChar("counts"));  /* length of each chain */
565
0
    setAttrib(ans, R_NamesSymbol, nms);
566
0
    UNPROTECT(1);
567
568
0
    SET_VECTOR_ELT(ans, 0, ScalarInteger(length(table)));
569
0
    SET_VECTOR_ELT(ans, 1, ScalarInteger(HASHPRI(table)));
570
571
0
    PROTECT(chain_counts = allocVector(INTSXP, length(table)));
572
0
    for (i = 0; i < length(table); i++) {
573
0
  chain = VECTOR_ELT(table, i);
574
0
  count = 0;
575
0
  for (; chain != R_NilValue ; chain = CDR(chain)) {
576
0
      count++;
577
0
  }
578
0
  INTEGER(chain_counts)[i] = count;
579
0
    }
580
581
0
    SET_VECTOR_ELT(ans, 2, chain_counts);
582
583
0
    UNPROTECT(2);
584
0
    return ans;
585
0
}
586
587
588
589
/*----------------------------------------------------------------------
590
591
  Environments
592
593
  The following code implements variable searching for environments.
594
595
*/
596
597
598
/*----------------------------------------------------------------------
599
600
  InitGlobalEnv
601
602
  Create the initial global environment.  The global environment is
603
  no longer a linked list of environment frames.  Instead it is a
604
  vector of environments which is searched from beginning to end.
605
606
  Note that only the first frame of each of these environments is
607
  searched.  This is intended to make it possible to implement
608
  namespaces at some (indeterminate) point in the future.
609
610
  We hash the initial environment.  100 is a magic number discovered
611
  by Ross.  Change it if you feel inclined.
612
613
*/
614
615
#define USE_GLOBAL_CACHE
616
#ifdef USE_GLOBAL_CACHE  /* NB leave in place: see below */
617
/* Global variable caching.  A cache is maintained in a hash table,
618
   R_GlobalCache.  The entry values are either R_UnboundValue (a
619
   flushed cache entry), the binding LISTSXP cell from the environment
620
   containing the binding found in a search from R_GlobalEnv, or a
621
   symbol if the globally visible binding lives in the base package.
622
   The cache for a variable is flushed if a new binding for it is
623
   created in a global frame or if the variable is removed from any
624
   global frame.
625
626
   Symbols in the global cache with values from the base environment
627
   are flagged with BASE_SYM_CACHED, so that their value can be
628
   returned immediately without needing to look in the hash table.
629
   They must still have entries in the hash table, however, so that
630
   they can be flushed as needed.
631
632
   To make sure the cache is valid, all binding creations and removals
633
   from global frames must go through the interface functions in this
634
   file.
635
636
   Initially only the R_GlobalEnv frame is a global frame.  Additional
637
   global frames can only be created by attach.  All other frames are
638
   considered local.  Whether a frame is local or not is recorded in
639
   the highest order bit of the ENVFLAGS field (the gp field of
640
   sxpinfo).
641
642
   It is possible that the benefit of caching may be significantly
643
   reduced if we introduce namespace management.  Since maintaining
644
   cache integrity is a bit tricky and since it might complicate
645
   threading a bit (I'm not sure it will but it needs to be thought
646
   through if nothing else) it might make sense to remove caching at
647
   that time.  To make that easier, the ifdef's should probably be
648
   left in place.
649
650
   L. T. */
651
652
10.2M
#define GLOBAL_FRAME_MASK (1<<15)
653
10.2M
#define IS_GLOBAL_FRAME(e) (ENVFLAGS(e) & GLOBAL_FRAME_MASK)
654
#define MARK_AS_GLOBAL_FRAME(e) \
655
96
  SET_ENVFLAGS(e, ENVFLAGS(e) | GLOBAL_FRAME_MASK)
656
#define MARK_AS_LOCAL_FRAME(e) \
657
0
  SET_ENVFLAGS(e, ENVFLAGS(e) & (~ GLOBAL_FRAME_MASK))
658
659
12
#define INITIAL_CACHE_SIZE 1000
660
661
static SEXP R_GlobalCache, R_GlobalCachePreserve;
662
#endif
663
static SEXP R_BaseNamespaceName;
664
static SEXP R_NamespaceSymbol;
665
666
attribute_hidden void InitBaseEnv(void)
667
12
{
668
12
    R_EmptyEnv = NewEnvironment(R_NilValue, R_NilValue, R_NilValue);
669
12
    R_BaseEnv = NewEnvironment(R_NilValue, R_NilValue, R_EmptyEnv);
670
12
}
671
672
attribute_hidden void InitGlobalEnv(void)
673
12
{
674
12
    R_NamespaceSymbol = install(".__NAMESPACE__.");
675
676
12
    R_GlobalEnv = R_NewHashedEnv(R_BaseEnv, 0);
677
12
    R_MethodsNamespace = R_GlobalEnv; // so it is initialized.
678
#ifdef NEW_CODE /* Not used */
679
    HASHTAB(R_GlobalEnv) = R_NewHashTable(100);
680
#endif
681
12
#ifdef USE_GLOBAL_CACHE
682
12
    MARK_AS_GLOBAL_FRAME(R_GlobalEnv);
683
12
    R_GlobalCache = R_NewHashTable(INITIAL_CACHE_SIZE);
684
12
    R_GlobalCachePreserve = CONS(R_GlobalCache, R_NilValue);
685
12
    R_PreserveObject(R_GlobalCachePreserve);
686
12
#endif
687
12
    R_BaseNamespace = NewEnvironment(R_NilValue, R_NilValue, R_GlobalEnv);
688
12
    R_PreserveObject(R_BaseNamespace);
689
12
    SET_SYMVALUE(install(".BaseNamespaceEnv"), R_BaseNamespace);
690
12
    R_BaseNamespaceName = ScalarString(mkChar("base"));
691
12
    R_PreserveObject(R_BaseNamespaceName);
692
12
    R_NamespaceRegistry = R_NewHashedEnv(R_NilValue, 0);
693
12
    R_PreserveObject(R_NamespaceRegistry);
694
12
    defineVar(R_BaseSymbol, R_BaseNamespace, R_NamespaceRegistry);
695
    /**** needed to properly initialize the base namespace */
696
12
}
697
698
#ifdef USE_GLOBAL_CACHE
699
static int hashIndex(SEXP symbol, SEXP table)
700
33.4k
{
701
33.4k
    SEXP c = PRINTNAME(symbol);
702
33.4k
    if( !HASHASH(c) ) {
703
0
  SET_HASHVALUE(c, R_Newhashpjw(CHAR(c)));
704
0
  SET_HASHASH(c, 1);
705
0
    }
706
33.4k
    return HASHVALUE(c) % HASHSIZE(table);
707
33.4k
}
708
709
static void R_FlushGlobalCache(SEXP sym)
710
31.4k
{
711
31.4k
    SEXP entry = R_HashGetLoc(hashIndex(sym, R_GlobalCache), sym,
712
31.4k
            R_GlobalCache);
713
31.4k
    if (entry != R_NilValue) {
714
0
  SETCAR(entry, R_UnboundValue);
715
0
#ifdef FAST_BASE_CACHE_LOOKUP
716
0
  UNSET_BASE_SYM_CACHED(sym);
717
0
#endif
718
0
    }
719
31.4k
}
720
721
static void R_FlushGlobalCacheFromTable(SEXP table)
722
84
{
723
84
    int i, size;
724
84
    SEXP chain;
725
84
    size = HASHSIZE(table);
726
2.52k
    for (i = 0; i < size; i++) {
727
2.43k
  for (chain = VECTOR_ELT(table, i); chain != R_NilValue; chain = CDR(chain))
728
0
      R_FlushGlobalCache(TAG(chain));
729
2.43k
    }
730
84
}
731
732
/**
733
 Flush the cache based on the names provided by the user defined
734
 table, specifically returned from calling objects() for that
735
 table.
736
 */
737
static void R_FlushGlobalCacheFromUserTable(SEXP udb)
738
0
{
739
0
    int n, i;
740
0
    R_ObjectTable *tb;
741
0
    SEXP names;
742
0
    tb = (R_ObjectTable*) R_ExternalPtrAddr(udb);
743
0
    names = tb->objects(tb);
744
0
    n = length(names);
745
0
    for(i = 0; i < n ; i++)
746
0
  R_FlushGlobalCache(Rf_installTrChar(STRING_ELT(names,i)));
747
0
}
748
749
static void R_AddGlobalCache(SEXP symbol, SEXP place)
750
48
{
751
48
    int oldpri = HASHPRI(R_GlobalCache);
752
48
    R_HashSet(hashIndex(symbol, R_GlobalCache), symbol, R_GlobalCache, place,
753
48
        FALSE);
754
48
#ifdef FAST_BASE_CACHE_LOOKUP
755
48
    if (symbol == place)
756
46
  SET_BASE_SYM_CACHED(symbol);
757
2
    else
758
2
  UNSET_BASE_SYM_CACHED(symbol);
759
48
#endif
760
48
    if (oldpri != HASHPRI(R_GlobalCache) &&
761
48
  HASHPRI(R_GlobalCache) > 0.85 * HASHSIZE(R_GlobalCache)) {
762
0
  R_GlobalCache = R_HashResize(R_GlobalCache);
763
0
  SETCAR(R_GlobalCachePreserve, R_GlobalCache);
764
0
    }
765
48
}
766
767
static SEXP R_GetGlobalCacheLoc(SEXP symbol)
768
1.95k
{
769
1.95k
#ifdef FAST_BASE_CACHE_LOOKUP
770
1.95k
    if (BASE_SYM_CACHED(symbol))
771
0
  return symbol;
772
1.95k
#endif
773
774
1.95k
    return R_HashGet(hashIndex(symbol, R_GlobalCache), symbol, R_GlobalCache);
775
1.95k
}
776
#endif /* USE_GLOBAL_CACHE */
777
778
779
/*----------------------------------------------------------------------
780
  R_GetBindingType
781
*/
782
783
/* Unwrap nested promises to the innermost one.
784
   Sets `*forced` to TRUE if the innermost promise has been evaluated.
785
   Uses Floyd's cycle detection to guard against promise loops. */
786
static SEXP promiseUnwrap(SEXP x, Rboolean *forced)
787
0
{
788
0
    SEXP slow = x;
789
0
    Rboolean advance_slow = FALSE;
790
0
    while (TRUE) {
791
0
  SEXP code = PRCODE(x);
792
0
  if (TYPEOF(code) != PROMSXP) {
793
0
      *forced = PROMISE_IS_EVALUATED(x);
794
0
      return x;
795
0
  }
796
797
0
  x = code;
798
0
  if (x == slow)
799
0
      error(_("cycle detected in promise chain"));
800
801
0
  if (advance_slow)
802
0
      slow = PRCODE(slow);
803
0
  advance_slow = !advance_slow;
804
0
    }
805
0
}
806
807
static R_BindingType_t BINDING_TYPE(SEXP cell)
808
0
{
809
0
    if (BNDCELL_TAG(cell))
810
  // avoid expanding immediate values
811
0
        return R_BindingTypeValue;
812
0
    else if (IS_ACTIVE_BINDING(cell))
813
0
        return R_BindingTypeActive;
814
0
    else {
815
0
  SEXP value = CAR(cell);
816
0
  if (value == R_MissingArg)
817
0
      return R_BindingTypeMissing;
818
0
  else if (TYPEOF(value) == PROMSXP) {
819
0
      Rboolean forced;
820
0
      promiseUnwrap(value, &forced);
821
0
      if (forced)
822
0
    return R_BindingTypeForced;
823
0
      else
824
0
    return R_BindingTypeDelayed;
825
0
  }
826
0
  else
827
0
      return R_BindingTypeValue;
828
0
    }
829
0
}
830
831
static R_BindingType_t SYMBOL_BINDING_TYPE(SEXP cell)
832
0
{
833
0
    if (IS_ACTIVE_BINDING(cell))
834
0
        return R_BindingTypeActive;
835
836
0
    SEXP value = SYMVALUE(cell);
837
0
    if (value == R_UnboundValue)
838
0
  return R_BindingTypeUnbound;
839
840
    /* Shouldn't happen but for completeness */
841
0
    if (value == R_MissingArg)
842
0
  return R_BindingTypeMissing;
843
844
    /* There really shouldn't be any promise chains here but we unwrap
845
       for consistency with BINDING_TYPE */
846
0
    if (TYPEOF(value) == PROMSXP) {
847
0
  Rboolean forced;
848
0
  promiseUnwrap(value, &forced);
849
0
  if (forced)
850
0
      return R_BindingTypeForced;
851
0
  else
852
0
      return R_BindingTypeDelayed;
853
0
    }
854
855
0
    return R_BindingTypeValue;
856
0
}
857
858
attribute_hidden
859
R_BindingType_t R_GetVarLocType(R_varloc_t vl)
860
0
{
861
0
    SEXP cell = vl.cell;
862
0
    if (cell == NULL || cell == R_UnboundValue)
863
0
        return R_BindingTypeUnbound;
864
0
    else if (TYPEOF(cell) == SYMSXP)
865
0
  return SYMBOL_BINDING_TYPE(cell);
866
0
    else
867
0
  return BINDING_TYPE(cell);
868
0
}
869
870
static R_varloc_t R_findVarLocInFrameCheck(SEXP env, SEXP sym)
871
0
{
872
0
    if (TYPEOF(sym) != SYMSXP)
873
0
  error(_("not a symbol"));
874
0
    if (TYPEOF(env) != ENVSXP)
875
0
  error(_("not an environment"));
876
0
    return R_findVarLocInFrame(env, sym);
877
0
}
878
879
0
R_BindingType_t R_GetBindingType(SEXP sym, SEXP env) {
880
0
    R_varloc_t loc = R_findVarLocInFrameCheck(env, sym);
881
0
    return R_GetVarLocType(loc);
882
0
}
883
884
attribute_hidden SEXP do_bindingType(SEXP call, SEXP op, SEXP args, SEXP rho)
885
0
{
886
0
    checkArity(op, args);
887
0
    SEXP sym = CAR(args);
888
0
    SEXP env = CADR(args);
889
0
    switch(R_GetBindingType(sym, env)) {
890
0
    case R_BindingTypeUnbound: return mkString("unbound");
891
0
    case R_BindingTypeValue: return mkString("value");
892
0
    case R_BindingTypeMissing: return mkString("missing");
893
0
    case R_BindingTypeDelayed: return mkString("delayed");
894
0
    case R_BindingTypeForced: return mkString("forced");
895
0
    case R_BindingTypeActive: return mkString("active");
896
0
    default: error("unknown binding type; should not happen");
897
0
    }
898
0
}
899
900
attribute_hidden
901
SEXP do_delayedBindingExpr(SEXP call, SEXP op, SEXP args, SEXP rho)
902
0
{
903
0
    checkArity(op, args);
904
0
    SEXP sym = CAR(args);
905
0
    SEXP env = CADR(args);
906
0
    return R_DelayedBindingExpression(sym, env);
907
0
}
908
909
attribute_hidden
910
SEXP do_delayedBindingEnv(SEXP call, SEXP op, SEXP args, SEXP rho)
911
0
{
912
0
    checkArity(op, args);
913
0
    SEXP sym = CAR(args);
914
0
    SEXP env = CADR(args);
915
0
    return R_DelayedBindingEnvironment(sym, env);
916
0
}
917
918
attribute_hidden
919
SEXP do_forcedBindingExpr(SEXP call, SEXP op, SEXP args, SEXP rho)
920
0
{
921
0
    checkArity(op, args);
922
0
    SEXP sym = CAR(args);
923
0
    SEXP env = CADR(args);
924
0
    return R_ForcedBindingExpression(sym, env);
925
0
}
926
927
928
/*----------------------------------------------------------------------
929
930
  unbindVar
931
932
  Remove a value from an environment. This happens only in the frame
933
  of the specified environment.
934
935
  FIXME ? should this also unbind the symbol value slot when rho is
936
  R_BaseEnv.
937
  This is only called from eval.c in applydefine and bcEval
938
  (and applydefine only works for unhashed environments, so not base).
939
*/
940
941
static SEXP RemoveFromList(SEXP thing, SEXP list, int *found)
942
25.7k
{
943
25.7k
    if (list == R_NilValue) {
944
0
  *found = 0;
945
0
  return R_NilValue;
946
0
    }
947
25.7k
    else if (TAG(list) == thing) {
948
25.6k
  *found = 1;
949
25.6k
  SET_BNDCELL(list, R_UnboundValue); /* in case binding is cached */
950
25.6k
  LOCK_BINDING(list);                /* in case binding is cached */
951
25.6k
  SEXP rest = CDR(list);
952
25.6k
  SETCDR(list, R_NilValue);          /* to fix refcnt on 'rest' */
953
25.6k
  return rest;
954
25.6k
    }
955
97
    else {
956
97
  SEXP last = list;
957
97
  SEXP next = CDR(list);
958
97
  while (next != R_NilValue) {
959
97
      if (TAG(next) == thing) {
960
97
    *found = 1;
961
97
    SETCAR(next, R_UnboundValue); /* in case binding is cached */
962
97
    LOCK_BINDING(next);           /* in case binding is cached */
963
97
    SETCDR(last, CDR(next));
964
97
    SETCDR(next, R_NilValue);     /* to fix refcnt on 'list' */
965
97
    return list;
966
97
      }
967
0
      else {
968
0
    last = next;
969
0
    next = CDR(next);
970
0
      }
971
97
  }
972
0
  *found = 0;
973
0
  return list;
974
97
    }
975
25.7k
}
976
977
attribute_hidden void unbindVar(SEXP symbol, SEXP rho)
978
25.7k
{
979
25.7k
    int hashcode;
980
25.7k
    int found;
981
25.7k
    SEXP c;
982
983
25.7k
    if (rho == R_BaseNamespace)
984
0
  error(_("cannot unbind in the base namespace"));
985
25.7k
    if (rho == R_BaseEnv)
986
0
  error(_("unbind in the base environment is unimplemented"));
987
25.7k
    if (FRAME_IS_LOCKED(rho))
988
0
  error(_("cannot remove bindings from a locked environment"));
989
25.7k
    if (HASHTAB(rho) == R_NilValue) {
990
25.7k
  SEXP list;
991
25.7k
  list = RemoveFromList(symbol, FRAME(rho), &found);
992
25.7k
  if (found) {
993
25.7k
      if (rho == R_GlobalEnv) R_DirtyImage = 1;
994
25.7k
      SET_FRAME(rho, list);
995
25.7k
#ifdef USE_GLOBAL_CACHE
996
25.7k
      if (IS_GLOBAL_FRAME(rho))
997
0
    R_FlushGlobalCache(symbol);
998
25.7k
#endif
999
25.7k
  }
1000
25.7k
    }
1001
0
    else {
1002
  /* This branch is used e.g. via sys.source, utils::data */
1003
0
  c = PRINTNAME(symbol);
1004
0
  if( !HASHASH(c) ) {
1005
0
      SET_HASHVALUE(c, R_Newhashpjw(CHAR(c)));
1006
0
      SET_HASHASH(c, 1);
1007
0
  }
1008
0
  hashcode = HASHVALUE(c) % HASHSIZE(HASHTAB(rho));
1009
0
  R_HashDelete(hashcode, symbol, rho, &found);
1010
0
#ifdef USE_GLOBAL_CACHE
1011
0
  if (found && IS_GLOBAL_FRAME(rho))
1012
0
       R_FlushGlobalCache(symbol);
1013
0
#endif
1014
0
    }
1015
25.7k
}
1016
1017
1018
1019
/*----------------------------------------------------------------------
1020
1021
  findVarLocInFrame
1022
1023
  Look up the location of the value of a symbol in a
1024
  single environment frame.  Almost like R_findVarInFrame, but
1025
  does not return the value. R_NilValue if not found.
1026
1027
  Callers set *canCache = TRUE or NULL
1028
*/
1029
1030
static SEXP findVarLocInFrame(SEXP rho, SEXP symbol, Rboolean *canCache)
1031
22.6M
{
1032
22.6M
    int hashcode;
1033
22.6M
    SEXP frame, c;
1034
1035
22.6M
    if (rho == R_BaseEnv || rho == R_BaseNamespace)
1036
84.4k
  return (SYMVALUE(symbol) == R_UnboundValue) ? R_NilValue : symbol;
1037
1038
22.5M
    if (rho == R_EmptyEnv)
1039
0
  return R_NilValue;
1040
1041
22.5M
    if(IS_USER_DATABASE(rho)) {
1042
0
  R_ObjectTable *table;
1043
0
  SEXP val, tmp = R_NilValue;
1044
0
  table = (R_ObjectTable *) R_ExternalPtrAddr(HASHTAB(rho));
1045
  /* Better to use exists() here if we don't actually need the value! */
1046
0
  val = table->get(CHAR(PRINTNAME(symbol)), canCache, table);
1047
0
  if(val != R_UnboundValue) {
1048
      /* The result should probably be identified as being from
1049
         a user database, or maybe use an active binding
1050
         mechanism to allow setting a new value to get back to
1051
         the data base. */
1052
0
      tmp = allocSExp(LISTSXP);
1053
0
      SETCAR(tmp, val);
1054
0
      SET_TAG(tmp, symbol);
1055
      /* If the database has a canCache method, then call that.
1056
         Otherwise, we believe the setting for canCache. */
1057
0
      if(canCache && table->canCache) {
1058
0
    PROTECT(tmp);
1059
0
    *canCache = table->canCache(CHAR(PRINTNAME(symbol)), table);
1060
0
    UNPROTECT(1);
1061
0
      }
1062
0
      MARK_NOT_MUTABLE(val); /* to keep complex assignment code sane */
1063
0
  }
1064
0
  return(tmp);
1065
0
    }
1066
1067
22.5M
    if (HASHTAB(rho) == R_NilValue) {
1068
22.3M
  frame = FRAME(rho);
1069
58.9M
  while (frame != R_NilValue && TAG(frame) != symbol)
1070
36.5M
      frame = CDR(frame);
1071
22.3M
  return frame;
1072
22.3M
    }
1073
140k
    else {
1074
140k
  c = PRINTNAME(symbol);
1075
140k
  if( !HASHASH(c) ) {
1076
0
      SET_HASHVALUE(c, R_Newhashpjw(CHAR(c)));
1077
0
      SET_HASHASH(c,  1);
1078
0
  }
1079
140k
  hashcode = HASHVALUE(c) % HASHSIZE(HASHTAB(rho));
1080
  /* Will return 'R_NilValue' if not found */
1081
140k
  return R_HashGetLoc(hashcode, symbol, HASHTAB(rho));
1082
140k
    }
1083
22.5M
}
1084
1085
1086
/*
1087
  External version and accessor functions. Returned value is cast as
1088
  an opaque pointer to insure it is only used by routines in this
1089
  group.  This allows the implementation to be changed without needing
1090
  to change other files.
1091
*/
1092
1093
R_varloc_t R_findVarLocInFrame(SEXP rho, SEXP symbol)
1094
21.7M
{
1095
21.7M
    SEXP binding = findVarLocInFrame(rho, symbol, NULL);
1096
21.7M
    R_varloc_t val;
1097
21.7M
    val.cell = binding == R_NilValue ? NULL : binding;
1098
21.7M
    return val;
1099
21.7M
}
1100
1101
attribute_hidden
1102
SEXP R_GetVarLocValue(R_varloc_t vl)
1103
323k
{
1104
323k
    SEXP cell = vl.cell;
1105
323k
    if (cell == NULL || cell == R_UnboundValue)
1106
0
  return R_UnboundValue;
1107
323k
    else if (TYPEOF(cell) == SYMSXP)
1108
84.4k
  return SYMBOL_BINDING_VALUE(cell);
1109
238k
    else return BINDING_VALUE(cell);
1110
323k
}
1111
1112
attribute_hidden
1113
SEXP R_GetVarLocSymbol(R_varloc_t vl)
1114
0
{
1115
0
    return TAG(vl.cell);
1116
0
}
1117
1118
/* used in methods */
1119
Rboolean R_GetVarLocMISSING(R_varloc_t vl)
1120
0
{
1121
0
    return MISSING(vl.cell);
1122
0
}
1123
1124
attribute_hidden
1125
void R_SetVarLocValue(R_varloc_t vl, SEXP value)
1126
25.7k
{
1127
25.7k
    SET_BINDING_VALUE(vl.cell, value);
1128
25.7k
}
1129
1130
1131
/*----------------------------------------------------------------------
1132
1133
  R_findVarInFrame
1134
1135
  Look up the value of a symbol in a single environment frame.  This
1136
  is the basic building block of all variable lookups.
1137
1138
  It is important that this be as efficient as possible.
1139
1140
  The final argument is usually TRUE and indicates whether the
1141
  lookup is being done in order to get the value (TRUE) or
1142
  simply to check whether there is a value bound to the specified
1143
  symbol in this frame (FALSE).  This is used for get() and exists().
1144
*/
1145
1146
// In Rinternals.h
1147
SEXP findVarInFrame3(SEXP rho, SEXP symbol, Rboolean doGet)
1148
39.0M
{
1149
39.0M
    int hashcode;
1150
39.0M
    SEXP frame, c;
1151
1152
39.0M
    if (TYPEOF(rho) == NILSXP)
1153
0
  error(_("use of NULL environment is defunct"));
1154
1155
39.0M
    if (rho == R_BaseNamespace || rho == R_BaseEnv)
1156
12.7M
  return SYMBOL_BINDING_VALUE(symbol);
1157
1158
26.3M
    if (rho == R_EmptyEnv)
1159
0
  return R_UnboundValue;
1160
1161
26.3M
    if(IS_USER_DATABASE(rho)) {
1162
  /* Use the objects function pointer for this symbol. */
1163
0
  R_ObjectTable *table;
1164
0
  SEXP val = R_UnboundValue;
1165
0
  table = (R_ObjectTable *) R_ExternalPtrAddr(HASHTAB(rho));
1166
0
  if(table->active) {
1167
0
      if(doGet)
1168
0
    val = table->get(CHAR(PRINTNAME(symbol)), NULL, table);
1169
0
      else {
1170
0
    if(table->exists(CHAR(PRINTNAME(symbol)), NULL, table))
1171
0
        val = table->get(CHAR(PRINTNAME(symbol)), NULL, table);
1172
0
    else
1173
0
        val = R_UnboundValue;
1174
0
      }
1175
0
      MARK_NOT_MUTABLE(val); /* to keep complex assignment code sane */
1176
0
  }
1177
0
  return(val);
1178
26.3M
    } else if (HASHTAB(rho) == R_NilValue) {
1179
22.2M
  frame = FRAME(rho);
1180
123M
  while (frame != R_NilValue) {
1181
106M
      if (TAG(frame) == symbol)
1182
5.90M
    return BINDING_VALUE(frame);
1183
100M
      frame = CDR(frame);
1184
100M
  }
1185
22.2M
    }
1186
4.10M
    else {
1187
4.10M
  c = PRINTNAME(symbol);
1188
4.10M
  if( !HASHASH(c) ) {
1189
0
      SET_HASHVALUE(c, R_Newhashpjw(CHAR(c)));
1190
0
      SET_HASHASH(c, 1);
1191
0
  }
1192
4.10M
  hashcode = HASHVALUE(c) % HASHSIZE(HASHTAB(rho));
1193
  /* Will return 'R_UnboundValue' if not found */
1194
4.10M
  return(R_HashGet(hashcode, symbol, HASHTAB(rho)));
1195
4.10M
    }
1196
16.3M
    return R_UnboundValue;
1197
26.3M
}
1198
1199
/* This variant of findVarinFrame3 is needed to avoid running active
1200
   binding functions in calls to exists() with mode = "any" */
1201
Rboolean R_existsVarInFrame(SEXP rho, SEXP symbol)
1202
4.13M
{
1203
4.13M
    int hashcode;
1204
4.13M
    SEXP frame, c;
1205
1206
4.13M
    if (TYPEOF(rho) == NILSXP)
1207
0
  error(_("use of NULL environment is defunct"));
1208
1209
4.13M
    if (rho == R_BaseNamespace || rho == R_BaseEnv)
1210
12
  return SYMBOL_HAS_BINDING(symbol);
1211
1212
4.13M
    if (rho == R_EmptyEnv)
1213
0
  return FALSE;
1214
1215
4.13M
    if(IS_USER_DATABASE(rho)) {
1216
  /* Use the objects function pointer for this symbol. */
1217
0
  R_ObjectTable *table;
1218
0
  Rboolean val = FALSE;
1219
0
  table = (R_ObjectTable *) R_ExternalPtrAddr(HASHTAB(rho));
1220
0
  if(table->active) {
1221
0
      if(table->exists(CHAR(PRINTNAME(symbol)), NULL, table))
1222
0
    val = TRUE;
1223
0
      else
1224
0
    val = FALSE;
1225
0
  }
1226
0
  return(val);
1227
4.13M
    } else if (HASHTAB(rho) == R_NilValue) {
1228
4.12M
  frame = FRAME(rho);
1229
27.3M
  while (frame != R_NilValue) {
1230
23.2M
      if (TAG(frame) == symbol)
1231
0
    return TRUE;
1232
23.2M
      frame = CDR(frame);
1233
23.2M
  }
1234
4.12M
    }
1235
13.4k
    else {
1236
13.4k
  c = PRINTNAME(symbol);
1237
13.4k
  if( !HASHASH(c) ) {
1238
0
      SET_HASHVALUE(c, R_Newhashpjw(CHAR(c)));
1239
0
      SET_HASHASH(c, 1);
1240
0
  }
1241
13.4k
  hashcode = HASHVALUE(c) % HASHSIZE(HASHTAB(rho));
1242
13.4k
  return R_HashExists(hashcode, symbol, HASHTAB(rho));
1243
13.4k
    }
1244
4.12M
    return FALSE;
1245
4.13M
}
1246
1247
attribute_hidden SEXP R_findVarInFrame(SEXP rho, SEXP symbol)
1248
38.8M
{
1249
38.8M
    return findVarInFrame3(rho, symbol, TRUE);
1250
38.8M
}
1251
1252
SEXP findVarInFrame(SEXP rho, SEXP symbol)
1253
11.4k
{
1254
11.4k
    return R_findVarInFrame(rho, symbol);
1255
11.4k
}
1256
1257
/*----------------------------------------------------------------------
1258
1259
  readS3VarsFromFrame
1260
1261
  Reads the S3 meta-variables from a given (single) frame.
1262
  R_UnboundValue marks that respective variable is not present.
1263
  This function is optimized to be fast in the common case when the
1264
  S3 meta-variables are in the expected order and that the frame is
1265
  represented by a pairlist.
1266
*/
1267
1268
attribute_hidden
1269
void readS3VarsFromFrame(SEXP rho,
1270
    SEXP *dotGeneric, SEXP *dotGroup, SEXP *dotClass, SEXP *dotMethod,
1271
327
    SEXP *dotGenericCallEnv, SEXP *dotGenericDefEnv) {
1272
1273
327
    if (TYPEOF(rho) == NILSXP ||
1274
327
  rho == R_BaseNamespace || rho == R_BaseEnv || rho == R_EmptyEnv ||
1275
327
  IS_USER_DATABASE(rho) || HASHTAB(rho) != R_NilValue) goto slowpath;
1276
1277
327
    SEXP frame = FRAME(rho);
1278
1279
    /*
1280
    This code speculates there is a specific order of S3 meta-variables.  It
1281
    holds in most (perhaps all non-fabricated) cases.  If at any time this
1282
    ceased to hold, this code will fall back to the slowpath, which may be
1283
    slow but still correct.
1284
    */
1285
1286
327
    for(;TAG(frame) != R_dot_Generic; frame = CDR(frame))
1287
0
  if (frame == R_NilValue) goto slowpath;
1288
327
    *dotGeneric = BINDING_VALUE(frame);
1289
327
    frame = CDR(frame);
1290
1291
327
    if (TAG(frame) != R_dot_Class) goto slowpath;
1292
327
    *dotClass = BINDING_VALUE(frame);
1293
327
    frame = CDR(frame);
1294
1295
327
    if (TAG(frame) != R_dot_Method) goto slowpath;
1296
327
    *dotMethod = BINDING_VALUE(frame);
1297
327
    frame = CDR(frame);
1298
1299
327
    if (TAG(frame) != R_dot_Group) goto slowpath;
1300
327
    *dotGroup = BINDING_VALUE(frame);
1301
327
    frame = CDR(frame);
1302
1303
327
    if (TAG(frame) != R_dot_GenericCallEnv) goto slowpath;
1304
327
    *dotGenericCallEnv = BINDING_VALUE(frame);
1305
327
    frame = CDR(frame);
1306
1307
327
    if (TAG(frame) != R_dot_GenericDefEnv) goto slowpath;
1308
327
    *dotGenericDefEnv = BINDING_VALUE(frame);
1309
1310
327
    return;
1311
1312
0
slowpath:
1313
    /* fall back to the slow but general implementation */
1314
1315
0
    *dotGeneric = R_findVarInFrame(rho, R_dot_Generic);
1316
0
    *dotClass = R_findVarInFrame(rho, R_dot_Class);
1317
0
    *dotMethod = R_findVarInFrame(rho, R_dot_Method);
1318
0
    *dotGroup = R_findVarInFrame(rho, R_dot_Group);
1319
0
    *dotGenericCallEnv = R_findVarInFrame(rho, R_dot_GenericCallEnv);
1320
0
    *dotGenericDefEnv = R_findVarInFrame(rho, R_dot_GenericDefEnv);
1321
0
}
1322
1323
1324
/*----------------------------------------------------------------------
1325
1326
  findVar
1327
1328
  Look up a symbol in an environment.
1329
1330
*/
1331
1332
#ifdef USE_GLOBAL_CACHE
1333
/* findGlobalVar searches for a symbol value starting at R_GlobalEnv,
1334
   so the cache can be used. */
1335
static SEXP findGlobalVarLoc(SEXP symbol)
1336
1.95k
{
1337
1.95k
    SEXP vl, rho;
1338
1.95k
    Rboolean canCache = TRUE;
1339
1.95k
    vl = R_GetGlobalCacheLoc(symbol);
1340
1.95k
    if (vl != R_UnboundValue)
1341
1.89k
  return vl;
1342
400
    for (rho = R_GlobalEnv; rho != R_EmptyEnv; rho = ENCLOS(rho)) {
1343
400
  if (rho != R_BaseEnv) { /* we won't have R_BaseNamespace */
1344
342
      vl = findVarLocInFrame(rho, symbol, &canCache);
1345
342
      if (vl != R_NilValue) {
1346
2
    if(canCache)
1347
2
        R_AddGlobalCache(symbol, vl);
1348
2
    return vl;
1349
2
      }
1350
342
  }
1351
58
  else {
1352
58
      if (SYMVALUE(symbol) != R_UnboundValue)
1353
46
    R_AddGlobalCache(symbol, symbol);
1354
58
      return symbol;
1355
58
  }
1356
400
    }
1357
0
    return R_NilValue;
1358
60
}
1359
1360
static R_INLINE SEXP findGlobalVar(SEXP symbol)
1361
1.95k
{
1362
1.95k
    SEXP loc = findGlobalVarLoc(symbol);
1363
1.95k
    switch (TYPEOF(loc)) {
1364
0
    case NILSXP: return R_UnboundValue;
1365
58
    case SYMSXP: return SYMBOL_BINDING_VALUE(symbol);
1366
1.89k
    default: return BINDING_VALUE(loc);
1367
                    /* loc is protected by callee when needed */
1368
1.95k
    }
1369
1.95k
}
1370
#endif
1371
1372
attribute_hidden SEXP R_findVar(SEXP symbol, SEXP rho)
1373
3.17M
{
1374
3.17M
    SEXP vl;
1375
1376
3.17M
    if (TYPEOF(rho) == NILSXP)
1377
0
  error(_("use of NULL environment is defunct"));
1378
1379
3.17M
    if (!isEnvironment(rho))
1380
0
  error(_("argument to '%s' is not an environment"), "findVar");
1381
1382
3.17M
#ifdef USE_GLOBAL_CACHE
1383
    /* This first loop handles local frames, if there are any.  It
1384
       will also handle all frames if rho is a global frame other than
1385
       R_GlobalEnv */
1386
3.22M
    while (rho != R_GlobalEnv && rho != R_EmptyEnv) {
1387
3.22M
  vl = R_findVarInFrame(rho, symbol);
1388
3.22M
  if (vl != R_UnboundValue) return (vl);
1389
51.1k
  rho = ENCLOS(rho);
1390
51.1k
    }
1391
24
    if (rho == R_GlobalEnv)
1392
24
  return findGlobalVar(symbol);
1393
0
    else
1394
0
  return R_UnboundValue;
1395
#else
1396
    while (rho != R_EmptyEnv) {
1397
  vl = R_findVarInFrame(rho, symbol);
1398
  if (vl != R_UnboundValue) return (vl);
1399
  rho = ENCLOS(rho);
1400
    }
1401
    return R_UnboundValue;
1402
#endif
1403
24
}
1404
1405
SEXP findVar(SEXP symbol, SEXP rho)
1406
24
{
1407
24
    return R_findVar(symbol, rho);
1408
24
}
1409
1410
static SEXP findVarLoc(SEXP symbol, SEXP rho)
1411
300k
{
1412
300k
    SEXP vl;
1413
1414
300k
    if (TYPEOF(rho) == NILSXP)
1415
0
  error(_("use of NULL environment is defunct"));
1416
1417
300k
    if (!isEnvironment(rho))
1418
0
  error(_("argument to '%s' is not an environment"), "findVarLoc");
1419
1420
300k
#ifdef USE_GLOBAL_CACHE
1421
    /* This first loop handles local frames, if there are any.  It
1422
       will also handle all frames if rho is a global frame other than
1423
       R_GlobalEnv */
1424
650k
    while (rho != R_GlobalEnv && rho != R_EmptyEnv) {
1425
650k
  vl = findVarLocInFrame(rho, symbol, NULL);
1426
650k
  if (vl != R_NilValue) return vl;
1427
349k
  rho = ENCLOS(rho);
1428
349k
    }
1429
0
    if (rho == R_GlobalEnv)
1430
0
  return findGlobalVarLoc(symbol);
1431
0
    else
1432
0
  return R_NilValue;
1433
#else
1434
    while (rho != R_EmptyEnv) {
1435
  vl = R_findVarInLocFrame(rho, symbol, NULL);
1436
  if (vl != R_NilValue) return vl;
1437
  rho = ENCLOS(rho);
1438
    }
1439
    return R_NilValue;
1440
#endif
1441
0
}
1442
1443
R_varloc_t R_findVarLoc(SEXP symbol, SEXP rho)
1444
300k
{
1445
300k
    SEXP binding = findVarLoc(symbol, rho);
1446
300k
    R_varloc_t val;
1447
300k
    val.cell = binding == R_NilValue ? NULL : binding;
1448
300k
    return val;
1449
300k
}
1450
1451
1452
/*----------------------------------------------------------------------
1453
1454
  findVar1
1455
1456
  Look up a symbol in an environment.  Ignore any values which are
1457
  not of the specified type.
1458
1459
*/
1460
1461
attribute_hidden SEXP
1462
findVar1(SEXP symbol, SEXP rho, SEXPTYPE mode, int inherits)
1463
0
{
1464
0
    SEXP vl;
1465
0
    while (rho != R_EmptyEnv) {
1466
0
  vl = R_findVarInFrame(rho, symbol);
1467
0
  if (vl != R_UnboundValue) {
1468
0
      if (mode == ANYSXP) return vl;
1469
0
      if (TYPEOF(vl) == PROMSXP) {
1470
0
    PROTECT(vl);
1471
0
    vl = eval(vl, rho);
1472
0
    UNPROTECT(1);
1473
0
      }
1474
0
      if (TYPEOF(vl) == mode) return vl;
1475
0
      if (mode == FUNSXP && (TYPEOF(vl) == CLOSXP ||
1476
0
           TYPEOF(vl) == BUILTINSXP ||
1477
0
           TYPEOF(vl) == SPECIALSXP))
1478
0
    return (vl);
1479
0
  }
1480
0
  if (inherits)
1481
0
      rho = ENCLOS(rho);
1482
0
  else
1483
0
      return (R_UnboundValue);
1484
0
    }
1485
0
    return (R_UnboundValue);
1486
0
}
1487
1488
/*
1489
 *  ditto, but check *mode* not *type*
1490
 */
1491
1492
static SEXP
1493
findVar1mode(SEXP symbol, SEXP rho, SEXPTYPE mode, Rboolean wants_S4,
1494
       int inherits, Rboolean doGet)
1495
187k
{
1496
187k
    SEXP vl;
1497
187k
    int tl;
1498
187k
    if (mode == INTSXP) mode = REALSXP;
1499
187k
    if (mode == FUNSXP || mode ==  BUILTINSXP || mode == SPECIALSXP)
1500
276
  mode = CLOSXP;
1501
188k
    while (rho != R_EmptyEnv) {
1502
188k
  if (! doGet && mode == ANYSXP)
1503
12.9k
      vl = R_existsVarInFrame(rho, symbol) ? R_NilValue : R_UnboundValue;
1504
175k
  else
1505
175k
      vl = findVarInFrame3(rho, symbol, doGet);
1506
1507
188k
  if (vl != R_UnboundValue) {
1508
29.6k
      if (mode == ANYSXP) return vl;
1509
276
      if (TYPEOF(vl) == PROMSXP) {
1510
24
    PROTECT(vl);
1511
24
    vl = eval(vl, rho);
1512
24
    UNPROTECT(1);
1513
24
      }
1514
276
      tl = TYPEOF(vl);
1515
276
      if (tl == INTSXP) tl = REALSXP;
1516
276
      if (tl == FUNSXP || tl ==  BUILTINSXP || tl == SPECIALSXP)
1517
252
    tl = CLOSXP;
1518
276
      if (tl == mode) {
1519
276
    if (tl == OBJSXP) {
1520
0
        if ((wants_S4 && IS_S4_OBJECT(vl)) ||
1521
0
      (! wants_S4 && ! IS_S4_OBJECT(vl)))
1522
0
      return vl;
1523
0
    }
1524
276
    else return vl;
1525
276
      }
1526
276
  }
1527
158k
  if (inherits)
1528
1.12k
      rho = ENCLOS(rho);
1529
157k
  else
1530
157k
      return (R_UnboundValue);
1531
158k
    }
1532
0
    return (R_UnboundValue);
1533
187k
}
1534
1535
1536
/*
1537
   ddVal ("dot-dot-value"):
1538
   a function to take a name and determine if it is of the form
1539
   ..x where x is an integer; if so x is returned otherwise 0 is returned
1540
*/
1541
static int ddVal(SEXP symbol)
1542
49.0k
{
1543
49.0k
    const char *buf;
1544
49.0k
    char *endp;
1545
49.0k
    int rval;
1546
1547
49.0k
    buf = CHAR(PRINTNAME(symbol));
1548
49.0k
    if( !strncmp(buf,"..",2) && strlen(buf) > 2 ) {
1549
49.0k
  buf += 2;
1550
49.0k
  rval = (int) strtol(buf, &endp, 10);
1551
49.0k
  if( *endp != '\0')
1552
0
      return 0;
1553
49.0k
  else
1554
49.0k
      return rval;
1555
49.0k
    }
1556
0
    return 0;
1557
49.0k
}
1558
1559
/*----------------------------------------------------------------------
1560
  ddfindVar
1561
1562
  This function fetches the variables ..1, ..2, etc from the first
1563
  frame of the environment passed as the second argument to ddfindVar.
1564
  These variables are implicitly defined whenever a ... object is
1565
  created.
1566
1567
  To determine values for the variables we first search for an
1568
  explicit definition of the symbol, them we look for a ... object in
1569
  the frame and then walk through it to find the appropriate values.
1570
1571
  If no value is obtained we return R_UnboundValue.
1572
1573
  It is an error to specify a .. index longer than the length of the
1574
  ... object the value is sought in.
1575
1576
*/
1577
1578
80.3k
#define length_DOTS(_v_) (TYPEOF(_v_) == DOTSXP ? length(_v_) : 0)
1579
1580
/* Walk parent environments to find the first one containing a proper `...` */
1581
SEXP R_findDotsEnv(SEXP env)
1582
80.3k
{
1583
80.3k
    while (env != R_EmptyEnv) {
1584
80.3k
  SEXP vl = R_findVarInFrame(env, R_DotsSymbol);
1585
80.3k
  if (vl != R_UnboundValue &&
1586
80.3k
      (vl == R_MissingArg || TYPEOF(vl) == DOTSXP))
1587
80.3k
      return env;
1588
0
  env = ENCLOS(env);
1589
0
    }
1590
0
    return R_EmptyEnv;
1591
80.3k
}
1592
1593
Rboolean R_DotsExist(SEXP env)
1594
0
{
1595
0
    SEXP vl = R_findVarInFrame(env, R_DotsSymbol);
1596
0
    return vl != R_UnboundValue &&
1597
0
  (vl == R_MissingArg || TYPEOF(vl) == DOTSXP);
1598
0
}
1599
1600
static SEXP resolveDotsEnv(SEXP env, Rboolean inherits)
1601
0
{
1602
0
    return inherits ? R_findDotsEnv(env) : env;
1603
0
}
1604
1605
attribute_hidden SEXP do_dotsExist(SEXP call, SEXP op, SEXP args, SEXP env)
1606
0
{
1607
0
    checkArity(op, args);
1608
0
    SEXP rho = resolveDotsEnv(CAR(args), asLogical(CADR(args)));
1609
0
    return ScalarLogical(R_DotsExist(rho));
1610
0
}
1611
1612
/* Frame-only: does not search parent environments */
1613
static SEXP ddfindInFrame(int i, SEXP rho)
1614
54.7k
{
1615
54.7k
    if(i <= 0)
1616
0
  error(_("indexing '...' with non-positive index %d"), i);
1617
54.7k
    SEXP vl = R_findVarInFrame(rho, R_DotsSymbol);
1618
54.7k
    if (vl != R_UnboundValue) {
1619
54.7k
  if (TYPEOF(vl) != DOTSXP && vl != R_MissingArg)
1620
0
      error(_("bad ... value"));
1621
54.7k
  if (length_DOTS(vl) >= i) {
1622
54.7k
      vl = nthcdr(vl, i - 1);
1623
54.7k
      return(CAR(vl));
1624
54.7k
  }
1625
0
  else // length(...) < i
1626
0
      error(ngettext("the ... list contains fewer than %d element",
1627
0
         "the ... list contains fewer than %d elements", i),
1628
0
                  i);
1629
54.7k
    }
1630
0
    else error(_("..%d used in an incorrect context, no ... to look in"), i);
1631
1632
0
    return R_NilValue;
1633
54.7k
}
1634
1635
static SEXP ddfind(int i, SEXP rho)
1636
49.0k
{
1637
49.0k
    return ddfindInFrame(i, R_findDotsEnv(rho));
1638
49.0k
}
1639
1640
attribute_hidden
1641
SEXP ddfindVar(SEXP symbol, SEXP rho)
1642
49.0k
{
1643
49.0k
    int i = ddVal(symbol);
1644
49.0k
    return ddfind(i, rho);
1645
49.0k
}
1646
1647
SEXP R_DotsElt(int i, SEXP env)
1648
5.71k
{
1649
5.71k
    SEXP val = ddfindInFrame(i, env);
1650
5.71k
    if (TYPEOF(val) == PROMSXP || val == R_MissingArg)
1651
5.71k
  return eval(val, env);
1652
0
    else
1653
0
  return val;
1654
5.71k
}
1655
1656
attribute_hidden SEXP do_dotsElt(SEXP call, SEXP op, SEXP args, SEXP env)
1657
5.71k
{
1658
5.71k
    checkArity(op, args);
1659
5.71k
    check1arg(args, call, "n");
1660
1661
5.71k
    SEXP si = CAR(args);
1662
5.71k
    if (! isNumeric(si) || XLENGTH(si) != 1)
1663
0
  errorcall(call, _("indexing '...' with an invalid index"));
1664
5.71k
    int i = asInteger(si);
1665
5.71k
    return R_DotsElt(i, R_findDotsEnv(env));
1666
5.71k
}
1667
1668
int R_DotsLength(SEXP env)
1669
25.3k
{
1670
25.3k
    SEXP vl = R_findVarInFrame(env, R_DotsSymbol);
1671
25.3k
    if (vl == R_UnboundValue)
1672
0
  error(_("incorrect context: the current call has no '...' to look in"));
1673
25.3k
    return length_DOTS(vl);
1674
25.3k
}
1675
1676
attribute_hidden SEXP do_dotsLength(SEXP call, SEXP op, SEXP args, SEXP env)
1677
25.3k
{
1678
25.3k
    checkArity(op, args);
1679
25.3k
    return ScalarInteger(R_DotsLength(R_findDotsEnv(env)));
1680
25.3k
}
1681
1682
SEXP R_DotsNames(SEXP env)
1683
240
{
1684
240
    SEXP vl = R_findVarInFrame(env, R_DotsSymbol);
1685
240
    PROTECT(vl);
1686
240
    if (vl == R_UnboundValue)
1687
0
  error(_("incorrect context: the current call has no '...' to look in"));
1688
240
    SEXP out = R_NilValue;
1689
240
    int n = length_DOTS(vl);
1690
420
    for(int i = 0; i < n; i++) {
1691
180
  if(TAG(vl) != R_NilValue) {
1692
180
      if(out == R_NilValue) {
1693
    // this fills 'out' with ""
1694
180
    PROTECT(out = allocVector(STRSXP, n));
1695
180
      }
1696
180
      SET_STRING_ELT(out, i, PRINTNAME(TAG(vl)));
1697
180
  }
1698
180
        vl = CDR(vl);
1699
180
    }
1700
240
    if(out != R_NilValue)
1701
180
        UNPROTECT(1); // out
1702
240
    UNPROTECT(1); // vl
1703
240
    return out;
1704
240
}
1705
1706
attribute_hidden SEXP do_dotsNames(SEXP call, SEXP op, SEXP args, SEXP env)
1707
240
{
1708
240
    checkArity(op, args);
1709
240
    return R_DotsNames(R_findDotsEnv(env));
1710
240
}
1711
1712
R_DotType_t R_GetDotType(int i, SEXP env)
1713
0
{
1714
0
    SEXP value = ddfindInFrame(i, env);
1715
1716
0
    if (value == R_MissingArg)
1717
0
  return R_DotTypeMissing;
1718
1719
0
    if (TYPEOF(value) == PROMSXP) {
1720
0
  Rboolean forced;
1721
0
  promiseUnwrap(value, &forced);
1722
0
  if (forced)
1723
0
      return R_DotTypeForced;
1724
0
  else
1725
0
      return R_DotTypeDelayed;
1726
0
    }
1727
1728
0
    return R_DotTypeValue;
1729
0
}
1730
1731
SEXP R_DotDelayedExpression(int i, SEXP env)
1732
0
{
1733
0
    SEXP value = ddfindInFrame(i, env);
1734
0
    if (TYPEOF(value) != PROMSXP)
1735
0
  error(_("not a delayed ... element"));
1736
1737
0
    Rboolean forced;
1738
0
    SEXP inner = promiseUnwrap(value, &forced);
1739
0
    if (forced)
1740
0
  error(_("not a delayed ... element"));
1741
1742
0
    return R_PromiseExpr(inner);
1743
0
}
1744
1745
SEXP R_DotDelayedEnvironment(int i, SEXP env)
1746
0
{
1747
0
    SEXP value = ddfindInFrame(i, env);
1748
0
    if (TYPEOF(value) != PROMSXP)
1749
0
  error(_("not a delayed ... element"));
1750
1751
0
    Rboolean forced;
1752
0
    SEXP inner = promiseUnwrap(value, &forced);
1753
0
    if (forced)
1754
0
  error(_("not a delayed ... element"));
1755
1756
0
    return PRENV(inner);
1757
0
}
1758
1759
SEXP R_DotForcedExpression(int i, SEXP env)
1760
0
{
1761
0
    SEXP value = ddfindInFrame(i, env);
1762
0
    if (TYPEOF(value) != PROMSXP)
1763
0
  error(_("not a forced ... element"));
1764
1765
0
    Rboolean forced;
1766
0
    SEXP inner = promiseUnwrap(value, &forced);
1767
0
    if (!forced)
1768
0
  error(_("not a forced ... element"));
1769
1770
0
    return R_PromiseExpr(inner);
1771
0
}
1772
1773
attribute_hidden SEXP do_dotType(SEXP call, SEXP op, SEXP args, SEXP rho)
1774
0
{
1775
0
    checkArity(op, args);
1776
0
    int i = asInteger(CAR(args));
1777
0
    SEXP env = resolveDotsEnv(CADR(args), asLogical(CADDR(args)));
1778
0
    switch(R_GetDotType(i, env)) {
1779
0
    case R_DotTypeValue: return mkString("value");
1780
0
    case R_DotTypeMissing: return mkString("missing");
1781
0
    case R_DotTypeDelayed: return mkString("delayed");
1782
0
    case R_DotTypeForced: return mkString("forced");
1783
0
    default: error("unknown dot type; should not happen");
1784
0
    }
1785
0
}
1786
1787
attribute_hidden SEXP do_dotDelayedExpr(SEXP call, SEXP op, SEXP args, SEXP rho)
1788
0
{
1789
0
    checkArity(op, args);
1790
0
    int i = asInteger(CAR(args));
1791
0
    SEXP env = resolveDotsEnv(CADR(args), asLogical(CADDR(args)));
1792
0
    return R_DotDelayedExpression(i, env);
1793
0
}
1794
1795
attribute_hidden SEXP do_dotDelayedEnv(SEXP call, SEXP op, SEXP args, SEXP rho)
1796
0
{
1797
0
    checkArity(op, args);
1798
0
    int i = asInteger(CAR(args));
1799
0
    SEXP env = resolveDotsEnv(CADR(args), asLogical(CADDR(args)));
1800
0
    return R_DotDelayedEnvironment(i, env);
1801
0
}
1802
1803
attribute_hidden SEXP do_dotForcedExpr(SEXP call, SEXP op, SEXP args, SEXP rho)
1804
0
{
1805
0
    checkArity(op, args);
1806
0
    int i = asInteger(CAR(args));
1807
0
    SEXP env = resolveDotsEnv(CADR(args), asLogical(CADDR(args)));
1808
0
    return R_DotForcedExpression(i, env);
1809
0
}
1810
1811
/* .Internal wrappers for dots accessors taking explicit `env` and `inherits` */
1812
1813
attribute_hidden SEXP do_CDotsLength(SEXP call, SEXP op, SEXP args, SEXP rho)
1814
0
{
1815
0
    checkArity(op, args);
1816
0
    SEXP env = resolveDotsEnv(CAR(args), asLogical(CADR(args)));
1817
0
    return ScalarInteger(R_DotsLength(env));
1818
0
}
1819
1820
attribute_hidden SEXP do_CDotsNames(SEXP call, SEXP op, SEXP args, SEXP rho)
1821
0
{
1822
0
    checkArity(op, args);
1823
0
    SEXP env = resolveDotsEnv(CAR(args), asLogical(CADR(args)));
1824
0
    return R_DotsNames(env);
1825
0
}
1826
1827
attribute_hidden SEXP do_CDotsElt(SEXP call, SEXP op, SEXP args, SEXP rho)
1828
0
{
1829
0
    checkArity(op, args);
1830
0
    int i = asInteger(CAR(args));
1831
0
    SEXP env = resolveDotsEnv(CADR(args), asLogical(CADDR(args)));
1832
0
    return R_DotsElt(i, env);
1833
0
}
1834
1835
#undef length_DOTS
1836
1837
/*----------------------------------------------------------------------
1838
1839
  dynamicfindVar
1840
1841
  This function does a variable lookup, but uses dynamic scoping rules
1842
  rather than the lexical scoping rules used in findVar.
1843
1844
  Return R_UnboundValue if the symbol isn't located and the calling
1845
  function needs to handle the errors.
1846
1847
*/
1848
1849
#ifdef UNUSED
1850
SEXP dynamicfindVar(SEXP symbol, RCNTXT *cptr)
1851
{
1852
    SEXP vl;
1853
    while (cptr != R_ToplevelContext) {
1854
  if (cptr->callflag & CTXT_FUNCTION) {
1855
      vl = R_findVarInFrame(cptr->cloenv, symbol);
1856
      if (vl != R_UnboundValue) return vl;
1857
  }
1858
  cptr = cptr->nextcontext;
1859
    }
1860
    return R_UnboundValue;
1861
}
1862
#endif
1863
1864
1865
1866
/*----------------------------------------------------------------------
1867
1868
  findFun
1869
1870
  Search for a function in an environment This is a specially modified
1871
  version of findVar which ignores values its finds if they are not
1872
  functions.
1873
1874
 [ NEEDED: This needs to be modified so that a search for an arbitrary mode can
1875
  be made.  Then findVar and findFun could become same function.]
1876
1877
  This could call findVar1.  NB: they behave differently on failure.
1878
*/
1879
1880
attribute_hidden
1881
SEXP findFun3(SEXP symbol, SEXP rho, SEXP call)
1882
8.62M
{
1883
8.62M
    SEXP vl;
1884
1885
    /* If the symbol is marked as special, skip to the first
1886
       environment that might contain such a symbol. */
1887
8.62M
    if (IS_SPECIAL_SYMBOL(symbol)) {
1888
1.98M
  while (rho != R_EmptyEnv && NO_SPECIAL_SYMBOLS(rho))
1889
998k
      rho = ENCLOS(rho);
1890
982k
    }
1891
1892
16.6M
    while (rho != R_EmptyEnv) {
1893
  /* This is not really right.  Any variable can mask a function */
1894
16.6M
#ifdef USE_GLOBAL_CACHE
1895
16.6M
  if (rho == R_GlobalEnv)
1896
38.0k
#ifdef FAST_BASE_CACHE_LOOKUP
1897
38.0k
      if (BASE_SYM_CACHED(symbol))
1898
36.0k
    vl = SYMBOL_BINDING_VALUE(symbol);
1899
1.92k
      else
1900
1.92k
    vl = findGlobalVar(symbol);
1901
#else
1902
      vl = findGlobalVar(symbol);
1903
#endif
1904
16.6M
  else
1905
16.6M
      vl = R_findVarInFrame(rho, symbol);
1906
#else
1907
  vl = R_findVarInFrame(rho, symbol);
1908
#endif
1909
16.6M
  if (vl != R_UnboundValue) {
1910
8.62M
      if (TYPEOF(vl) == PROMSXP) {
1911
3.60M
    if (PROMISE_IS_EVALUATED(vl))
1912
3.59M
        vl = PRVALUE(vl);
1913
2.49k
    else {
1914
2.49k
        PROTECT(vl);
1915
2.49k
        vl = eval(vl, rho);
1916
2.49k
        UNPROTECT(1);
1917
2.49k
    }
1918
3.60M
      }
1919
8.62M
      if (TYPEOF(vl) == CLOSXP || TYPEOF(vl) == BUILTINSXP ||
1920
1.02M
    TYPEOF(vl) == SPECIALSXP)
1921
8.62M
    return (vl);
1922
84
      if (vl == R_MissingArg)
1923
0
          R_MissingArgError(symbol, call, "getMissingError");
1924
1925
84
  }
1926
8.01M
  rho = ENCLOS(rho);
1927
8.01M
    }
1928
0
    R_FunctionNotFoundError(symbol, call);
1929
    /* NOT REACHED */
1930
0
    return R_UnboundValue;
1931
8.62M
}
1932
1933
SEXP findFun(SEXP symbol, SEXP rho)
1934
6.79M
{
1935
6.79M
    return findFun3(symbol, rho, R_CurrentExpression);
1936
6.79M
}
1937
1938
/*----------------------------------------------------------------------
1939
1940
  defineVar
1941
1942
  Assign a value in a specific environment frame.
1943
1944
*/
1945
1946
void defineVar(SEXP symbol, SEXP value, SEXP rho)
1947
10.2M
{
1948
10.2M
    int hashcode;
1949
10.2M
    SEXP frame, c;
1950
1951
10.2M
    if (value == R_UnboundValue)
1952
0
  error("attempt to bind a variable to R_UnboundValue");
1953
    /* R_DirtyImage should only be set if assigning to R_GlobalEnv. */
1954
10.2M
    if (rho == R_GlobalEnv) R_DirtyImage = 1;
1955
1956
10.2M
    if (rho == R_EmptyEnv)
1957
0
  error(_("cannot assign values in the empty environment"));
1958
1959
10.2M
    if(IS_USER_DATABASE(rho)) {
1960
0
  R_ObjectTable *table;
1961
0
  table = (R_ObjectTable *) R_ExternalPtrAddr(HASHTAB(rho));
1962
0
  if(table->assign == NULL)
1963
0
      error(_("cannot assign variables to this database"));
1964
0
  PROTECT(value);
1965
0
  table->assign(CHAR(PRINTNAME(symbol)), value, table);
1966
0
  UNPROTECT(1);
1967
0
#ifdef USE_GLOBAL_CACHE
1968
0
  if (IS_GLOBAL_FRAME(rho)) R_FlushGlobalCache(symbol);
1969
0
#endif
1970
0
  return;
1971
0
    }
1972
1973
10.2M
    if (rho == R_BaseNamespace || rho == R_BaseEnv) {
1974
14.5k
  gsetVar(symbol, value, rho);
1975
10.2M
    } else {
1976
10.2M
#ifdef USE_GLOBAL_CACHE
1977
10.2M
  if (IS_GLOBAL_FRAME(rho)) R_FlushGlobalCache(symbol);
1978
10.2M
#endif
1979
1980
10.2M
  if (IS_SPECIAL_SYMBOL(symbol))
1981
612
      UNSET_NO_SPECIAL_SYMBOLS(rho);
1982
1983
10.2M
  if (HASHTAB(rho) == R_NilValue) {
1984
      /* First check for an existing binding */
1985
10.1M
      frame = FRAME(rho);
1986
51.3M
      while (frame != R_NilValue) {
1987
41.8M
    if (TAG(frame) == symbol) {
1988
609k
        SET_BINDING_VALUE(frame, value);
1989
609k
        SET_MISSING(frame, 0);  /* Over-ride */
1990
609k
        return;
1991
609k
    }
1992
41.2M
    frame = CDR(frame);
1993
41.2M
      }
1994
9.53M
      if (FRAME_IS_LOCKED(rho))
1995
0
    error(_("cannot add bindings to a locked environment"));
1996
9.53M
      SET_FRAME(rho, CONS(value, FRAME(rho)));
1997
9.53M
      SET_TAG(FRAME(rho), symbol);
1998
9.53M
  }
1999
119k
  else {
2000
119k
      c = PRINTNAME(symbol);
2001
119k
      if( !HASHASH(c) ) {
2002
0
    SET_HASHVALUE(c, R_Newhashpjw(CHAR(c)));
2003
0
    SET_HASHASH(c, 1);
2004
0
      }
2005
119k
      hashcode = HASHVALUE(c) % HASHSIZE(HASHTAB(rho));
2006
119k
      R_HashSet(hashcode, symbol, HASHTAB(rho), value,
2007
119k
          (Rboolean) FRAME_IS_LOCKED(rho));
2008
119k
      if (R_HashSizeCheck(HASHTAB(rho)))
2009
3.54k
    SET_HASHTAB(rho, R_HashResize(HASHTAB(rho)));
2010
119k
  }
2011
10.2M
    }
2012
10.2M
}
2013
2014
/*----------------------------------------------------------------------
2015
2016
  addMissingVarsToNewEnv
2017
2018
  Add given variables (addVars - list) to given environment (env) unless
2019
  they are already there.  Env is a "new" environment, created by
2020
  NewEnvironment, as in applyClosure (so it list-based).  Slots for vars are
2021
  re-used.  The addVars list itself can have duplicit variables.
2022
2023
  The implementation is performance optimized towards the common case that
2024
  the variables from addVars are not present in env and that addVars does
2025
  not have duplicit variables.
2026
*/
2027
2028
attribute_hidden
2029
void addMissingVarsToNewEnv(SEXP env, SEXP addVars)
2030
144k
{
2031
144k
    if (addVars == R_NilValue) return;
2032
2033
    /* temporary sanity check */
2034
144k
    if (TYPEOF(addVars) == ENVSXP)
2035
0
  error("additional variables should now be passed as a list, "
2036
0
        "not in an environment");
2037
2038
    /* append variables from env after addVars */
2039
144k
    SEXP aprev = addVars;
2040
144k
    SEXP a = CDR(addVars);
2041
868k
    while (a != R_NilValue) {
2042
723k
  aprev = a;
2043
723k
  a = CDR(a);
2044
723k
    }
2045
144k
    SETCDR(aprev, FRAME(env));
2046
144k
    SET_FRAME(env, addVars);
2047
2048
    /* remove duplicates - a variable listed later has precedence over a
2049
       variable listed sooner */
2050
144k
    SEXP end;
2051
1.17M
    for(end = CDR(addVars); end != R_NilValue; end = CDR(end)) {
2052
1.02M
  SEXP endTag = TAG(end);
2053
1.02M
  SEXP sprev = R_NilValue;
2054
1.02M
  SEXP s;
2055
5.29M
  for(s = addVars; s != end; s = CDR(s)) {
2056
4.26M
      if (TAG(s) == endTag) {
2057
    /* remove variable s from the list, because it is overridden by "end" */
2058
0
    if (sprev == R_NilValue) {
2059
0
        addVars = CDR(s);
2060
0
        SET_FRAME(env, addVars);
2061
0
    } else
2062
0
        SETCDR(sprev, CDR(s));
2063
0
      } else
2064
4.26M
    sprev = s;
2065
4.26M
  }
2066
1.02M
    }
2067
144k
}
2068
2069
/*----------------------------------------------------------------------
2070
2071
  setVarInFrame
2072
2073
  Assign a new value to an existing symbol in a frame.
2074
  Return the symbol if successful and R_NilValue if not.
2075
2076
  [ Taken static in 2.4.0: not called for emptyenv or baseenv. ]
2077
*/
2078
2079
static SEXP setVarInFrame(SEXP rho, SEXP symbol, SEXP value)
2080
17.4k
{
2081
17.4k
    int hashcode;
2082
17.4k
    SEXP frame, c;
2083
2084
    /* R_DirtyImage should only be set if assigning to R_GlobalEnv. */
2085
17.4k
    if (rho == R_GlobalEnv) R_DirtyImage = 1;
2086
17.4k
    if (rho == R_EmptyEnv) return R_NilValue;
2087
2088
17.4k
    if(IS_USER_DATABASE(rho)) {
2089
  /* FIXME: This does not behave as described */
2090
0
  R_ObjectTable *table;
2091
0
  table = (R_ObjectTable *) R_ExternalPtrAddr(HASHTAB(rho));
2092
0
  if(table->assign == NULL)
2093
0
      error(_("cannot assign variables to this database"));
2094
0
  PROTECT(value);
2095
0
  SEXP result = table->assign(CHAR(PRINTNAME(symbol)), value, table);
2096
0
  UNPROTECT(1);
2097
0
  return(result);
2098
0
    }
2099
2100
17.4k
    if (rho == R_BaseNamespace || rho == R_BaseEnv) {
2101
0
  if (SYMVALUE(symbol) == R_UnboundValue) return R_NilValue;
2102
0
  SET_SYMBOL_BINDING_VALUE(symbol, value);
2103
0
  return symbol;
2104
0
    }
2105
2106
17.4k
    if (HASHTAB(rho) == R_NilValue) {
2107
17.3k
  frame = FRAME(rho);
2108
48.2k
  while (frame != R_NilValue) {
2109
40.0k
      if (TAG(frame) == symbol) {
2110
9.09k
    SET_BINDING_VALUE(frame, value);
2111
9.09k
    SET_MISSING(frame, 0);  /* same as defineVar */
2112
9.09k
    return symbol;
2113
9.09k
      }
2114
30.9k
      frame = CDR(frame);
2115
30.9k
  }
2116
17.3k
    } else {
2117
  /* Do the hash table thing */
2118
108
  c = PRINTNAME(symbol);
2119
108
  if( !HASHASH(c) ) {
2120
0
      SET_HASHVALUE(c, R_Newhashpjw(CHAR(c)));
2121
0
      SET_HASHASH(c, 1);
2122
0
  }
2123
108
  hashcode = HASHVALUE(c) % HASHSIZE(HASHTAB(rho));
2124
108
  frame = R_HashGetLoc(hashcode, symbol, HASHTAB(rho));
2125
108
  if (frame != R_NilValue) {
2126
108
      SET_BINDING_VALUE(frame, value);
2127
108
      SET_MISSING(frame, 0);  /* same as defineVar */
2128
108
      return symbol;
2129
108
  }
2130
108
    }
2131
8.20k
    return R_NilValue; /* -Wall */
2132
17.4k
}
2133
2134
2135
/*----------------------------------------------------------------------
2136
2137
    setVar
2138
2139
    Assign a new value to bound symbol.  Note this does the "inherits"
2140
    case.  I.e. it searches frame-by-frame for a symbol and binds the
2141
    given value to the first symbol encountered.  If no symbol is
2142
    found then a binding is created in the global environment.
2143
2144
    Changed in R 2.4.0 to look in the base environment (previously the
2145
    search stopped befor the base environment, but would (and still
2146
    does) assign into the base namespace if that is on the search and
2147
    the symbol existed there).
2148
2149
*/
2150
2151
void setVar(SEXP symbol, SEXP value, SEXP rho)
2152
9.20k
{
2153
9.20k
    SEXP vl;
2154
17.4k
    while (rho != R_EmptyEnv) {
2155
17.4k
  vl = setVarInFrame(rho, symbol, value);
2156
17.4k
  if (vl != R_NilValue) return;
2157
8.20k
  rho = ENCLOS(rho);
2158
8.20k
    }
2159
0
    defineVar(symbol, value, R_GlobalEnv);
2160
0
}
2161
2162
2163
2164
/*----------------------------------------------------------------------
2165
2166
  gsetVar
2167
2168
  Assignment in the base environment. Here we assign directly into
2169
  the base environment.
2170
2171
*/
2172
2173
void gsetVar(SEXP symbol, SEXP value, SEXP rho)
2174
14.6k
{
2175
14.6k
    if (FRAME_IS_LOCKED(rho)) {
2176
0
  if(SYMVALUE(symbol) == R_UnboundValue)
2177
0
      error(_("cannot add binding of '%s' to the base environment"),
2178
0
      CHAR(PRINTNAME(symbol)));
2179
0
    }
2180
14.6k
#ifdef USE_GLOBAL_CACHE
2181
14.6k
    R_FlushGlobalCache(symbol);
2182
14.6k
#endif
2183
14.6k
    SET_SYMBOL_BINDING_VALUE(symbol, value);
2184
14.6k
}
2185
2186
/* get environment from a subclass if possible; else return NULL */
2187
0
#define simple_as_environment(arg) (IS_S4_OBJECT(arg) && (TYPEOF(arg) == OBJSXP) ? R_getS4DataSlot(arg, ENVSXP) : R_NilValue)
2188
2189
2190
2191
/*----------------------------------------------------------------------
2192
2193
  do_assign : .Internal(assign(x, value, envir, inherits))
2194
2195
*/
2196
attribute_hidden SEXP do_assign(SEXP call, SEXP op, SEXP args, SEXP rho)
2197
624
{
2198
624
    SEXP name=R_NilValue, val, aenv;
2199
624
    int ginherits = 0;
2200
624
    checkArity(op, args);
2201
2202
624
    if (!isString(CAR(args)) || length(CAR(args)) == 0)
2203
0
  error(_("invalid first argument"));
2204
624
    else {
2205
624
  if (length(CAR(args)) > 1)
2206
0
      warning(_("only the first element is used as variable name"));
2207
624
  name = installTrChar(STRING_ELT(CAR(args), 0));
2208
624
    }
2209
624
    PROTECT(val = CADR(args));
2210
624
    aenv = CADDR(args);
2211
624
    if (TYPEOF(aenv) == NILSXP)
2212
0
  error(_("use of NULL environment is defunct"));
2213
624
    if (TYPEOF(aenv) != ENVSXP &&
2214
0
  TYPEOF((aenv = simple_as_environment(aenv))) != ENVSXP)
2215
0
  error(_("invalid '%s' argument"), "envir");
2216
624
    ginherits = asLogical(CADDDR(args));
2217
624
    if (ginherits == NA_LOGICAL)
2218
0
  error(_("invalid '%s' argument"), "inherits");
2219
624
    if (ginherits)
2220
0
  setVar(name, val, aenv);
2221
624
    else
2222
624
  defineVar(name, val, aenv);
2223
624
    UNPROTECT(1);
2224
624
    return val;
2225
624
}
2226
2227
2228
/**
2229
 * do_list2env : .Internal(list2env(x, envir))
2230
  */
2231
attribute_hidden SEXP do_list2env(SEXP call, SEXP op, SEXP args, SEXP rho)
2232
3.62k
{
2233
3.62k
    SEXP x, xnms, envir;
2234
3.62k
    int n;
2235
3.62k
    checkArity(op, args);
2236
2237
3.62k
    if (TYPEOF(CAR(args)) != VECSXP)
2238
0
  error(_("first argument must be a named list"));
2239
3.62k
    x = CAR(args);
2240
3.62k
    n = LENGTH(x);
2241
3.62k
    xnms = getAttrib(x, R_NamesSymbol);
2242
3.62k
    PROTECT(xnms);
2243
3.62k
    if (n && (TYPEOF(xnms) != STRSXP || LENGTH(xnms) != n))
2244
0
  error(_("names(x) must be a character vector of the same length as x"));
2245
3.62k
    envir = CADR(args);
2246
3.62k
    if (TYPEOF(envir) != ENVSXP)
2247
0
  error(_("'envir' argument must be an environment"));
2248
2249
44.0k
    for(int i = 0; i < n; i++) {
2250
40.4k
  SEXP name = installTrChar(STRING_ELT(xnms, i));
2251
40.4k
  defineVar(name, lazy_duplicate(VECTOR_ELT(x, i)), envir);
2252
40.4k
    }
2253
3.62k
    UNPROTECT(1); /* xnms */
2254
2255
3.62k
    return envir;
2256
3.62k
}
2257
2258
2259
/*----------------------------------------------------------------------
2260
2261
  do_remove
2262
2263
  There are three arguments to do_remove; a list of names to remove,
2264
  an optional environment (if missing set it to R_GlobalEnv) and
2265
  inherits, a logical indicating whether to look in the parent env if
2266
  a symbol is not found in the supplied env.  This is ignored if
2267
  environment is not specified.
2268
2269
*/
2270
2271
static int RemoveVariable(SEXP name, int hashcode, SEXP env)
2272
12
{
2273
12
    int found;
2274
12
    SEXP list;
2275
2276
12
    if (env == R_BaseNamespace)
2277
0
  error(_("cannot remove variables from base namespace"));
2278
12
    if (env == R_BaseEnv)
2279
0
  error(_("cannot remove variables from the base environment"));
2280
12
    if (env == R_EmptyEnv)
2281
0
  error(_("cannot remove variables from the empty environment"));
2282
12
    if (FRAME_IS_LOCKED(env))
2283
0
  error(_("cannot remove bindings from a locked environment"));
2284
2285
12
    if(IS_USER_DATABASE(env)) {
2286
0
  R_ObjectTable *table;
2287
0
  table = (R_ObjectTable *) R_ExternalPtrAddr(HASHTAB(env));
2288
0
  if(table->remove == NULL)
2289
0
      error(_("cannot remove variables from this database"));
2290
0
  return(table->remove(CHAR(PRINTNAME(name)), table));
2291
0
    }
2292
2293
12
    if (IS_HASHED(env)) {
2294
12
  R_HashDelete(hashcode, name, env, &found);
2295
12
#ifdef USE_GLOBAL_CACHE
2296
12
  if (found && IS_GLOBAL_FRAME(env))
2297
12
      R_FlushGlobalCache(name);
2298
12
#endif
2299
12
    } else {
2300
0
  list = RemoveFromList(name, FRAME(env), &found);
2301
0
  if (found) {
2302
0
      if(env == R_GlobalEnv) R_DirtyImage = 1;
2303
0
      SET_FRAME(env, list);
2304
0
#ifdef USE_GLOBAL_CACHE
2305
0
      if (IS_GLOBAL_FRAME(env))
2306
0
    R_FlushGlobalCache(name);
2307
0
#endif
2308
0
  }
2309
0
    }
2310
12
    return found;
2311
12
}
2312
2313
attribute_hidden SEXP do_remove(SEXP call, SEXP op, SEXP args, SEXP rho)
2314
0
{
2315
    /* .Internal(remove(list, envir, inherits)) */
2316
2317
0
    checkArity(op, args);
2318
2319
0
    SEXP name = CAR(args);
2320
0
    if(TYPEOF(name) == NILSXP) return R_NilValue;
2321
0
    if (!isString(name))
2322
0
  error(_("invalid first argument"));
2323
0
    args = CDR(args);
2324
2325
0
    SEXP envarg = CAR(args);
2326
0
    if (TYPEOF(envarg) == NILSXP)
2327
0
  error(_("use of NULL environment is defunct"));
2328
0
    if (TYPEOF(envarg) != ENVSXP &&
2329
0
  TYPEOF((envarg = simple_as_environment(envarg))) != ENVSXP)
2330
0
  error(_("invalid '%s' argument"), "envir");
2331
0
    args = CDR(args);
2332
2333
0
    int ginherits = asLogical(CAR(args));
2334
0
    if (ginherits == NA_LOGICAL)
2335
0
  error(_("invalid '%s' argument"), "inherits");
2336
2337
0
    for (int i = 0, done = 0; i < LENGTH(name); i++) {
2338
0
  SEXP tsym = installTrChar(STRING_ELT(name, i));
2339
0
  int hashcode;
2340
0
  if( !HASHASH(PRINTNAME(tsym)) )
2341
0
      hashcode = R_Newhashpjw(CHAR(PRINTNAME(tsym)));
2342
0
  else
2343
0
      hashcode = HASHVALUE(PRINTNAME(tsym));
2344
0
  SEXP tenv = envarg;
2345
0
  while (tenv != R_EmptyEnv) {
2346
0
      done = RemoveVariable(tsym, hashcode, tenv);
2347
0
      if (done || !ginherits)
2348
0
    break;
2349
0
      tenv = CDR(tenv);
2350
0
  }
2351
0
  if (!done)
2352
0
      warning(_("object '%s' not found"), EncodeChar(PRINTNAME(tsym)));
2353
0
    }
2354
0
    return R_NilValue;
2355
0
}
2356
2357
void R_removeVarFromFrame(SEXP name, SEXP env)
2358
12
{
2359
12
    int hashcode = -1;
2360
2361
12
    if (TYPEOF(env) == NILSXP)
2362
0
  error(_("use of NULL environment is defunct"));
2363
2364
12
    if (!isEnvironment(env))
2365
0
  error(_("argument to '%s' is not an environment"), "R_removeVarFromFrame");
2366
2367
12
    if (TYPEOF(name) != SYMSXP)
2368
0
  error(_("not a symbol"));
2369
2370
12
    if (IS_HASHED(env)) {
2371
12
  if( !HASHASH(PRINTNAME(name)))
2372
0
      hashcode = R_Newhashpjw(CHAR(PRINTNAME(name)));
2373
12
  else
2374
12
      hashcode = HASHVALUE(PRINTNAME(name));
2375
12
    }
2376
12
    RemoveVariable(name, hashcode, env);
2377
12
}
2378
2379
2380
/*----------------------------------------------------------------------
2381
2382
  do_get
2383
2384
  This function returns the SEXP associated with the character
2385
  argument.  It needs the environment of the calling function as a
2386
  default.
2387
2388
      exists (x, envir, mode, inherits)
2389
      get    (x, envir, mode, inherits)
2390
      get0   (x, envir, mode, inherits, value_if_not_exists)
2391
*/
2392
2393
static SEXPTYPE str2mode(const char *modestr, Rboolean *pS4)
2394
187k
{
2395
187k
    if (!strcmp(modestr, "function"))
2396
276
  return FUNSXP;
2397
186k
    else if (!strcmp(modestr, "S4")) {
2398
0
  if (pS4 != NULL)
2399
0
      *pS4 = TRUE;
2400
0
  return OBJSXP;
2401
0
    }
2402
186k
    else {
2403
186k
  SEXPTYPE gmode = str2type(modestr);
2404
186k
  if(gmode == (SEXPTYPE) (-1))
2405
0
      error(_("invalid '%s' argument '%s'"), "mode", modestr);
2406
186k
  return gmode;
2407
186k
    }
2408
187k
}
2409
2410
attribute_hidden SEXP do_get(SEXP call, SEXP op, SEXP args, SEXP rho)
2411
168k
{
2412
168k
    SEXP rval, genv, t1 = R_NilValue;
2413
168k
    int ginherits = 0, where;
2414
168k
    checkArity(op, args);
2415
2416
    /* The first arg is the object name */
2417
    /* It must be present and a non-empty string */
2418
2419
168k
    if (TYPEOF(CAR(args)) == SYMSXP)
2420
0
  t1 = CAR(args);
2421
168k
    else if (isValidStringF(CAR(args))) {
2422
168k
  if (XLENGTH(CAR(args)) > 1)
2423
0
      error(_("first argument has length > 1"));
2424
168k
  t1 = installTrChar(STRING_ELT(CAR(args), 0));
2425
168k
    }
2426
0
    else
2427
0
  error(_("invalid first argument"));
2428
2429
    /* envir :  originally, the "where=" argument */
2430
2431
168k
    if (TYPEOF(CADR(args)) == ENVSXP)
2432
168k
  genv = CADR(args);
2433
0
    else if (TYPEOF(CADR(args)) == REALSXP || TYPEOF(CADR(args)) == INTSXP) {
2434
0
  where = asInteger(CADR(args));
2435
0
  genv = R_sysframe(where, R_GlobalContext);
2436
0
    }
2437
0
    else if (TYPEOF(CADR(args)) == NILSXP) {
2438
0
  error(_("use of NULL environment is defunct"));
2439
0
  genv = R_NilValue;  /* -Wall */
2440
0
    }
2441
0
    else if(TYPEOF((genv = simple_as_environment(CADR(args)))) != ENVSXP) {
2442
0
  error(_("invalid '%s' argument"), "envir");
2443
0
  genv = R_NilValue;  /* -Wall */
2444
0
    }
2445
2446
    /* mode :  The mode of the object being sought */
2447
2448
    /* as from R 1.2.0, this is the *mode*, not the *typeof* aka
2449
       storage.mode.
2450
    */
2451
2452
168k
    SEXPTYPE gmode;
2453
168k
    Rboolean wants_S4 = FALSE;
2454
168k
    if (isString(CADDR(args)))
2455
168k
  gmode = str2mode(CHAR(STRING_ELT(CADDR(args), 0)), &wants_S4);
2456
0
    else {
2457
0
  error(_("invalid '%s' argument"), "mode");
2458
0
  gmode = FUNSXP;/* -Wall */
2459
0
    }
2460
2461
168k
    ginherits = asLogical(CADDDR(args));
2462
168k
    if (ginherits == NA_LOGICAL)
2463
0
  error(_("invalid '%s' argument"), "inherits");
2464
2465
    /* Search for the object */
2466
168k
    rval = findVar1mode(t1, genv, gmode, wants_S4, ginherits,
2467
168k
      (Rboolean) PRIMVAL(op));
2468
168k
    if (rval == R_MissingArg) { // signal a *classed* error:
2469
0
  R_MissingArgError(t1, call, "getMissingError");
2470
0
    }
2471
2472
168k
    switch (PRIMVAL(op) ) {
2473
12.9k
    case 0: // exists(.) :
2474
12.9k
  return ScalarLogical(rval != R_UnboundValue);
2475
0
  break;
2476
2477
5.52k
    case 1: // have get(.)
2478
5.52k
  if (rval == R_UnboundValue) {
2479
0
      if (gmode == ANYSXP)
2480
0
    R_ObjectNotFoundError(t1, R_CurrentExpression, NULL);
2481
0
      else
2482
0
    R_ObjectNotFoundError(t1, R_CurrentExpression,
2483
0
              CHAR(STRING_ELT(CADDR(args), 0))); /* ASCII */
2484
0
  }
2485
2486
6.40k
#     define GET_VALUE(rval) do {       \
2487
      /* We need to evaluate if it is a promise */  \
2488
6.40k
      if (TYPEOF(rval) == PROMSXP) {     \
2489
5.39k
    PROTECT(rval);         \
2490
5.39k
    rval = eval(rval, genv);     \
2491
5.39k
    UNPROTECT(1);          \
2492
5.39k
      }              \
2493
6.40k
      ENSURE_NAMED(rval);         \
2494
6.40k
  } while (0)
2495
2496
5.52k
  GET_VALUE(rval);
2497
5.52k
  break;
2498
2499
150k
    case 2: // get0(.)
2500
150k
  if (rval == R_UnboundValue)
2501
149k
      return CAD4R(args);// i.e.  value_if_not_exists
2502
876
  GET_VALUE(rval);
2503
876
  break;
2504
168k
    }
2505
6.40k
    return rval;
2506
168k
}
2507
#undef GET_VALUE
2508
2509
static SEXP gfind(const char *name, SEXP env,
2510
      SEXPTYPE mode, Rboolean wants_S4,
2511
      SEXP ifnotfound, int inherits, SEXP enclos)
2512
18.4k
{
2513
18.4k
    SEXP rval, t1, R_fcall, var;
2514
2515
18.4k
    t1 = install(name);
2516
2517
    /* Search for the object - last arg is 1 to 'get' */
2518
18.4k
    rval = findVar1mode(t1, env, mode, wants_S4, inherits, 1);
2519
2520
18.4k
    if (rval == R_UnboundValue) {
2521
0
  if( isFunction(ifnotfound) ) {
2522
0
      PROTECT(var = mkString(name));
2523
0
      PROTECT(R_fcall = LCONS(ifnotfound, LCONS(var, R_NilValue)));
2524
0
      rval = eval(R_fcall, enclos);
2525
0
      UNPROTECT(2);
2526
0
  } else
2527
0
      rval = ifnotfound;
2528
0
    }
2529
2530
    /* We need to evaluate if it is a promise */
2531
18.4k
    if (TYPEOF(rval) == PROMSXP) {
2532
0
  PROTECT(rval);
2533
0
  rval = eval(rval, env);
2534
0
  UNPROTECT(1);
2535
0
    }
2536
18.4k
    ENSURE_NAMED(rval);
2537
18.4k
    return rval;
2538
18.4k
}
2539
2540
2541
/** mget(): get multiple values from an environment
2542
 *
2543
 * .Internal(mget(x, envir, mode, ifnotfound, inherits))
2544
 *
2545
 * @return  a list of the same length as x, a character vector (of names).
2546
 */
2547
attribute_hidden SEXP do_mget(SEXP call, SEXP op, SEXP args, SEXP rho)
2548
120
{
2549
120
    SEXP ans, env, x, mode, ifnotfound;
2550
120
    int ginherits = 0, nvals, nmode, nifnfnd;
2551
2552
120
    checkArity(op, args);
2553
2554
120
    x = CAR(args);
2555
2556
120
    nvals = length(x);
2557
2558
    /* The first arg is the object name */
2559
    /* It must be present and a string */
2560
120
    if (!isString(x) )
2561
0
  error(_("invalid first argument"));
2562
18.5k
    for(int i = 0; i < nvals; i++)
2563
18.4k
  if( isNull(STRING_ELT(x, i)) || !CHAR(STRING_ELT(x, 0))[0] )
2564
0
      error(_("invalid name in position %d"), i+1);
2565
2566
120
    env = CADR(args);
2567
120
    if (ISNULL(env)) {
2568
0
  error(_("use of NULL environment is defunct"));
2569
120
    } else if( !isEnvironment(env) )
2570
0
  error(_("second argument must be an environment"));
2571
2572
120
    mode = CADDR(args);
2573
120
    nmode = length(mode);
2574
120
    if( !isString(mode) )
2575
0
  error(_("invalid '%s' argument"), "mode");
2576
2577
120
    if( nmode != nvals && nmode != 1 )
2578
0
  error(_("wrong length for '%s' argument"), "mode");
2579
2580
120
    PROTECT(ifnotfound = coerceVector(CADDDR(args), VECSXP));
2581
120
    nifnfnd = length(ifnotfound);
2582
120
    if( !isVector(ifnotfound) )
2583
0
  error(_("invalid '%s' argument"), "ifnotfound");
2584
2585
120
    if( nifnfnd != nvals && nifnfnd != 1 )
2586
0
  error(_("wrong length for '%s' argument"), "ifnotfound");
2587
2588
120
    ginherits = asLogical(CAD4R(args));
2589
120
    if (ginherits == NA_LOGICAL)
2590
0
  error(_("invalid '%s' argument"), "inherits");
2591
2592
120
    PROTECT(ans = allocVector(VECSXP, nvals));
2593
2594
18.5k
    for(int i = 0; i < nvals; i++) {
2595
18.4k
  Rboolean wants_S4 = FALSE;
2596
18.4k
  const char *modestr = CHAR(STRING_ELT(CADDR(args), i % nmode));
2597
18.4k
  SEXPTYPE gmode = str2mode(modestr, &wants_S4);
2598
18.4k
  SEXP nf = VECTOR_ELT(ifnotfound, i % nifnfnd);
2599
18.4k
  SEXP ans_i = gfind(translateChar(STRING_ELT(x, i % nvals)), env,
2600
18.4k
         gmode, wants_S4, nf, ginherits, rho);
2601
18.4k
  SET_VECTOR_ELT(ans, i, lazy_duplicate(ans_i));
2602
18.4k
    }
2603
2604
120
    setAttrib(ans, R_NamesSymbol, lazy_duplicate(x));
2605
120
    UNPROTECT(2);
2606
120
    return(ans);
2607
120
}
2608
2609
// In Rinternals.h
2610
SEXP R_getVarEx(SEXP sym, SEXP rho, Rboolean inherits, SEXP ifnotfound)
2611
0
{
2612
0
    if (TYPEOF(sym) != SYMSXP)
2613
0
  error(_("first argument to '%s' must be a symbol"), __func__);
2614
0
    if (TYPEOF(rho) != ENVSXP)
2615
0
  error(_("second argument to '%s' must be an environment"), __func__);
2616
2617
0
    SEXP val = inherits ? R_findVar(sym, rho) : R_findVarInFrame(rho, sym);
2618
0
    if (val == R_MissingArg)
2619
0
  R_MissingArgError(sym, getLexicalCall(rho), "getVarExError");
2620
0
    else if (val == R_UnboundValue)
2621
0
  return ifnotfound;
2622
0
    else if (TYPEOF(val) == PROMSXP) {
2623
0
  PROTECT(val);
2624
0
  val = eval(val, rho);
2625
0
  UNPROTECT(1);
2626
0
    }
2627
0
    return val;
2628
0
}
2629
2630
// In Rinternals.h
2631
SEXP R_getVar(SEXP sym, SEXP rho, Rboolean inherits)
2632
0
{
2633
0
    SEXP val = R_getVarEx(sym, rho, inherits, R_UnboundValue);
2634
0
    if (val == R_UnboundValue)
2635
0
  R_ObjectNotFoundError(sym, R_CurrentExpression, NULL);
2636
0
    return val;
2637
0
}
2638
2639
2640
/*----------------------------------------------------------------------
2641
2642
  do_missing
2643
2644
  This function tests whether the symbol passed as its first argument
2645
  is a missing argument to the current closure.  rho is the
2646
  environment that missing was called from.
2647
2648
  R_isMissing is called on the not-yet-evaluated value of an argument,
2649
  if this is a symbol, as it could be a missing argument that has been
2650
  passed down.  So 'symbol' is the promise value, and 'rho' its
2651
  evaluation argument.
2652
2653
  It is also called in arithmetic.c. for e.g. do_log
2654
*/
2655
2656
45.8k
static SEXP findRootPromise(SEXP p) {
2657
45.8k
    if (TYPEOF(p) == PROMSXP) {
2658
21.9k
  while(TYPEOF(PREXPR(p)) == PROMSXP) {
2659
0
      p = PREXPR(p);
2660
0
  }
2661
21.9k
    }
2662
45.8k
    return p;
2663
45.8k
}
2664
2665
// missing() for the case of promise aka *un*evaluated symbol:
2666
attribute_hidden
2667
Rboolean R_isMissing(SEXP symbol, SEXP rho)
2668
31.2k
{
2669
31.2k
    int ddv=0;
2670
31.2k
    SEXP vl, s;
2671
2672
31.2k
    if (symbol == R_MissingArg) /* Yes, this can happen */
2673
0
  return TRUE;
2674
2675
    /* check for infinite recursion */
2676
31.2k
    R_CheckStack();
2677
2678
31.2k
    if (DDVAL(symbol)) {
2679
0
  s = R_DotsSymbol;
2680
0
  ddv = ddVal(symbol);
2681
0
    }
2682
31.2k
    else
2683
31.2k
  s = symbol;
2684
2685
31.2k
    if (rho == R_BaseEnv || rho == R_BaseNamespace)
2686
0
  return FALSE;  /* is this really the right thing to do? LT */
2687
2688
31.2k
    vl = findVarLocInFrame(rho, s, NULL);
2689
31.2k
    if (vl != R_NilValue) {
2690
31.2k
  if (DDVAL(symbol)) {
2691
0
      if (length(CAR(vl)) < ddv || CAR(vl) == R_MissingArg)
2692
0
    return TRUE;
2693
      /* defineVar(symbol, value, R_GlobalEnv); */
2694
0
      else
2695
0
    vl = nthcdr(CAR(vl), ddv-1);
2696
0
  }
2697
31.2k
  if (MISSING(vl) == 1 ||
2698
30.9k
      (BNDCELL_TAG(vl) == 0 && CAR(vl) == R_MissingArg))
2699
312
      return TRUE;
2700
30.9k
  if (IS_ACTIVE_BINDING(vl))
2701
0
      return FALSE;
2702
30.9k
  if (BNDCELL_TAG(vl))
2703
72
      return FALSE;
2704
30.9k
  SETCAR(vl, findRootPromise(CAR(vl)));
2705
30.9k
  if (TYPEOF(CAR(vl)) == PROMSXP &&
2706
7.02k
      ! PROMISE_IS_EVALUATED(CAR(vl)) &&
2707
6.13k
      TYPEOF(PREXPR(CAR(vl))) == SYMSXP) {
2708
      /* This code uses the PRSEEN value to detect cycles.  If a
2709
         cycle occurs then a missing argument was encountered,
2710
         so the return value is TRUE.  It would be a little
2711
         safer to use the promise stack to ensure unsetting of
2712
         the bits in the event of a longjump, but doing so would
2713
         require distinguishing between evaluating promises and
2714
         checking for missingness.  Because of the test above
2715
         for an active binding a longjmp should only happen if
2716
         the stack check fails.  LT */
2717
96
      if (PRSEEN(CAR(vl)) == 1)
2718
0
    return TRUE;
2719
96
      else {
2720
96
    int oldseen = PRSEEN(CAR(vl));
2721
96
    SET_PRSEEN(CAR(vl), 1);
2722
96
    PROTECT(vl);
2723
96
    Rboolean val = R_isMissing(PREXPR(CAR(vl)), PRENV(CAR(vl)));
2724
96
    UNPROTECT(1); /* vl */
2725
    /* The oldseen value will usually be 0, but might be 2
2726
       from an interrupted evaluation. LT */
2727
96
    SET_PRSEEN(CAR(vl), oldseen);
2728
96
    return val;
2729
96
      }
2730
96
  }
2731
30.8k
  else
2732
30.8k
      return FALSE;
2733
30.9k
    }
2734
0
    return FALSE;
2735
31.2k
}
2736
2737
// workhorse of do_missing()  == R's missing(); more generally useful -> ./bind.c
2738
attribute_hidden
2739
Rboolean R_missing(SEXP var, SEXP rho)
2740
146k
{
2741
146k
    int ddv = 0;
2742
146k
    SEXP s = var;
2743
146k
    if (DDVAL(var)) {
2744
0
  ddv = ddVal(var);
2745
0
  var = R_DotsSymbol;
2746
0
    }
2747
2748
146k
    SEXP t = findVarLocInFrame(rho, var, NULL);
2749
146k
    if (t != R_NilValue) {
2750
146k
  if (DDVAL(s)) {
2751
0
      if (length(CAR(t)) < ddv  || CAR(t) == R_MissingArg) {
2752
0
    return TRUE;
2753
0
      }
2754
0
      else
2755
0
    t = nthcdr(CAR(t), ddv-1);
2756
0
  }
2757
146k
  if (BNDCELL_TAG(t)) return FALSE;
2758
146k
  if (MISSING(t) || CAR(t) == R_MissingArg) {
2759
125k
      return TRUE;
2760
125k
  }
2761
146k
    }
2762
0
    else  /* it wasn't an argument to the function */
2763
0
  error(_("'missing(%s)' did not find an argument"), CHAR(PRINTNAME(var)));
2764
2765
21.0k
    t = CAR(t);
2766
21.0k
    if (TYPEOF(t) != PROMSXP) {
2767
6.09k
  return FALSE;
2768
6.09k
    }
2769
    // deal with promise :
2770
14.9k
    t = findRootPromise(t);
2771
14.9k
    if (!isSymbol(PREXPR(t)))
2772
13.2k
  return FALSE;
2773
1.68k
    else {
2774
1.68k
  return R_isMissing(PREXPR(t), PRENV(t));
2775
1.68k
    }
2776
14.9k
}
2777
2778
/* this is primitive and a SPECIALSXP */
2779
attribute_hidden SEXP do_missing(SEXP call, SEXP op, SEXP args, SEXP rho)
2780
146k
{
2781
146k
    checkArity(op, args);
2782
146k
    check1arg(args, call, "x");
2783
146k
    SEXP sym = CAR(args);
2784
146k
    if( isString(sym) && length(sym)==1 )
2785
0
  sym = installTrChar(STRING_ELT(CAR(args), 0));
2786
146k
    if (!isSymbol(sym))
2787
0
  errorcall(call, _("invalid use of 'missing'"));
2788
2789
146k
    SEXP rval = PROTECT(allocVector(LGLSXP, 1));
2790
146k
    LOGICAL(rval)[0] = R_missing(sym, rho);
2791
146k
    UNPROTECT(1);
2792
146k
    return rval;
2793
146k
}
2794
2795
/*----------------------------------------------------------------------
2796
2797
  do_globalenv
2798
2799
  Returns the current global environment.
2800
2801
*/
2802
2803
2804
attribute_hidden SEXP do_globalenv(SEXP call, SEXP op, SEXP args, SEXP rho)
2805
24
{
2806
24
    checkArity(op, args);
2807
24
    return R_GlobalEnv;
2808
24
}
2809
2810
/*----------------------------------------------------------------------
2811
2812
  do_baseenv
2813
2814
  Returns the current base environment.
2815
2816
*/
2817
2818
2819
attribute_hidden SEXP do_baseenv(SEXP call, SEXP op, SEXP args, SEXP rho)
2820
16.2k
{
2821
16.2k
    checkArity(op, args);
2822
16.2k
    return R_BaseEnv;
2823
16.2k
}
2824
2825
/*----------------------------------------------------------------------
2826
2827
  do_emptyenv
2828
2829
  Returns the current empty environment.
2830
2831
*/
2832
2833
2834
attribute_hidden SEXP do_emptyenv(SEXP call, SEXP op, SEXP args, SEXP rho)
2835
0
{
2836
0
    checkArity(op, args);
2837
0
    return R_EmptyEnv;
2838
0
}
2839
2840
2841
/*----------------------------------------------------------------------
2842
2843
  do_attach
2844
2845
  To attach a list we make up an environment and insert components
2846
  of the list in as the values of this env and install the tags from
2847
  the list as the names.
2848
2849
*/
2850
2851
static void set_attach_frame_value(SEXP p, SEXP s)
2852
0
{
2853
0
    if (IS_ACTIVE_BINDING(p))
2854
0
  R_MakeActiveBinding(TAG(p), CAR(p), s);
2855
0
    else
2856
0
  defineVar(TAG(p), lazy_duplicate(CAR(p)), s);
2857
0
}
2858
2859
attribute_hidden SEXP do_attach(SEXP call, SEXP op, SEXP args, SEXP env)
2860
84
{
2861
84
    SEXP name, s, t, x;
2862
84
    int pos, hsize;
2863
84
    Rboolean isSpecial;
2864
2865
84
    checkArity(op, args);
2866
2867
84
    pos = asInteger(CADR(args));
2868
84
    if (pos == NA_INTEGER)
2869
0
  error(_("'pos' must be an integer"));
2870
2871
84
    name = CADDR(args);
2872
84
    if (!isValidStringF(name))
2873
0
  error(_("invalid '%s' argument"), "name");
2874
2875
84
    isSpecial = IS_USER_DATABASE(CAR(args));
2876
2877
84
    if(!isSpecial) {
2878
84
  if (isNewList(CAR(args))) {
2879
84
      SETCAR(args, VectorToPairList(CAR(args)));
2880
2881
84
      for (x = CAR(args); x != R_NilValue; x = CDR(x))
2882
0
    if (TAG(x) == R_NilValue)
2883
0
        error(_("all elements of a list must be named"));
2884
84
      PROTECT(s = allocSExp(ENVSXP));
2885
84
      SET_FRAME(s, shallow_duplicate(CAR(args)));
2886
84
  } else if (isEnvironment(CAR(args))) {
2887
0
      SEXP p, loadenv = CAR(args);
2888
2889
0
      PROTECT(s = allocSExp(ENVSXP));
2890
0
      if (HASHTAB(loadenv) != R_NilValue) {
2891
0
    int i, n;
2892
0
    n = length(HASHTAB(loadenv));
2893
0
    for (i = 0; i < n; i++) {
2894
0
        p = VECTOR_ELT(HASHTAB(loadenv), i);
2895
0
        while (p != R_NilValue) {
2896
0
      set_attach_frame_value(p, s);
2897
0
      p = CDR(p);
2898
0
        }
2899
0
    }
2900
    /* FIXME: duplicate the hash table and assign here */
2901
0
      } else {
2902
0
    for(p = FRAME(loadenv); p != R_NilValue; p = CDR(p))
2903
0
        set_attach_frame_value(p, s);
2904
0
      }
2905
0
  } else {
2906
0
      error(_("'attach' only works for lists, data frames and environments"));
2907
0
      s = R_NilValue; /* -Wall */
2908
0
  }
2909
2910
  /* Connect FRAME(s) into HASHTAB(s) */
2911
84
  if (length(s) < HASHMINSIZE)
2912
84
      hsize = HASHMINSIZE;
2913
0
  else
2914
0
      hsize = length(s);
2915
2916
84
  SET_HASHTAB(s, R_NewHashTable(hsize));
2917
84
  s = R_HashFrame(s);
2918
2919
  /* FIXME: A little inefficient */
2920
84
  while (R_HashSizeCheck(HASHTAB(s)))
2921
0
      SET_HASHTAB(s, R_HashResize(HASHTAB(s)));
2922
2923
84
    } else { /* is a user object */
2924
  /* Having this here (rather than below) means that the onAttach routine
2925
     is called before the table is attached. This may not be necessary or
2926
     desirable. */
2927
0
  R_ObjectTable *tb = (R_ObjectTable*) R_ExternalPtrAddr(CAR(args));
2928
0
  if(tb->onAttach)
2929
0
      tb->onAttach(tb);
2930
0
  PROTECT(s = allocSExp(ENVSXP));
2931
0
  SET_HASHTAB(s, CAR(args));
2932
0
  setAttrib(s, R_ClassSymbol, getAttrib(HASHTAB(s), R_ClassSymbol));
2933
0
    }
2934
2935
84
    setAttrib(s, R_NameSymbol, name);
2936
84
    for (t = R_GlobalEnv; ENCLOS(t) != R_BaseEnv && pos > 2; t = ENCLOS(t))
2937
0
  pos--;
2938
2939
84
    if (ENCLOS(t) == R_BaseEnv) {
2940
12
  SET_ENCLOS(t, s);
2941
12
  SET_ENCLOS(s, R_BaseEnv);
2942
12
    }
2943
72
    else {
2944
72
  x = ENCLOS(t);
2945
72
  SET_ENCLOS(t, s);
2946
72
  SET_ENCLOS(s, x);
2947
72
    }
2948
2949
84
    if(!isSpecial) { /* Temporary: need to remove the elements identified by objects(CAR(args)) */
2950
84
#ifdef USE_GLOBAL_CACHE
2951
84
  R_FlushGlobalCacheFromTable(HASHTAB(s));
2952
84
  MARK_AS_GLOBAL_FRAME(s);
2953
84
#endif
2954
84
    } else {
2955
0
#ifdef USE_GLOBAL_CACHE
2956
0
  R_FlushGlobalCacheFromUserTable(HASHTAB(s));
2957
0
  MARK_AS_GLOBAL_FRAME(s);
2958
0
#endif
2959
0
    }
2960
2961
84
    UNPROTECT(1); /* s */
2962
84
    return s;
2963
84
}
2964
2965
2966
2967
/*----------------------------------------------------------------------
2968
2969
  do_detach
2970
2971
  detach the specified environment.  Detachment only takes place by
2972
  position.
2973
2974
*/
2975
2976
attribute_hidden SEXP do_detach(SEXP call, SEXP op, SEXP args, SEXP env)
2977
0
{
2978
0
    SEXP s, t, x;
2979
0
    int pos, n;
2980
0
    Rboolean isSpecial = FALSE;
2981
2982
0
    checkArity(op, args);
2983
0
    pos = asInteger(CAR(args));
2984
2985
0
    for (n = 2, t = ENCLOS(R_GlobalEnv); t != R_BaseEnv; t = ENCLOS(t))
2986
0
  n++;
2987
2988
0
    if (pos == n) /* n is the length of the search list */
2989
0
  error(_("detaching \"package:base\" is not allowed"));
2990
2991
0
    for (t = R_GlobalEnv ; ENCLOS(t) != R_BaseEnv && pos > 2 ; t = ENCLOS(t))
2992
0
  pos--;
2993
0
    if (pos != 2) {
2994
0
  error(_("invalid '%s' argument"), "pos");
2995
0
  s = t;  /* for -Wall */
2996
0
    }
2997
0
    else {
2998
0
  PROTECT(s = ENCLOS(t));
2999
0
  x = ENCLOS(s);
3000
0
  SET_ENCLOS(t, x);
3001
0
  isSpecial = IS_USER_DATABASE(s);
3002
0
  if(isSpecial) {
3003
0
      R_ObjectTable *tb = (R_ObjectTable*) R_ExternalPtrAddr(HASHTAB(s));
3004
0
      if(tb->onDetach) tb->onDetach(tb);
3005
0
  }
3006
3007
0
  SET_ENCLOS(s, R_BaseEnv);
3008
0
    }
3009
0
#ifdef USE_GLOBAL_CACHE
3010
0
    if(!isSpecial) {
3011
0
  R_FlushGlobalCacheFromTable(HASHTAB(s));
3012
0
  MARK_AS_LOCAL_FRAME(s);
3013
0
    } else {
3014
0
  R_FlushGlobalCacheFromUserTable(HASHTAB(s));
3015
0
  MARK_AS_LOCAL_FRAME(s); /* was _GLOBAL_ prior to 2.4.0 */
3016
0
    }
3017
0
#endif
3018
0
    UNPROTECT(1);
3019
0
    return s;
3020
0
}
3021
3022
3023
3024
/*----------------------------------------------------------------------
3025
3026
  do_search
3027
3028
  Print out the current search path.
3029
3030
*/
3031
3032
attribute_hidden SEXP do_search(SEXP call, SEXP op, SEXP args, SEXP env)
3033
314
{
3034
314
    SEXP ans, name, t;
3035
314
    int i, n;
3036
3037
314
    checkArity(op, args);
3038
314
    n = 2;
3039
1.50k
    for (t = ENCLOS(R_GlobalEnv); t != R_BaseEnv ; t = ENCLOS(t))
3040
1.19k
  n++;
3041
314
    PROTECT(ans = allocVector(STRSXP, n));
3042
    /* TODO - what should the name of this be? */
3043
314
    SET_STRING_ELT(ans, 0, mkChar(".GlobalEnv"));
3044
314
    SET_STRING_ELT(ans, n-1, mkChar("package:base"));
3045
314
    i = 1;
3046
1.50k
    for (t = ENCLOS(R_GlobalEnv); t != R_BaseEnv ; t = ENCLOS(t)) {
3047
1.19k
  name = getAttrib(t, R_NameSymbol);
3048
1.19k
  if (!isString(name) || length(name) < 1)
3049
0
      SET_STRING_ELT(ans, i, mkChar("(unknown)"));
3050
1.19k
  else
3051
1.19k
      SET_STRING_ELT(ans, i, STRING_ELT(name, 0));
3052
1.19k
  i++;
3053
1.19k
    }
3054
314
    UNPROTECT(1);
3055
314
    return ans;
3056
314
}
3057
3058
3059
/*----------------------------------------------------------------------
3060
3061
  do_ls
3062
3063
  This code implements the functionality of the "ls" and "objects"
3064
  functions.  [ ls(envir, all.names, sorted) ]
3065
3066
*/
3067
#define NONEMPTY_(_FRAME_) \
3068
0
    CHAR(PRINTNAME(TAG(_FRAME_)))[0] != '.'
3069
3070
static int FrameSize(SEXP frame, int all)
3071
182k
{
3072
182k
    int count = 0;
3073
182k
    if (all) {
3074
378k
  while (frame != R_NilValue) {
3075
195k
      count += 1;
3076
195k
      frame = CDR(frame);
3077
195k
  }
3078
182k
    } else {
3079
0
  while (frame != R_NilValue) {
3080
0
      if (NONEMPTY_(frame))
3081
0
    count += 1;
3082
0
      frame = CDR(frame);
3083
0
  }
3084
0
    }
3085
182k
    return count;
3086
182k
}
3087
3088
static void FrameNames(SEXP frame, int all, SEXP names, int *indx)
3089
182k
{
3090
182k
    if (all) {
3091
378k
  while (frame != R_NilValue) {
3092
195k
      SET_STRING_ELT(names, *indx, PRINTNAME(TAG(frame)));
3093
195k
      (*indx)++;
3094
195k
      frame = CDR(frame);
3095
195k
  }
3096
182k
    } else {
3097
0
  while (frame != R_NilValue) {
3098
0
      if (NONEMPTY_(frame)) {
3099
0
    SET_STRING_ELT(names, *indx, PRINTNAME(TAG(frame)));
3100
0
    (*indx)++;
3101
0
      }
3102
0
      frame = CDR(frame);
3103
0
  }
3104
0
    }
3105
182k
}
3106
3107
static void FrameValues(SEXP frame, int all, SEXP values, int *indx)
3108
0
{
3109
0
    if (all) {
3110
0
  while (frame != R_NilValue) {
3111
0
#         define DO_FrameValues           \
3112
0
      SEXP value = BINDING_VALUE(frame);        \
3113
0
      if (TYPEOF(value) == PROMSXP) {       \
3114
0
    PROTECT(value);            \
3115
0
    value = eval(value, R_GlobalEnv);     \
3116
0
    UNPROTECT(1);            \
3117
0
      }               \
3118
0
      SET_VECTOR_ELT(values, *indx, lazy_duplicate(value)); \
3119
0
      (*indx)++
3120
3121
0
      DO_FrameValues;
3122
0
      frame = CDR(frame);
3123
0
  }
3124
0
    } else {
3125
0
  while (frame != R_NilValue) {
3126
0
      if (NONEMPTY_(frame)) {
3127
0
    DO_FrameValues;
3128
0
      }
3129
0
      frame = CDR(frame);
3130
0
  }
3131
0
    }
3132
0
}
3133
#undef DO_FrameValues
3134
#undef NONEMPTY_
3135
3136
1.89k
#define CHECK_HASH_TABLE(table) do {   \
3137
1.89k
  if (TYPEOF(table) != VECSXP)   \
3138
1.89k
      error("bad hash table contents"); \
3139
1.89k
    } while (0)
3140
3141
static int HashTableSize(SEXP table, int all)
3142
948
{
3143
948
    CHECK_HASH_TABLE(table);
3144
948
    int count = 0;
3145
948
    int n = length(table);
3146
948
    int i;
3147
183k
    for (i = 0; i < n; i++)
3148
182k
  count += FrameSize(VECTOR_ELT(table, i), all);
3149
948
    return count;
3150
948
}
3151
3152
static void HashTableNames(SEXP table, int all, SEXP names, int *indx)
3153
948
{
3154
948
    CHECK_HASH_TABLE(table);
3155
948
    int n = length(table);
3156
948
    int i;
3157
183k
    for (i = 0; i < n; i++)
3158
182k
  FrameNames(VECTOR_ELT(table, i), all, names, indx);
3159
948
}
3160
3161
static void HashTableValues(SEXP table, int all, SEXP values, int *indx)
3162
0
{
3163
0
    CHECK_HASH_TABLE(table);
3164
0
    int n = length(table);
3165
0
    int i;
3166
0
    for (i = 0; i < n; i++)
3167
0
  FrameValues(VECTOR_ELT(table, i), all, values, indx);
3168
0
}
3169
3170
static int BuiltinSize(int all, int intern)
3171
84
{
3172
84
    int count = 0;
3173
84
    SEXP s;
3174
84
    int j;
3175
4.12M
    for (j = 0; j < HSIZE; j++) {
3176
4.51M
  for (s = R_SymbolTable[j]; s != R_NilValue; s = CDR(s)) {
3177
390k
      if (intern) {
3178
0
    if (INTERNAL(CAR(s)) != R_NilValue)
3179
0
        count++;
3180
0
      }
3181
390k
      else {
3182
390k
    if ((all || CHAR(PRINTNAME(CAR(s)))[0] != '.')
3183
390k
        && SYMVALUE(CAR(s)) != R_UnboundValue)
3184
118k
        count++;
3185
390k
      }
3186
390k
  }
3187
4.12M
    }
3188
84
    return count;
3189
84
}
3190
3191
static void
3192
BuiltinNames(int all, int intern, SEXP names, int *indx)
3193
84
{
3194
84
    SEXP s;
3195
84
    int j;
3196
4.12M
    for (j = 0; j < HSIZE; j++) {
3197
4.51M
  for (s = R_SymbolTable[j]; s != R_NilValue; s = CDR(s)) {
3198
390k
      if (intern) {
3199
0
    if (INTERNAL(CAR(s)) != R_NilValue)
3200
0
        SET_STRING_ELT(names, (*indx)++, PRINTNAME(CAR(s)));
3201
0
      }
3202
390k
      else {
3203
390k
    if ((all || CHAR(PRINTNAME(CAR(s)))[0] != '.')
3204
390k
        && SYMVALUE(CAR(s)) != R_UnboundValue)
3205
118k
        SET_STRING_ELT(names, (*indx)++, PRINTNAME(CAR(s)));
3206
390k
      }
3207
390k
  }
3208
4.12M
    }
3209
84
}
3210
3211
static void
3212
BuiltinValues(int all, int intern, SEXP values, int *indx)
3213
0
{
3214
0
    SEXP s, vl;
3215
0
    int j;
3216
0
    for (j = 0; j < HSIZE; j++) {
3217
0
  for (s = R_SymbolTable[j]; s != R_NilValue; s = CDR(s)) {
3218
0
      if (intern) {
3219
0
    if (INTERNAL(CAR(s)) != R_NilValue) {
3220
0
        vl = SYMVALUE(CAR(s));
3221
0
        if (TYPEOF(vl) == PROMSXP) {
3222
0
      PROTECT(vl);
3223
0
      vl = eval(vl, R_BaseEnv);
3224
0
      UNPROTECT(1);
3225
0
        }
3226
0
        SET_VECTOR_ELT(values, (*indx)++, lazy_duplicate(vl));
3227
0
    }
3228
0
      }
3229
0
      else {
3230
0
    if ((all || CHAR(PRINTNAME(CAR(s)))[0] != '.')
3231
0
        && SYMVALUE(CAR(s)) != R_UnboundValue) {
3232
0
        vl = SYMVALUE(CAR(s));
3233
0
        if (TYPEOF(vl) == PROMSXP) {
3234
0
      PROTECT(vl);
3235
0
      vl = eval(vl, R_BaseEnv);
3236
0
      UNPROTECT(1);
3237
0
        }
3238
0
        SET_VECTOR_ELT(values, (*indx)++, lazy_duplicate(vl));
3239
0
    }
3240
0
      }
3241
0
  }
3242
0
    }
3243
0
}
3244
3245
// .Internal(ls(envir, all.names, sorted)) :
3246
attribute_hidden SEXP do_ls(SEXP call, SEXP op, SEXP args, SEXP rho)
3247
36
{
3248
36
    checkArity(op, args);
3249
3250
36
    if(IS_USER_DATABASE(CAR(args))) {
3251
0
  R_ObjectTable *tb = (R_ObjectTable*)
3252
0
      R_ExternalPtrAddr(HASHTAB(CAR(args)));
3253
0
  return(tb->objects(tb));
3254
0
    }
3255
3256
36
    SEXP env = CAR(args);
3257
3258
    /* if (env == R_BaseNamespace) env = R_BaseEnv; */
3259
3260
36
    int all = asLogical(CADR(args));
3261
36
    if (all == NA_LOGICAL) all = 0;
3262
3263
36
    int sort_nms = asLogical(CADDR(args)); /* sorted = TRUE/FALSE */
3264
36
    if (sort_nms == NA_LOGICAL) sort_nms = 0;
3265
3266
36
    return R_lsInternal3(env, (Rboolean) all, (Rboolean) sort_nms);
3267
36
}
3268
3269
/* takes an environment, a boolean indicating whether to get all
3270
   names and a boolean if sorted is desired */
3271
// In Rinternals.h
3272
SEXP R_lsInternal3(SEXP env, Rboolean all, Rboolean sorted)
3273
1.03k
{
3274
1.03k
    if(IS_USER_DATABASE(env)) {
3275
0
  R_ObjectTable *tb = (R_ObjectTable*)
3276
0
      R_ExternalPtrAddr(HASHTAB(env));
3277
0
  return(tb->objects(tb));
3278
0
    }
3279
3280
    /* Step 1 : Compute the Vector Size */
3281
1.03k
    int k = 0;
3282
1.03k
    if (env == R_BaseEnv || env == R_BaseNamespace)
3283
84
  k += BuiltinSize(all, 0);
3284
948
    else if (isEnvironment(env) ||
3285
948
  isEnvironment(env = simple_as_environment(env))) {
3286
948
  if (HASHTAB(env) != R_NilValue)
3287
948
      k += HashTableSize(HASHTAB(env), all);
3288
0
  else
3289
0
      k += FrameSize(FRAME(env), all);
3290
948
    }
3291
0
    else
3292
0
  error(_("invalid '%s' argument"), "envir");
3293
3294
    /* Step 2 : Allocate and Fill the Result */
3295
1.03k
    SEXP ans = PROTECT(allocVector(STRSXP, k));
3296
1.03k
    k = 0;
3297
1.03k
    if (env == R_BaseEnv || env == R_BaseNamespace)
3298
84
  BuiltinNames(all, 0, ans, &k);
3299
948
    else if (isEnvironment(env)) {
3300
948
  if (HASHTAB(env) != R_NilValue)
3301
948
      HashTableNames(HASHTAB(env), all, ans, &k);
3302
0
  else
3303
0
      FrameNames(FRAME(env), all, ans, &k);
3304
948
    }
3305
3306
1.03k
    if(sorted) sortVector(ans, FALSE);
3307
1.03k
    UNPROTECT(1);
3308
1.03k
    return ans;
3309
1.03k
}
3310
3311
/* non-API version used in several packages */
3312
// in Rinternals.h
3313
SEXP R_lsInternal(SEXP env, Rboolean all)
3314
0
{
3315
0
    return R_lsInternal3(env, all, TRUE);
3316
0
}
3317
3318
SEXP R_envSymbols(SEXP env)
3319
0
{
3320
    // this could be rewritten to avoid allocating the intermediate STRSXP
3321
    // this would be mor efficient for non-USER-DATABASE environments
3322
0
    SEXP names = PROTECT(R_lsInternal3(env, TRUE, FALSE));
3323
0
    R_xlen_t n = XLENGTH(names);
3324
0
    SEXP val = PROTECT(allocVector(VECSXP, n));
3325
0
    for (R_xlen_t i = 0; i < n; i++)
3326
0
  SET_VECTOR_ELT(val, i, installChar(STRING_ELT(names, i)));
3327
0
    UNPROTECT(2); // names, val
3328
0
    return val;      
3329
0
}
3330
3331
/* transform an environment into a named list: as.list.environment(.) */
3332
3333
attribute_hidden SEXP do_env2list(SEXP call, SEXP op, SEXP args, SEXP rho)
3334
0
{
3335
0
    SEXP env, ans, names;
3336
0
    int k, all;
3337
3338
0
    checkArity(op, args);
3339
3340
0
    env = CAR(args);
3341
0
    if (ISNULL(env))
3342
0
  error(_("use of NULL environment is defunct"));
3343
0
    if( !isEnvironment(env) ) {
3344
0
  SEXP xdata;
3345
0
  if( IS_S4_OBJECT(env) && TYPEOF(env) == OBJSXP &&
3346
0
      (xdata = R_getS4DataSlot(env, ENVSXP)) != R_NilValue)
3347
0
      env = xdata;
3348
0
  else
3349
0
      error(_("argument must be an environment"));
3350
0
    }
3351
3352
0
    all = asLogical(CADR(args)); /* all.names = TRUE/FALSE */
3353
0
    if (all == NA_LOGICAL) all = 0;
3354
3355
0
    int sort_nms = asLogical(CADDR(args)); /* sorted = TRUE/FALSE */
3356
0
    if (sort_nms == NA_LOGICAL) sort_nms = 0;
3357
3358
    // k := length(env) = envxlength(env) :
3359
0
    if (env == R_BaseEnv || env == R_BaseNamespace)
3360
0
  k = BuiltinSize(all, 0);
3361
0
    else if (HASHTAB(env) != R_NilValue)
3362
0
  k = HashTableSize(HASHTAB(env), all);
3363
0
    else
3364
0
  k = FrameSize(FRAME(env), all);
3365
3366
0
    PROTECT(names = allocVector(STRSXP, k));
3367
0
    PROTECT(ans = allocVector(VECSXP, k));
3368
3369
0
    k = 0;
3370
0
    if (env == R_BaseEnv || env == R_BaseNamespace)
3371
0
  BuiltinValues(all, 0, ans, &k);
3372
0
    else if (HASHTAB(env) != R_NilValue)
3373
0
  HashTableValues(HASHTAB(env), all, ans, &k);
3374
0
    else
3375
0
  FrameValues(FRAME(env), all, ans, &k);
3376
3377
0
    k = 0;
3378
0
    if (env == R_BaseEnv || env == R_BaseNamespace)
3379
0
  BuiltinNames(all, 0, names, &k);
3380
0
    else if (HASHTAB(env) != R_NilValue)
3381
0
  HashTableNames(HASHTAB(env), all, names, &k);
3382
0
    else
3383
0
  FrameNames(FRAME(env), all, names, &k);
3384
3385
0
    if(k == 0) { // no sorting, keep NULL names
3386
0
  UNPROTECT(2);
3387
0
  return(ans);
3388
0
    }
3389
0
    if(sort_nms) {
3390
  // return list with *sorted* names
3391
0
  SEXP sind = PROTECT(allocVector(INTSXP, k));
3392
0
  int *indx = INTEGER(sind);
3393
0
  for (int i = 0; i < k; i++) indx[i] = i;
3394
0
  orderVector1(indx, k, names, /* nalast */ true, /* decreasing */ false,
3395
0
         R_NilValue);
3396
0
  SEXP ans2   = PROTECT(allocVector(VECSXP, k));
3397
0
  SEXP names2 = PROTECT(allocVector(STRSXP, k));
3398
0
  for(int i = 0; i < k; i++) {
3399
0
      SET_STRING_ELT(names2, i, STRING_ELT(names, indx[i]));
3400
0
      SET_VECTOR_ELT(ans2,   i, VECTOR_ELT(ans,   indx[i]));
3401
0
  }
3402
0
  setAttrib(ans2, R_NamesSymbol, names2);
3403
0
  UNPROTECT(5);
3404
0
  return(ans2);
3405
0
    }
3406
0
    else {
3407
0
  setAttrib(ans, R_NamesSymbol, names);
3408
0
  UNPROTECT(2);
3409
0
  return(ans);
3410
0
    }
3411
0
}
3412
3413
/*
3414
 * apply a function to all objects in an environment and return the
3415
 * results in a list.
3416
 * Equivalent to lapply(as.list(env, all.names=all.names), FUN, ...)
3417
 */
3418
/* This is a special .Internal */
3419
attribute_hidden SEXP do_eapply(SEXP call, SEXP op, SEXP args, SEXP rho)
3420
0
{
3421
0
    SEXP env, ans, R_fcall, FUN, tmp, tmp2, ind;
3422
0
    int i, k, k2;
3423
0
    int /* boolean */ all, useNms;
3424
3425
0
    checkArity(op, args);
3426
3427
0
    PROTECT(env = eval(CAR(args), rho));
3428
0
    if (ISNULL(env))
3429
0
  error(_("use of NULL environment is defunct"));
3430
0
    if( !isEnvironment(env) )
3431
0
  error(_("argument must be an environment"));
3432
3433
0
    FUN = CADR(args);
3434
0
    if (!isSymbol(FUN))
3435
0
  error(_("arguments must be symbolic"));
3436
3437
    /* 'all.names' : */
3438
0
    all = asLogical(PROTECT(eval(CADDR(args), rho)));
3439
0
    UNPROTECT(1);
3440
0
    if (all == NA_LOGICAL) all = 0;
3441
3442
    /* 'USE.NAMES' : */
3443
0
    useNms = asLogical(PROTECT(eval(CADDDR(args), rho)));
3444
0
    UNPROTECT(1);
3445
0
    if (useNms == NA_LOGICAL) useNms = 0;
3446
3447
0
    if (env == R_BaseEnv || env == R_BaseNamespace)
3448
0
  k = BuiltinSize(all, 0);
3449
0
    else if (HASHTAB(env) != R_NilValue)
3450
0
  k = HashTableSize(HASHTAB(env), all);
3451
0
    else
3452
0
  k = FrameSize(FRAME(env), all);
3453
3454
0
    PROTECT(ans  = allocVector(VECSXP, k));
3455
0
    PROTECT(tmp2 = allocVector(VECSXP, k));
3456
3457
0
    k2 = 0;
3458
0
    if (env == R_BaseEnv || env == R_BaseNamespace)
3459
0
  BuiltinValues(all, 0, tmp2, &k2);
3460
0
    else if (HASHTAB(env) != R_NilValue)
3461
0
  HashTableValues(HASHTAB(env), all, tmp2, &k2);
3462
0
    else
3463
0
  FrameValues(FRAME(env), all, tmp2, &k2);
3464
3465
0
    SEXP Xsym = install("X");
3466
0
    SEXP isym = install("i");
3467
0
    PROTECT(ind = allocVector(INTSXP, 1));
3468
    /* tmp :=  `[`(<elist>, i) */
3469
0
    PROTECT(tmp = LCONS(R_Bracket2Symbol,
3470
0
      LCONS(Xsym, LCONS(isym, R_NilValue))));
3471
    /* fcall :=  <FUN>( tmp, ... ) */
3472
0
    PROTECT(R_fcall = LCONS(FUN, LCONS(tmp, LCONS(R_DotsSymbol, R_NilValue))));
3473
3474
0
    defineVar(Xsym, tmp2, rho);
3475
0
    INCREMENT_NAMED(tmp2);
3476
0
    defineVar(isym, ind, rho);
3477
0
    INCREMENT_NAMED(ind);
3478
3479
0
    for(i = 0; i < k2; i++) {
3480
0
  INTEGER(ind)[0] = i+1;
3481
0
  SEXP tmp = R_forceAndCall(R_fcall, 1, rho);
3482
0
  if (MAYBE_REFERENCED(tmp))
3483
0
      tmp = lazy_duplicate(tmp);
3484
0
  SET_VECTOR_ELT(ans, i, tmp);
3485
0
    }
3486
3487
0
    if (useNms) {
3488
0
  SEXP names;
3489
0
  PROTECT(names = allocVector(STRSXP, k));
3490
0
  k = 0;
3491
0
  if (env == R_BaseEnv || env == R_BaseNamespace)
3492
0
      BuiltinNames(all, 0, names, &k);
3493
0
  else if(HASHTAB(env) != R_NilValue)
3494
0
      HashTableNames(HASHTAB(env), all, names, &k);
3495
0
  else
3496
0
      FrameNames(FRAME(env), all, names, &k);
3497
3498
0
  setAttrib(ans, R_NamesSymbol, names);
3499
0
  UNPROTECT(1);
3500
0
    }
3501
0
    UNPROTECT(6);
3502
0
    return(ans);
3503
0
}
3504
3505
/* Leaks out via inlining in ../library/tools/src/ */
3506
#define R_ENVLENGTH(NAME_, LENGTH_FN_, TYPE_)       \
3507
84
TYPE_ NAME_(SEXP rho)             \
3508
84
{                 \
3509
84
    if(IS_USER_DATABASE(rho)) {           \
3510
0
  R_ObjectTable *tb = (R_ObjectTable*) R_ExternalPtrAddr(HASHTAB(rho)); \
3511
0
  return LENGTH_FN_(tb->objects(tb));        \
3512
84
    } else if( HASHTAB(rho) != R_NilValue)       \
3513
84
  return HashTableSize(HASHTAB(rho), 1);       \
3514
84
    else if (rho == R_BaseEnv || rho == R_BaseNamespace)     \
3515
84
  return BuiltinSize(1, 0);         \
3516
84
    else                \
3517
84
  return FrameSize(FRAME(rho), 1);       \
3518
84
}
Rf_envlength
Line
Count
Source
3507
84
TYPE_ NAME_(SEXP rho)             \
3508
84
{                 \
3509
84
    if(IS_USER_DATABASE(rho)) {           \
3510
0
  R_ObjectTable *tb = (R_ObjectTable*) R_ExternalPtrAddr(HASHTAB(rho)); \
3511
0
  return LENGTH_FN_(tb->objects(tb));        \
3512
84
    } else if( HASHTAB(rho) != R_NilValue)       \
3513
84
  return HashTableSize(HASHTAB(rho), 1);       \
3514
84
    else if (rho == R_BaseEnv || rho == R_BaseNamespace)     \
3515
84
  return BuiltinSize(1, 0);         \
3516
84
    else                \
3517
84
  return FrameSize(FRAME(rho), 1);       \
3518
84
}
Unexecuted instantiation: Rf_envxlength
3519
3520
0
R_ENVLENGTH(Rf_envlength,   length, int)
3521
3522
0
R_ENVLENGTH(Rf_envxlength, xlength, R_xlen_t)
3523
3524
/*----------------------------------------------------------------------
3525
3526
  do_builtins
3527
3528
  Return the names of all the built in functions.  These are fetched
3529
  directly from the symbol table.
3530
3531
*/
3532
3533
attribute_hidden SEXP do_builtins(SEXP call, SEXP op, SEXP args, SEXP rho)
3534
0
{
3535
0
    SEXP ans;
3536
0
    int intern, nelts;
3537
0
    checkArity(op, args);
3538
0
    intern = asLogical(CAR(args));
3539
0
    if (intern == NA_INTEGER) intern = 0;
3540
0
    nelts = BuiltinSize(1, intern);
3541
0
    PROTECT(ans = allocVector(STRSXP, nelts));
3542
0
    nelts = 0;
3543
0
    BuiltinNames(1, intern, ans, &nelts);
3544
0
    sortVector(ans, TRUE);
3545
0
    UNPROTECT(1); /* ans */
3546
0
    return ans;
3547
0
}
3548
3549
3550
/*----------------------------------------------------------------------
3551
3552
  do_pos2env
3553
3554
  This function returns the environment at a specified position in the
3555
  search path or the environment of the caller of
3556
  pos.to.env (? but pos.to.env is usually used in arg lists and hence
3557
  is evaluated in the calling environment so this is one higher).
3558
3559
  When pos = -1 the environment of the closure that pos2env is
3560
  evaluated in is obtained. Note: this relies on pos.to.env being
3561
  a primitive.
3562
3563
 */
3564
static SEXP pos2env(int pos, SEXP call)
3565
840
{
3566
840
    SEXP env;
3567
840
    RCNTXT *cptr;
3568
3569
840
    if (pos == NA_INTEGER || pos < -1 || pos == 0) {
3570
0
  errorcall(call, _("invalid '%s' argument"), "pos");
3571
0
  env = call;/* just for -Wall */
3572
0
    }
3573
840
    else if (pos == -1) {
3574
  /* make sure the context is a funcall */
3575
228
  cptr = R_GlobalContext;
3576
228
  while( !(cptr->callflag & CTXT_FUNCTION) && cptr->nextcontext
3577
0
         != NULL )
3578
0
      cptr = cptr->nextcontext;
3579
228
  if( !(cptr->callflag & CTXT_FUNCTION) )
3580
0
      errorcall(call, _("no enclosing environment"));
3581
3582
228
  env = cptr->sysparent;
3583
228
  if (R_GlobalEnv != R_NilValue && env == R_NilValue)
3584
0
      errorcall(call, _("invalid '%s' argument"), "pos");
3585
228
    }
3586
612
    else {
3587
1.81k
  for (env = R_GlobalEnv; env != R_EmptyEnv && pos > 1;
3588
1.20k
       env = ENCLOS(env))
3589
1.20k
      pos--;
3590
612
  if (pos != 1)
3591
0
      errorcall(call, _("invalid '%s' argument"), "pos");
3592
612
    }
3593
840
    return env;
3594
840
}
3595
3596
/* this is primitive */
3597
attribute_hidden SEXP do_pos2env(SEXP call, SEXP op, SEXP args, SEXP rho)
3598
840
{
3599
840
    SEXP env, pos;
3600
840
    int i, npos;
3601
840
    checkArity(op, args);
3602
840
    check1arg(args, call, "x");
3603
3604
840
    PROTECT(pos = coerceVector(CAR(args), INTSXP));
3605
840
    npos = length(pos);
3606
840
    if (npos <= 0)
3607
0
  errorcall(call, _("invalid '%s' argument"), "pos");
3608
840
    if (npos == 1)
3609
840
  env = pos2env(INTEGER(pos)[0], call);
3610
0
    else {
3611
0
  PROTECT(env = allocVector(VECSXP, npos));
3612
0
  for (i = 0; i < npos; i++) {
3613
0
      SET_VECTOR_ELT(env, i, pos2env(INTEGER(pos)[i], call));
3614
0
  }
3615
0
  UNPROTECT(1); /* env */
3616
0
    }
3617
840
    UNPROTECT(1); /* pos */
3618
840
    return env;
3619
840
}
3620
3621
static SEXP matchEnvir(SEXP call, const char *what)
3622
0
{
3623
0
    SEXP t, name;
3624
0
    const void *vmax = vmaxget();
3625
0
    if(!strcmp(".GlobalEnv", what))
3626
0
  return R_GlobalEnv;
3627
0
    if(!strcmp("package:base", what))
3628
0
  return R_BaseEnv;
3629
0
    for (t = ENCLOS(R_GlobalEnv); t != R_EmptyEnv ; t = ENCLOS(t)) {
3630
0
  name = getAttrib(t, R_NameSymbol);
3631
0
  if(isString(name) && length(name) > 0 &&
3632
0
     !strcmp(translateChar(STRING_ELT(name, 0)), what)) {
3633
0
      vmaxset(vmax);
3634
0
      return t;
3635
0
  }
3636
0
    }
3637
0
    errorcall(call, _("no item called \"%s\" on the search list"), what);
3638
    /* not reached */
3639
0
    vmaxset(vmax);
3640
0
    return R_NilValue;
3641
0
}
3642
3643
/* This is primitive */
3644
attribute_hidden SEXP
3645
do_as_environment(SEXP call, SEXP op, SEXP args, SEXP rho)
3646
996
{
3647
996
    SEXP arg = CAR(args), ans;
3648
996
    checkArity(op, args);
3649
996
    check1arg(args, call, "x");
3650
996
    if(isEnvironment(arg))
3651
156
  return arg;
3652
    /* DispatchOrEval internal generic: as.environment */
3653
840
    if(isObject(arg) &&
3654
0
       DispatchOrEval(call, op, "as.environment", args, rho, &ans, 0, 1))
3655
0
  return ans;
3656
840
    switch(TYPEOF(arg)) {
3657
0
    case STRSXP:
3658
0
  return matchEnvir(call, translateChar(asChar(arg)));
3659
12
    case REALSXP:
3660
840
    case INTSXP:
3661
840
  return do_pos2env(call, op, args, rho);
3662
0
    case NILSXP:
3663
0
  errorcall(call,_("using 'as.environment(NULL)' is defunct"));
3664
0
  return R_BaseEnv;  /* -Wall */
3665
0
    case OBJSXP: {
3666
  /* dispatch was tried above already */
3667
0
  SEXP dot_xData = R_getS4DataSlot(arg, ENVSXP);
3668
0
  if(!isEnvironment(dot_xData))
3669
0
      errorcall(call, _("S4 object does not extend class \"environment\""));
3670
0
  else
3671
0
      return(dot_xData);
3672
0
    }
3673
0
    case VECSXP: {
3674
  /* implement as.environment.list() {isObject(.) is false for a list} */
3675
0
  SEXP call, val;
3676
0
  PROTECT(call = lang4(install("list2env"), arg,
3677
0
           /* envir = */R_NilValue,
3678
0
           /* parent = */R_EmptyEnv));
3679
0
  val = eval(call, rho);
3680
0
  UNPROTECT(1);
3681
0
  return val;
3682
0
    }
3683
0
    default:
3684
0
  errorcall(call, _("invalid object for 'as.environment'"));
3685
0
  return R_NilValue; /* -Wall */
3686
840
    }
3687
840
}
3688
3689
void R_LockEnvironment(SEXP env, Rboolean bindings)
3690
330
{
3691
330
    if(IS_S4_OBJECT(env) && (TYPEOF(env) == OBJSXP))
3692
0
  env = R_getS4DataSlot(env, ANYSXP); /* better be an ENVSXP */
3693
330
    if (env == R_BaseEnv || env == R_BaseNamespace) {
3694
24
  if (bindings) {
3695
12
      SEXP s;
3696
12
      int j;
3697
589k
      for (j = 0; j < HSIZE; j++)
3698
614k
    for (s = R_SymbolTable[j]; s != R_NilValue; s = CDR(s))
3699
24.8k
        if(SYMVALUE(CAR(s)) != R_UnboundValue)
3700
16.9k
      LOCK_BINDING(CAR(s));
3701
12
  }
3702
24
  LOCK_FRAME(env);
3703
24
  return;
3704
24
    }
3705
3706
306
    if (TYPEOF(env) != ENVSXP)
3707
0
  error(_("not an environment"));
3708
306
    if (bindings) {
3709
264
  if (IS_HASHED(env)) {
3710
264
      SEXP table, chain;
3711
264
      int i, size;
3712
264
      table = HASHTAB(env);
3713
264
      size = HASHSIZE(table);
3714
56.9k
      for (i = 0; i < size; i++)
3715
56.6k
    for (chain = VECTOR_ELT(table, i);
3716
118k
         chain != R_NilValue;
3717
62.0k
         chain = CDR(chain))
3718
62.0k
        LOCK_BINDING(chain);
3719
264
  }
3720
0
  else {
3721
0
      SEXP frame;
3722
0
      for (frame = FRAME(env); frame != R_NilValue; frame = CDR(frame))
3723
0
    LOCK_BINDING(frame);
3724
0
  }
3725
264
    }
3726
306
    LOCK_FRAME(env);
3727
306
}
3728
3729
Rboolean R_EnvironmentIsLocked(SEXP env)
3730
7.10k
{
3731
7.10k
    if (TYPEOF(env) == NILSXP)
3732
0
  error(_("use of NULL environment is defunct"));
3733
7.10k
    if (TYPEOF(env) != ENVSXP &&
3734
0
  TYPEOF((env = simple_as_environment(env))) != ENVSXP)
3735
0
  error(_("not an environment"));
3736
7.10k
    return FRAME_IS_LOCKED(env) != 0;
3737
7.10k
}
3738
3739
attribute_hidden SEXP do_lockEnv(SEXP call, SEXP op, SEXP args, SEXP rho)
3740
264
{
3741
264
    SEXP frame;
3742
264
    Rboolean bindings;
3743
264
    checkArity(op, args);
3744
264
    frame = CAR(args);
3745
264
    bindings = asRbool(CADR(args), call);
3746
264
    R_LockEnvironment(frame, bindings);
3747
264
    return R_NilValue;
3748
264
}
3749
3750
attribute_hidden SEXP do_envIsLocked(SEXP call, SEXP op, SEXP args, SEXP rho)
3751
216
{
3752
216
    checkArity(op, args);
3753
216
    return ScalarLogical(R_EnvironmentIsLocked(CAR(args)));
3754
216
}
3755
3756
void R_LockBinding(SEXP sym, SEXP env)
3757
0
{
3758
0
    if (TYPEOF(sym) != SYMSXP)
3759
0
  error(_("not a symbol"));
3760
0
    if (TYPEOF(env) == NILSXP)
3761
0
  error(_("use of NULL environment is defunct"));
3762
0
    if (TYPEOF(env) != ENVSXP &&
3763
0
  TYPEOF((env = simple_as_environment(env))) != ENVSXP)
3764
0
  error(_("not an environment"));
3765
0
    if (env == R_BaseEnv || env == R_BaseNamespace)
3766
  /* It is a symbol, so must have a binding even if it is
3767
     R_UnboundSymbol */
3768
0
  LOCK_BINDING(sym);
3769
0
    else {
3770
0
  SEXP binding = findVarLocInFrame(env, sym, NULL);
3771
0
  if (binding == R_NilValue)
3772
0
      error(_("no binding for \"%s\""), EncodeChar(PRINTNAME(sym)));
3773
0
  LOCK_BINDING(binding);
3774
0
    }
3775
0
}
3776
3777
void R_unLockBinding(SEXP sym, SEXP env)
3778
36
{
3779
36
    if (TYPEOF(sym) != SYMSXP)
3780
0
  error(_("not a symbol"));
3781
36
    if (TYPEOF(env) == NILSXP)
3782
0
  error(_("use of NULL environment is defunct"));
3783
36
    if (TYPEOF(env) != ENVSXP &&
3784
0
  TYPEOF((env = simple_as_environment(env))) != ENVSXP)
3785
0
  error(_("not an environment"));
3786
36
    if (env == R_BaseEnv || env == R_BaseNamespace)
3787
  /* It is a symbol, so must have a binding even if it is
3788
     R_UnboundSymbol */
3789
24
  UNLOCK_BINDING(sym);
3790
12
    else {
3791
12
  SEXP binding = findVarLocInFrame(env, sym, NULL);
3792
12
  if (binding == R_NilValue)
3793
0
      error(_("no binding for \"%s\""), EncodeChar(PRINTNAME(sym)));
3794
12
  UNLOCK_BINDING(binding);
3795
12
    }
3796
36
}
3797
3798
0
void R_MakeDelayedBinding(SEXP sym, SEXP expr, SEXP evalEnv, SEXP env) {
3799
0
    if (TYPEOF(sym) != SYMSXP)
3800
0
  error(_("not a symbol"));
3801
0
    if (TYPEOF(env) != ENVSXP)
3802
0
  error(_("not an environment"));
3803
0
    if (TYPEOF(evalEnv) != ENVSXP)
3804
0
  error(_("not an environment"));
3805
0
    defineVar(sym, Rf_mkPROMISE(expr, evalEnv), env);
3806
0
}
3807
3808
0
void R_MakeForcedBinding(SEXP sym, SEXP expr, SEXP value, SEXP env) {
3809
0
    if (TYPEOF(sym) != SYMSXP)
3810
0
  error(_("not a symbol"));
3811
0
    if (TYPEOF(env) != ENVSXP)
3812
0
  error(_("not an environment"));
3813
0
    defineVar(sym, R_mkEVPROMISE(expr, value), env);
3814
0
}
3815
3816
0
void R_MakeMissingBinding(SEXP sym, SEXP env) {
3817
0
    if (TYPEOF(sym) != SYMSXP)
3818
0
  error(_("not a symbol"));
3819
0
    if (TYPEOF(env) != ENVSXP)
3820
0
  error(_("not an environment"));
3821
0
    defineVar(sym, R_MissingArg, env);
3822
0
}
3823
3824
void R_MakeActiveBinding(SEXP sym, SEXP fun, SEXP env)
3825
24
{
3826
24
    if (TYPEOF(sym) != SYMSXP)
3827
0
  error(_("not a symbol"));
3828
24
    if (! isFunction(fun))
3829
0
  error(_("not a function"));
3830
24
    if (TYPEOF(env) == NILSXP)
3831
0
  error(_("use of NULL environment is defunct"));
3832
24
    if (TYPEOF(env) != ENVSXP &&
3833
0
  TYPEOF((env = simple_as_environment(env))) != ENVSXP)
3834
0
  error(_("not an environment"));
3835
24
    if (env == R_BaseEnv || env == R_BaseNamespace) {
3836
12
  if (SYMVALUE(sym) != R_UnboundValue && ! IS_ACTIVE_BINDING(sym))
3837
0
      error(_("symbol already has a regular binding"));
3838
12
  else if (BINDING_IS_LOCKED(sym))
3839
0
      error(_("cannot change active binding if binding is locked"));
3840
12
  SET_SYMVALUE(sym, fun);
3841
12
  SET_ACTIVE_BINDING_BIT(sym);
3842
  /* we don't need to worry about the global cache here as
3843
     a regular binding cannot be changed */
3844
12
    }
3845
12
    else {
3846
12
  SEXP binding = findVarLocInFrame(env, sym, NULL);
3847
12
  if (binding == R_NilValue) {
3848
12
      defineVar(sym, fun, env); /* fails if env is locked */
3849
12
      binding = findVarLocInFrame(env, sym, NULL);
3850
12
      SET_ACTIVE_BINDING_BIT(binding);
3851
12
  }
3852
0
  else if (! IS_ACTIVE_BINDING(binding))
3853
0
      error(_("symbol already has a regular binding"));
3854
0
  else if (BINDING_IS_LOCKED(binding))
3855
0
      error(_("cannot change active binding if binding is locked"));
3856
0
  else
3857
0
      SETCAR(binding, fun);
3858
12
    }
3859
24
}
3860
3861
Rboolean R_BindingIsLocked(SEXP sym, SEXP env)
3862
12
{
3863
12
    if (TYPEOF(sym) != SYMSXP)
3864
0
  error(_("not a symbol"));
3865
12
    if (TYPEOF(env) == NILSXP)
3866
0
  error(_("use of NULL environment is defunct"));
3867
12
    if (TYPEOF(env) != ENVSXP &&
3868
0
  TYPEOF((env = simple_as_environment(env))) != ENVSXP)
3869
0
  error(_("not an environment"));
3870
12
    if (env == R_BaseEnv || env == R_BaseNamespace)
3871
  /* It is a symbol, so must have a binding even if it is
3872
     R_UnboundSymbol */
3873
12
  return BINDING_IS_LOCKED(sym) != 0;
3874
0
    else {
3875
0
  SEXP binding = findVarLocInFrame(env, sym, NULL);
3876
0
  if (binding == R_NilValue)
3877
0
      error(_("no binding for \"%s\""), EncodeChar(PRINTNAME(sym)));
3878
0
  return BINDING_IS_LOCKED(binding) != 0;
3879
0
    }
3880
12
}
3881
3882
Rboolean R_BindingIsActive(SEXP sym, SEXP env)
3883
12
{
3884
12
    if (TYPEOF(sym) != SYMSXP)
3885
0
  error(_("not a symbol"));
3886
12
    if (TYPEOF(env) == NILSXP)
3887
0
  error(_("use of NULL environment is defunct"));
3888
12
    if (TYPEOF(env) != ENVSXP &&
3889
0
  TYPEOF((env = simple_as_environment(env))) != ENVSXP)
3890
0
  error(_("not an environment"));
3891
12
    if (env == R_BaseEnv || env == R_BaseNamespace)
3892
  /* It is a symbol, so must have a binding even if it is
3893
     R_UnboundSymbol */
3894
12
  return IS_ACTIVE_BINDING(sym) != 0;
3895
0
    else {
3896
0
  SEXP binding = findVarLocInFrame(env, sym, NULL);
3897
0
  if (binding == R_NilValue)
3898
0
      error(_("no binding for \"%s\""), EncodeChar(PRINTNAME(sym)));
3899
0
  return IS_ACTIVE_BINDING(binding) != 0;
3900
0
    }
3901
12
}
3902
3903
attribute_hidden Rboolean R_HasFancyBindings(SEXP rho)
3904
0
{
3905
0
    if (IS_HASHED(rho)) {
3906
0
  SEXP table, chain;
3907
0
  int i, size;
3908
3909
0
  table = HASHTAB(rho);
3910
0
  size = HASHSIZE(table);
3911
0
  for (i = 0; i < size; i++)
3912
0
      for (chain = VECTOR_ELT(table, i);
3913
0
     chain != R_NilValue;
3914
0
     chain = CDR(chain))
3915
0
    if (IS_ACTIVE_BINDING(chain) || BINDING_IS_LOCKED(chain))
3916
0
        return TRUE;
3917
0
  return FALSE;
3918
0
    }
3919
0
    else {
3920
0
  SEXP frame;
3921
3922
0
  for (frame = FRAME(rho); frame != R_NilValue; frame = CDR(frame))
3923
0
      if (IS_ACTIVE_BINDING(frame) || BINDING_IS_LOCKED(frame))
3924
0
    return TRUE;
3925
0
  return FALSE;
3926
0
    }
3927
0
}
3928
3929
/* Like BINDING_VALUE but handles symbol cells (base namespace) via
3930
   SYMVALUE instead of CAR. Also signals an error for active bindings. */
3931
static R_INLINE SEXP BINDING_OR_SYMBOL_VALUE(SEXP cell)
3932
0
{
3933
0
    if (IS_ACTIVE_BINDING(cell))
3934
0
  error("BINDING_OR_SYMBOL_VALUE called on active binding");
3935
3936
0
    if (TYPEOF(cell) == SYMSXP)
3937
0
  return SYMVALUE(cell);
3938
3939
0
    if (BNDCELL_TAG(cell)) {
3940
0
  R_expand_binding_value(cell);
3941
0
  return CAR0(cell);
3942
0
    }
3943
3944
0
    return CAR(cell);
3945
0
}
3946
3947
// get the expression for a delayed or forced binding
3948
static SEXP R_GetVarLocExpression(R_varloc_t loc)
3949
0
{
3950
0
    SEXP cell = loc.cell;
3951
0
    if (cell == NULL || cell == R_UnboundValue)
3952
0
  error(_("unbound variable"));
3953
3954
0
    SEXP value = BINDING_OR_SYMBOL_VALUE(cell);
3955
0
    if (TYPEOF(value) != PROMSXP)
3956
0
  error(_("not a delayed or forced binding"));
3957
3958
0
    Rboolean forced;
3959
0
    SEXP inner = promiseUnwrap(value, &forced);
3960
3961
    /* This has special handling for bytecode, unlike `PREXPR()` */
3962
0
    return R_PromiseExpr(inner);
3963
3964
0
}
3965
3966
SEXP R_DelayedBindingExpression(SEXP sym, SEXP env)
3967
0
{
3968
0
    R_varloc_t loc = R_findVarLocInFrameCheck(env, sym);
3969
0
    if (R_GetVarLocType(loc) != R_BindingTypeDelayed)
3970
0
  error(_("not a delayed binding")); 
3971
0
    return R_GetVarLocExpression(loc);
3972
0
}
3973
3974
SEXP R_ForcedBindingExpression(SEXP sym, SEXP env)
3975
0
{
3976
0
    R_varloc_t loc = R_findVarLocInFrameCheck(env, sym);
3977
0
    if (R_GetVarLocType(loc) != R_BindingTypeForced)
3978
0
  error(_("not a forced binding"));  
3979
0
    return R_GetVarLocExpression(loc);
3980
0
}
3981
3982
// get the environment for a delayed binding
3983
0
SEXP R_DelayedBindingEnvironment(SEXP sym, SEXP env) {
3984
0
    R_varloc_t loc = R_findVarLocInFrameCheck(env, sym);
3985
0
    SEXP cell = loc.cell;
3986
0
    if (cell == NULL || cell == R_UnboundValue)
3987
0
  error(_("unbound variable"));
3988
3989
0
    SEXP value = BINDING_OR_SYMBOL_VALUE(cell);
3990
0
    if (TYPEOF(value) != PROMSXP)
3991
0
  error(_("not a delayed binding"));
3992
3993
0
    Rboolean forced;
3994
0
    SEXP inner = promiseUnwrap(value, &forced);
3995
0
    if (forced)
3996
0
  error(_("not a delayed binding"));
3997
3998
0
    return PRENV(inner);
3999
0
}
4000
4001
SEXP R_ActiveBindingFunction(SEXP sym, SEXP env)
4002
0
{
4003
0
    if (TYPEOF(sym) != SYMSXP)
4004
0
  error(_("not a symbol"));
4005
0
    if (TYPEOF(env) == NILSXP)
4006
0
  error(_("use of NULL environment is defunct"));
4007
0
    if (TYPEOF(env) != ENVSXP &&
4008
0
  TYPEOF((env = simple_as_environment(env))) != ENVSXP)
4009
0
  error(_("not an environment"));
4010
0
    if (env == R_BaseEnv || env == R_BaseNamespace) {
4011
0
  SEXP val = SYMVALUE(sym);
4012
0
  if (val == R_UnboundValue)
4013
0
      error(_("no binding for \"%s\""), EncodeChar(PRINTNAME(sym)));
4014
0
  if (! IS_ACTIVE_BINDING(sym))
4015
0
      error(_("no active binding for \"%s\""),
4016
0
      EncodeChar(PRINTNAME(sym)));
4017
0
  return val;
4018
0
    }
4019
0
    else {
4020
0
  SEXP binding = findVarLocInFrame(env, sym, NULL);
4021
0
  if (binding == R_NilValue)
4022
0
      error(_("no binding for \"%s\""), EncodeChar(PRINTNAME(sym)));
4023
0
  if (! IS_ACTIVE_BINDING(binding))
4024
0
      error(_("no active binding for \"%s\""),
4025
0
      EncodeChar(PRINTNAME(sym)));
4026
0
  return CAR(binding);
4027
0
    }
4028
0
}
4029
4030
attribute_hidden SEXP do_lockBnd(SEXP call, SEXP op, SEXP args, SEXP rho)
4031
12
{
4032
12
    SEXP sym, env;
4033
12
    checkArity(op, args);
4034
12
    sym = CAR(args);
4035
12
    env = CADR(args);
4036
12
    switch(PRIMVAL(op)) {
4037
0
    case 0:
4038
0
  R_LockBinding(sym, env);
4039
0
  break;
4040
12
    case 1:
4041
12
  R_unLockBinding(sym, env);
4042
12
  break;
4043
0
    default:
4044
0
  error(_("unknown op"));
4045
12
    }
4046
12
    return R_NilValue;
4047
12
}
4048
4049
attribute_hidden SEXP do_bndIsLocked(SEXP call, SEXP op, SEXP args, SEXP rho)
4050
0
{
4051
0
    SEXP sym, env;
4052
0
    checkArity(op, args);
4053
0
    sym = CAR(args);
4054
0
    env = CADR(args);
4055
0
    return ScalarLogical(R_BindingIsLocked(sym, env));
4056
0
}
4057
4058
attribute_hidden SEXP do_mkActiveBnd(SEXP call, SEXP op, SEXP args, SEXP rho)
4059
24
{
4060
24
    SEXP sym, fun, env;
4061
24
    checkArity(op, args);
4062
24
    sym = CAR(args);
4063
24
    fun = CADR(args);
4064
24
    env = CADDR(args);
4065
24
    R_MakeActiveBinding(sym, fun, env);
4066
24
    return R_NilValue;
4067
24
}
4068
4069
attribute_hidden SEXP do_bndIsActive(SEXP call, SEXP op, SEXP args, SEXP rho)
4070
0
{
4071
0
    SEXP sym, env;
4072
0
    checkArity(op, args);
4073
0
    sym = CAR(args);
4074
0
    env = CADR(args);
4075
0
    return ScalarLogical(R_BindingIsActive(sym, env));
4076
0
}
4077
4078
attribute_hidden SEXP do_activeBndFun(SEXP call, SEXP op, SEXP args, SEXP rho)
4079
0
{
4080
0
    SEXP sym, env;
4081
0
    checkArity(op, args);
4082
0
    sym = CAR(args);
4083
0
    env = CADR(args);
4084
0
    return R_ActiveBindingFunction(sym, env);
4085
0
}
4086
4087
/* This is a .Internal with no wrapper */
4088
attribute_hidden SEXP do_mkUnbound(SEXP call, SEXP op, SEXP args, SEXP rho)
4089
12
{
4090
12
    SEXP sym;
4091
12
    checkArity(op, args);
4092
12
    sym = CAR(args);
4093
4094
12
    if (TYPEOF(sym) != SYMSXP) error(_("not a symbol"));
4095
    /* This is not quite the same as SET_SYMBOL_BINDING_VALUE as it
4096
       does not allow active bindings to be unbound */
4097
12
    if (FRAME_IS_LOCKED(R_BaseEnv))
4098
0
  error(_("cannot remove bindings from a locked environment"));
4099
12
    if (R_BindingIsLocked(sym, R_BaseEnv))
4100
0
  error(_("cannot unbind a locked binding"));
4101
12
    if (R_BindingIsActive(sym, R_BaseEnv))
4102
0
  error(_("cannot unbind an active binding"));
4103
12
    SET_SYMVALUE(sym, R_UnboundValue);
4104
12
#ifdef USE_GLOBAL_CACHE
4105
12
    R_FlushGlobalCache(sym);
4106
12
#endif
4107
12
    return R_NilValue;
4108
12
}
4109
4110
/* C version of new.env */
4111
SEXP R_NewEnv(SEXP enclos, int hash, int size)
4112
4.39k
{
4113
4.39k
    if (hash)
4114
4.38k
  return R_NewHashedEnv(enclos, size);
4115
12
    else
4116
12
  return NewEnvironment(R_NilValue, R_NilValue, enclos);
4117
4.39k
}
4118
4119
attribute_hidden void R_RestoreHashCount(SEXP rho)
4120
47
{
4121
47
    if (IS_HASHED(rho)) {
4122
5
  SEXP table;
4123
5
  int i, count, size;
4124
4125
5
  table = HASHTAB(rho);
4126
5
  size = HASHSIZE(table);
4127
6
  for (i = 0, count = 0; i < size; i++)
4128
1
      if (VECTOR_ELT(table, i) != R_NilValue)
4129
0
    count++;
4130
5
  SET_HASHPRI(table, count);
4131
5
    }
4132
47
}
4133
4134
Rboolean R_IsPackageEnv(SEXP rho)
4135
4.12M
{
4136
4.12M
    if (TYPEOF(rho) == ENVSXP) {
4137
4.12M
  SEXP name = getAttrib(rho, R_NameSymbol);
4138
4.12M
  char *packprefix = "package:";
4139
4.12M
  size_t pplen = strlen(packprefix);
4140
4.12M
  if(isString(name) && length(name) > 0 &&
4141
0
     ! strncmp(packprefix, CHAR(STRING_ELT(name, 0)), pplen)) /* ASCII */
4142
0
      return TRUE;
4143
4.12M
  else
4144
4.12M
      return FALSE;
4145
4.12M
    }
4146
0
    else
4147
0
  return FALSE;
4148
4.12M
}
4149
4150
SEXP R_PackageEnvName(SEXP rho)
4151
0
{
4152
0
    if (TYPEOF(rho) == ENVSXP) {
4153
0
  SEXP name = getAttrib(rho, R_NameSymbol);
4154
0
  char *packprefix = "package:";
4155
0
  size_t pplen = strlen(packprefix);
4156
0
  if(isString(name) && length(name) > 0 &&
4157
0
     ! strncmp(packprefix, CHAR(STRING_ELT(name, 0)), pplen)) /* ASCII */
4158
0
      return name;
4159
0
  else
4160
0
      return R_NilValue;
4161
0
    }
4162
0
    else
4163
0
  return R_NilValue;
4164
0
}
4165
4166
attribute_hidden SEXP R_FindPackageEnv(SEXP info)
4167
2
{
4168
2
    SEXP expr, val;
4169
2
    PROTECT(info);
4170
2
    SEXP s_findPackageEnv = install("findPackageEnv");
4171
2
    PROTECT(expr = LCONS(s_findPackageEnv, LCONS(info, R_NilValue)));
4172
2
    val = eval(expr, R_BaseEnv);
4173
2
    UNPROTECT(2);
4174
2
    return val;
4175
2
}
4176
4177
Rboolean R_IsNamespaceEnv(SEXP rho)
4178
4.83M
{
4179
4.83M
    if (rho == R_BaseNamespace)
4180
348k
  return TRUE;
4181
4.48M
    else if (TYPEOF(rho) == ENVSXP) {
4182
4.15M
  SEXP info = R_findVarInFrame(rho, R_NamespaceSymbol);
4183
4.15M
  if (info != R_UnboundValue && TYPEOF(info) == ENVSXP) {
4184
9.93k
      PROTECT(info);
4185
9.93k
      SEXP spec = R_findVarInFrame(info, install("spec"));
4186
9.93k
      UNPROTECT(1);
4187
9.93k
      if (spec != R_UnboundValue &&
4188
9.93k
    TYPEOF(spec) == STRSXP && LENGTH(spec) > 0)
4189
9.93k
    return TRUE;
4190
0
      else
4191
0
    return FALSE;
4192
9.93k
  }
4193
4.14M
  else return FALSE;
4194
4.15M
    }
4195
334k
    else return FALSE;
4196
4.83M
}
4197
4198
attribute_hidden SEXP do_isNSEnv(SEXP call, SEXP op, SEXP args, SEXP rho)
4199
4.00k
{
4200
4.00k
    checkArity(op, args);
4201
4.00k
    return R_IsNamespaceEnv(CAR(args)) ? mkTrue() : mkFalse();
4202
4.00k
}
4203
4204
SEXP R_NamespaceEnvSpec(SEXP rho)
4205
17.2k
{
4206
    /* The namespace spec is a character vector that specifies the
4207
       namespace.  The first element is the namespace name.  The
4208
       second element, if present, is the namespace version.  Further
4209
       elements may be added later. */
4210
17.2k
    if (rho == R_BaseNamespace)
4211
17.2k
  return R_BaseNamespaceName;
4212
0
    else if (TYPEOF(rho) == ENVSXP) {
4213
0
  SEXP info = R_findVarInFrame(rho, R_NamespaceSymbol);
4214
0
  if (info != R_UnboundValue && TYPEOF(info) == ENVSXP) {
4215
0
      PROTECT(info);
4216
0
      SEXP spec = R_findVarInFrame(info, install("spec"));
4217
0
      UNPROTECT(1);
4218
0
      if (spec != R_UnboundValue &&
4219
0
    TYPEOF(spec) == STRSXP && LENGTH(spec) > 0)
4220
0
    return spec;
4221
0
      else
4222
0
    return R_NilValue;
4223
0
  }
4224
0
  else return R_NilValue;
4225
0
    }
4226
0
    else return R_NilValue;
4227
17.2k
}
4228
4229
SEXP R_FindNamespace(SEXP info)
4230
25.5k
{
4231
25.5k
    SEXP expr, val;
4232
25.5k
    PROTECT(info);
4233
25.5k
    SEXP s_getNamespace = install("getNamespace");
4234
25.5k
    PROTECT(expr = LCONS(s_getNamespace, LCONS(info, R_NilValue)));
4235
25.5k
    val = eval(expr, R_BaseEnv);
4236
25.5k
    UNPROTECT(2);
4237
25.5k
    return val;
4238
25.5k
}
4239
4240
static SEXP checkNSname(SEXP call, SEXP name)
4241
395k
{
4242
395k
    switch (TYPEOF(name)) {
4243
395k
    case SYMSXP:
4244
395k
  break;
4245
84
    case STRSXP:
4246
84
  if (LENGTH(name) >= 1) {
4247
84
      name = installTrChar(STRING_ELT(name, 0));
4248
84
      break;
4249
84
  }
4250
  /* else fall through */
4251
0
    default:
4252
0
  errorcall(call, _("bad namespace name"));
4253
395k
    }
4254
395k
    return name;
4255
395k
}
4256
4257
// .Internal(registerNamespace(name, env))
4258
attribute_hidden SEXP do_regNS(SEXP call, SEXP op, SEXP args, SEXP rho)
4259
84
{
4260
84
    SEXP name, val;
4261
84
    checkArity(op, args);
4262
84
    name = checkNSname(call, CAR(args));
4263
84
    val = CADR(args);
4264
84
    if (R_findVarInFrame(R_NamespaceRegistry, name) != R_UnboundValue)
4265
0
  errorcall(call, _("namespace already registered"));
4266
84
    defineVar(name, val, R_NamespaceRegistry);
4267
84
    return R_NilValue;
4268
84
}
4269
4270
// .Internal(unregisterNamespace(nsname))
4271
attribute_hidden SEXP do_unregNS(SEXP call, SEXP op, SEXP args, SEXP rho)
4272
0
{
4273
0
    SEXP name;
4274
0
    int hashcode;
4275
0
    checkArity(op, args);
4276
0
    name = checkNSname(call, CAR(args));
4277
0
    if (R_findVarInFrame(R_NamespaceRegistry, name) == R_UnboundValue)
4278
0
  errorcall(call, _("namespace not registered"));
4279
0
    if( !HASHASH(PRINTNAME(name)))
4280
0
  hashcode = R_Newhashpjw(CHAR(PRINTNAME(name)));
4281
0
    else
4282
0
  hashcode = HASHVALUE(PRINTNAME(name));
4283
0
    RemoveVariable(name, hashcode, R_NamespaceRegistry);
4284
0
    return R_NilValue;
4285
0
}
4286
4287
// .Internal(getRegisteredNamespace(name))  ==  .getNamespace(name)
4288
// .Internal(isRegisteredNamespace (name))  ==  isNamespaceLoaded(name)
4289
attribute_hidden SEXP do_getRegNS(SEXP call, SEXP op, SEXP args, SEXP rho)
4290
61.1k
{
4291
61.1k
    checkArity(op, args);
4292
61.1k
    SEXP name = checkNSname(call, PROTECT(coerceVector(CAR(args), SYMSXP)));
4293
61.1k
    UNPROTECT(1);
4294
61.1k
    SEXP val = R_findVarInFrame(R_NamespaceRegistry, name);
4295
4296
61.1k
    switch(PRIMVAL(op)) {
4297
46.3k
    case 0: // get..()
4298
46.3k
  if (val == R_UnboundValue)
4299
29.7k
      return R_NilValue;
4300
16.6k
  else
4301
16.6k
      return val;
4302
14.7k
    case 1: // is..()
4303
14.7k
  return ScalarLogical(val == R_UnboundValue ? FALSE : TRUE);
4304
4305
0
    default: error(_("unknown op"));
4306
61.1k
    }
4307
0
    return R_NilValue; // -Wall
4308
61.1k
}
4309
4310
SEXP R_getRegisteredNamespace(const char *name)
4311
0
{
4312
0
    SEXP sym = install(name);
4313
0
    SEXP val = R_findVarInFrame(R_NamespaceRegistry, sym);
4314
0
    if (val == R_UnboundValue)
4315
0
  return R_NilValue;
4316
0
    else
4317
0
  return val;
4318
0
}
4319
4320
// .Internal(getNamespaceRegistry())
4321
attribute_hidden SEXP do_getNSRegistry(SEXP call, SEXP op, SEXP args, SEXP rho)
4322
0
{
4323
0
    checkArity(op, args);
4324
0
    return R_NamespaceRegistry;
4325
0
}
4326
4327
static SEXP getVarValInFrame(SEXP rho, SEXP sym, int unbound_ok)
4328
346k
{
4329
346k
    SEXP val = R_findVarInFrame(rho, sym);
4330
346k
    if (! unbound_ok && val == R_UnboundValue)
4331
0
  R_ObjectNotFoundError(sym, R_CurrentExpression, NULL);
4332
346k
    if (TYPEOF(val) == PROMSXP) {
4333
96
  PROTECT(val);
4334
96
  val = eval(val, R_EmptyEnv);
4335
96
  UNPROTECT(1);
4336
96
    }
4337
346k
    return val;
4338
346k
}
4339
4340
static SEXP checkVarName(SEXP call, SEXP name)
4341
340k
{
4342
340k
    switch(TYPEOF(name)) {
4343
334k
    case SYMSXP: break;
4344
5.71k
    case STRSXP:
4345
5.71k
  if (LENGTH(name) >= 1) {
4346
5.71k
      name = installTrChar(STRING_ELT(name, 0));
4347
5.71k
      break;
4348
5.71k
  }
4349
  /* else fall through */
4350
0
    default:
4351
0
  errorcall(call, _("bad variable name"));
4352
340k
    }
4353
340k
    return name;
4354
340k
}
4355
4356
static SEXP callR1(SEXP fun, SEXP arg)
4357
0
{
4358
0
    static SEXP R_xSymbol = NULL;
4359
0
    if (R_xSymbol == NULL)
4360
0
  R_xSymbol = install("x");
4361
4362
0
    SEXP rho = PROTECT(NewEnvironment(R_NilValue, R_NilValue, R_BaseNamespace));
4363
0
    defineVar(R_xSymbol, arg, rho);
4364
0
    SEXP expr = PROTECT(lang2(fun, R_xSymbol));
4365
0
    SEXP val = eval(expr, rho);
4366
    /**** ideally this should clear out rho if it isn't captured - LT */
4367
0
    UNPROTECT(2); /* rho, expr */
4368
0
    return val;
4369
0
}
4370
4371
attribute_hidden SEXP R_getNSValue(SEXP call, SEXP ns, SEXP name, int exported)
4372
334k
{
4373
334k
    static SEXP R_loadNamespaceSymbol = NULL;
4374
334k
    static SEXP R_exportsSymbol = NULL;
4375
334k
    static SEXP R_lazydataSymbol = NULL;
4376
334k
    static SEXP R_getNamespaceNameSymbol = NULL;
4377
334k
    if (R_loadNamespaceSymbol == NULL) {
4378
12
  R_loadNamespaceSymbol = install("loadNamespace");
4379
12
  R_exportsSymbol = install("exports");
4380
12
  R_lazydataSymbol = install("lazydata");
4381
12
  R_getNamespaceNameSymbol = install("getNamespaceName");
4382
12
    }
4383
4384
334k
    if (R_IsNamespaceEnv(ns))
4385
0
  PROTECT(ns);
4386
334k
    else {
4387
334k
  SEXP pkg = checkNSname(call, ns);
4388
334k
  ns = R_findVarInFrame(R_NamespaceRegistry, pkg);
4389
334k
  if (ns == R_UnboundValue)
4390
0
      ns = callR1(R_loadNamespaceSymbol, pkg);
4391
334k
  PROTECT(ns);
4392
334k
  if (! R_IsNamespaceEnv(ns))
4393
0
      errorcall(call, _("bad namespace"));
4394
334k
    }
4395
4396
334k
    name = checkVarName(call, name);
4397
4398
334k
    SEXP val;
4399
4400
    /* base or non-exported variables */
4401
334k
    if (ns == R_BaseNamespace || ! exported) {
4402
328k
  val = getVarValInFrame(ns, name, FALSE);
4403
328k
  UNPROTECT(1); /* ns */
4404
328k
  return val;
4405
328k
    }
4406
4407
    /* exported variables */
4408
5.71k
    SEXP info = PROTECT(getVarValInFrame(ns, R_NamespaceSymbol, FALSE));
4409
5.71k
    SEXP exports = PROTECT(getVarValInFrame(info, R_exportsSymbol, FALSE));
4410
5.71k
    SEXP exportName = PROTECT(getVarValInFrame(exports, name, TRUE));
4411
5.71k
    if (exportName != R_UnboundValue) {
4412
5.71k
  val = eval(checkVarName(call, exportName), ns);
4413
5.71k
  UNPROTECT(4);  /* ns, info, exports, exportName */
4414
5.71k
  return val;
4415
5.71k
    }
4416
4417
    /* lazydata */
4418
0
    SEXP ld = PROTECT(getVarValInFrame(info, R_lazydataSymbol, FALSE));
4419
0
    val = getVarValInFrame(ld, name, TRUE);
4420
0
    if (val != R_UnboundValue) {
4421
0
  UNPROTECT(5); /* ns, info, exports, exportName, ld */
4422
0
  return val;
4423
0
    }
4424
4425
0
    SEXP nsname = PROTECT(callR1(R_getNamespaceNameSymbol, ns));
4426
0
    if (TYPEOF(nsname) != STRSXP || LENGTH(nsname) != 1)
4427
0
  errorcall(call, "bad value returned by `getNamespaceName'");
4428
0
    errorcall_cpy(call,
4429
0
      _("'%s' is not an exported object from 'namespace:%s'"),
4430
0
      EncodeChar(PRINTNAME(name)),
4431
0
      CHAR(STRING_ELT(nsname, 0)));
4432
0
    return NULL; /* not reached */
4433
0
}
4434
4435
attribute_hidden SEXP do_getNSValue(SEXP call, SEXP op, SEXP args, SEXP rho)
4436
0
{
4437
0
    checkArity(op, args);
4438
0
    SEXP ns = CAR(args);
4439
0
    SEXP name = CADR(args);
4440
0
    int exported = asLogical(CADDR(args));
4441
4442
0
    return R_getNSValue(R_NilValue, ns, name, exported);
4443
0
}
4444
4445
attribute_hidden
4446
SEXP do_colon2(SEXP call, SEXP op, SEXP args, SEXP rho)
4447
334k
{
4448
334k
    checkArity(op, args);
4449
    /* use R_NilValue for the call to avoid changing the error message */
4450
334k
    return R_getNSValue(R_NilValue, CAR(args), CADR(args), TRUE);
4451
334k
}
4452
4453
attribute_hidden
4454
SEXP do_colon3(SEXP call, SEXP op, SEXP args, SEXP rho)
4455
96
{
4456
96
    checkArity(op, args);
4457
96
    return R_getNSValue(call, CAR(args), CADR(args), FALSE);
4458
96
}
4459
4460
attribute_hidden SEXP do_importIntoEnv(SEXP call, SEXP op, SEXP args, SEXP rho)
4461
240
{
4462
    /* This function copies values of variables from one environment
4463
       to another environment, possibly with different names.
4464
       Promises are not forced and active bindings are preserved. */
4465
240
    SEXP impenv, impnames, expenv, expnames;
4466
240
    SEXP impsym, expsym, val;
4467
240
    int i, n;
4468
4469
240
    checkArity(op, args);
4470
4471
240
    impenv = CAR(args); args = CDR(args);
4472
240
    impnames = CAR(args); args = CDR(args);
4473
240
    expenv = CAR(args); args = CDR(args);
4474
240
    expnames = CAR(args); args = CDR(args);
4475
4476
240
    if (TYPEOF(impenv) == NILSXP)
4477
0
  error(_("use of NULL environment is defunct"));
4478
240
    if (TYPEOF(impenv) != ENVSXP &&
4479
0
  TYPEOF((impenv = simple_as_environment(impenv))) != ENVSXP)
4480
0
  error(_("bad import environment argument"));
4481
240
    if (TYPEOF(expenv) == NILSXP)
4482
0
  error(_("use of NULL environment is defunct"));
4483
240
    if (TYPEOF(expenv) != ENVSXP &&
4484
0
  TYPEOF((expenv = simple_as_environment(expenv))) != ENVSXP)
4485
0
  error(_("bad export environment argument"));
4486
240
    if (TYPEOF(impnames) != STRSXP || TYPEOF(expnames) != STRSXP)
4487
0
  error(_("invalid '%s' argument"), "names");
4488
240
    if (LENGTH(impnames) != LENGTH(expnames))
4489
0
  error(_("length of import and export names must match"));
4490
4491
240
    n = LENGTH(impnames);
4492
24.9k
    for (i = 0; i < n; i++) {
4493
24.6k
  impsym = installTrChar(STRING_ELT(impnames, i));
4494
24.6k
  expsym = installTrChar(STRING_ELT(expnames, i));
4495
4496
  /* find the binding--may be a CONS cell or a symbol */
4497
24.6k
  SEXP binding = R_NilValue;
4498
24.6k
  for (SEXP env = expenv;
4499
49.3k
       env != R_EmptyEnv && binding == R_NilValue;
4500
24.7k
       env = ENCLOS(env))
4501
24.7k
      if (env == R_BaseNamespace) {
4502
24
    if (SYMVALUE(expsym) != R_UnboundValue)
4503
24
        binding = expsym;
4504
24
      } else
4505
24.6k
    binding = findVarLocInFrame(env, expsym, NULL);
4506
24.6k
  if (binding == R_NilValue)
4507
0
      binding = expsym;
4508
4509
  /* get value of the binding; do not force promises */
4510
24.6k
  if (TYPEOF(binding) == SYMSXP) {
4511
24
      if (SYMVALUE(expsym) == R_UnboundValue)
4512
0
    error(_("exported symbol '%s' has no value"),
4513
0
          CHAR(PRINTNAME(expsym)));
4514
24
      val = SYMVALUE(expsym);
4515
24
  }
4516
24.6k
  else val = CAR(binding);
4517
4518
  /* import the binding */
4519
24.6k
  if (IS_ACTIVE_BINDING(binding))
4520
0
      R_MakeActiveBinding(impsym, val, impenv);
4521
  /* This is just a tiny optimization */
4522
24.6k
  else if (impenv == R_BaseNamespace || impenv == R_BaseEnv)
4523
0
      gsetVar(impsym, val, impenv);
4524
24.6k
  else
4525
24.6k
      defineVar(impsym, val, impenv);
4526
24.6k
    }
4527
240
    return R_NilValue;
4528
240
}
4529
4530
4531
attribute_hidden SEXP do_envprofile(SEXP call, SEXP op, SEXP args, SEXP rho)
4532
0
{
4533
    /* Return a list containing profiling information given a hashed
4534
       environment.  For non-hashed environments, this function
4535
       returns R_NilValue.  This seems appropriate since there is no
4536
       way to test whether an environment is hashed at the R level.
4537
    */
4538
0
    checkArity(op, args);
4539
0
    SEXP env, ans = R_NilValue /* -Wall */;
4540
0
    env = CAR(args);
4541
0
    if (isEnvironment(env)) {
4542
0
  if (IS_HASHED(env))
4543
0
      ans = R_HashProfile(HASHTAB(env));
4544
0
    } else
4545
0
  error("argument must be a hashed environment");
4546
0
    return ans;
4547
0
}
4548
4549
SEXP mkCharCE(const char *name, cetype_t enc)
4550
1.23M
{
4551
1.23M
    size_t len =  strlen(name);
4552
1.23M
    if (len > INT_MAX)
4553
0
  error("R character strings are limited to 2^31-1 bytes");
4554
1.23M
   return mkCharLenCE(name, (int) len, enc);
4555
1.23M
}
4556
4557
/* no longer used in R but documented in 2.7.x */
4558
SEXP mkCharLen(const char *name, int len)
4559
0
{
4560
0
    return mkCharLenCE(name, len, CE_NATIVE);
4561
0
}
4562
4563
SEXP mkChar(const char *name)
4564
1.40M
{
4565
1.40M
    size_t len =  strlen(name);
4566
1.40M
    if (len > INT_MAX)
4567
0
  error("R character strings are limited to 2^31-1 bytes");
4568
1.40M
    return mkCharLenCE(name, (int) len, CE_NATIVE);
4569
1.40M
}
4570
4571
attribute_hidden SEXP mkCharWUTF8(const wchar_t *wname)
4572
0
{
4573
0
    const void *vmax = vmaxget();
4574
0
    size_t nb = wcstoutf8(NULL, wname, (size_t)INT_MAX + 2);
4575
0
    if (nb-1 > INT_MAX) {
4576
0
  error("R character strings are limited to 2^31-1 bytes");
4577
0
    }
4578
0
    char *name = R_alloc(nb, 1);
4579
0
    nb = wcstoutf8(name, wname, nb);
4580
0
    SEXP ans = mkCharLenCE(name, (int)(nb-1), CE_UTF8);
4581
0
    vmaxset(vmax);
4582
0
    return ans;
4583
0
}
4584
4585
/* Global CHARSXP cache and code for char-based hash tables */
4586
4587
/* We can reuse the hash structure, but need separate code for get/set
4588
   of values since our keys are char* and not SEXP symbol types.
4589
4590
   Experience has shown that it is better to use a different hash function,
4591
   and a power of 2 for the hash size.
4592
*/
4593
4594
/* char_hash_size MUST be a power of 2 and char_hash_mask ==
4595
   char_hash_size - 1 for x & char_hash_mask to be equivalent to x %
4596
   char_hash_size.
4597
*/
4598
static unsigned int char_hash_size = 65536;
4599
static unsigned int char_hash_mask = 65535;
4600
4601
static unsigned int char_hash(const char *s, int len)
4602
3.57M
{
4603
    /* djb2 as from http://www.cse.yorku.ca/~oz/hash.html */
4604
3.57M
    char *p;
4605
3.57M
    int i;
4606
3.57M
    unsigned int h = 5381;
4607
104M
    for (p = (char *) s, i = 0; i < len; p++, i++)
4608
101M
  h = ((h << 5) + h) + (*p);
4609
3.57M
    return h;
4610
3.57M
}
4611
4612
attribute_hidden void InitStringHash(void)
4613
12
{
4614
12
    R_StringHash = R_NewHashTable(char_hash_size);
4615
12
}
4616
4617
/* #define DEBUG_GLOBAL_STRING_HASH 1 */
4618
4619
/* Resize the global R_StringHash CHARSXP cache */
4620
static void R_StringHash_resize(unsigned int newsize)
4621
0
{
4622
0
    SEXP old_table = R_StringHash;
4623
0
    SEXP new_table, chain, new_chain, val, next;
4624
0
    unsigned int counter, new_hashcode, newmask;
4625
#ifdef DEBUG_GLOBAL_STRING_HASH
4626
    unsigned int oldsize = HASHSIZE(R_StringHash);
4627
    unsigned int oldpri = HASHPRI(R_StringHash);
4628
    unsigned int newsize, newpri;
4629
#endif
4630
4631
    /* Allocate the new hash table.  This could fail to allocate
4632
       enough memory, and ideally we would recover from that and
4633
       carry over with a table that was getting full.
4634
     */
4635
    /* When using the ATTRIB fields to maintain the chains the chain
4636
       moving is destructive and does not involve allocation.  This is
4637
       therefore the only point where GC can occur. */
4638
0
    new_table = R_NewHashTable(newsize);
4639
0
    newmask = newsize - 1;
4640
4641
    /* transfer chains from old table to new table */
4642
0
    for (counter = 0; counter < LENGTH(old_table); counter++) {
4643
0
  chain = VECTOR_ELT(old_table, counter);
4644
0
  while (!ISNULL(chain)) {
4645
0
      val = CXHEAD(chain);
4646
0
      next = CXTAIL(chain);
4647
0
      new_hashcode = char_hash(CHAR(val), LENGTH(val)) & newmask;
4648
0
      new_chain = VECTOR_ELT(new_table, new_hashcode);
4649
      /* If using a primary slot then increase HASHPRI */
4650
0
      if (ISNULL(new_chain))
4651
0
    SET_HASHPRI(new_table, HASHPRI(new_table) + 1);
4652
      /* move the current chain link to the new chain */
4653
      /* this is a destructive modification */
4654
0
      new_chain = SET_CXTAIL(val, new_chain);
4655
0
      SET_VECTOR_ELT(new_table, new_hashcode, new_chain);
4656
0
      chain = next;
4657
0
  }
4658
0
    }
4659
0
    R_StringHash = new_table;
4660
0
    char_hash_size = newsize;
4661
0
    char_hash_mask = newmask;
4662
#ifdef DEBUG_GLOBAL_STRING_HASH
4663
    newsize = HASHSIZE(new_table);
4664
    newpri = HASHPRI(new_table);
4665
    Rprintf("Resized: size %d => %d\tpri %d => %d\n",
4666
      oldsize, newsize, oldpri, newpri);
4667
#endif
4668
0
}
4669
4670
static void reportInvalidString(SEXP cval, int actionWhenInvalid)
4671
0
{
4672
0
    int oldout = R_OutputCon;
4673
0
    int olderr = R_ErrorCon;
4674
0
    R_OutputCon = 2;
4675
0
    R_ErrorCon = 2;
4676
0
    REprintf(" ----------- FAILURE REPORT -------------- \n");
4677
0
    REprintf(" --- failure: %s ---\n", "invalid string was created");
4678
0
    REprintf(" --- srcref --- \n");
4679
0
    SrcrefPrompt("", R_getCurrentSrcref());
4680
0
    REprintf("\n");
4681
0
    REprintf(" --- call from context --- \n");
4682
0
    PrintValue(R_GlobalContext->call);
4683
0
    REprintf(" --- R stacktrace ---\n");
4684
0
    printwhere();
4685
0
    REprintf(" --- current native encoding: %s ---\n",
4686
0
             R_nativeEncoding());
4687
0
    char *enc = "native/unknown";
4688
0
    if (IS_LATIN1(cval))
4689
0
  enc = "latin1";
4690
0
    else if (IS_UTF8(cval))
4691
0
  enc = "UTF-8";
4692
0
    else if (IS_BYTES(cval))
4693
0
  enc = "bytes";  // called in error
4694
0
    REprintf(" --- declared string encoding: %s ---\n", enc);
4695
0
    REprintf(" --- string (printed):\n");
4696
0
    PrintValue(cval);
4697
0
    REprintf(" --- string (bytes with ASCII chars):\n");
4698
0
    for(int i = 0; i < LENGTH(cval); i++) {
4699
0
  if (i > 0)
4700
0
      REprintf(" ");
4701
0
  unsigned char b = (unsigned char) CHAR(cval)[i];
4702
0
  REprintf("%2x", b);
4703
0
  if (b > 0 && b <= 127) REprintf("(%c) ", b);
4704
0
    }
4705
0
    REprintf("\n");
4706
0
    REprintf(" --- function from context --- \n");
4707
0
    if (R_GlobalContext->callfun != NULL &&
4708
0
  TYPEOF(R_GlobalContext->callfun) == CLOSXP)
4709
0
  PrintValue(R_GlobalContext->callfun);
4710
0
    REprintf(" --- function search by body ---\n");
4711
0
    if (R_GlobalContext->callfun != NULL &&
4712
0
  TYPEOF(R_GlobalContext->callfun) == CLOSXP)
4713
0
  findFunctionForBody(R_ClosureExpr(R_GlobalContext->callfun));
4714
0
    REprintf(" ----------- END OF FAILURE REPORT -------------- \n");
4715
0
    R_OutputCon = oldout;
4716
0
    R_ErrorCon = olderr;
4717
4718
0
    if (actionWhenInvalid == 3)
4719
0
  R_Suicide("invalid string was created");
4720
0
    else if (actionWhenInvalid > 0) {
4721
0
  const void *vmax = vmaxget();
4722
0
  const char *native_str;
4723
0
  const char *from = "";
4724
0
  if (IS_UTF8(cval))
4725
0
      from = "UTF-8";
4726
0
  else if (IS_LATIN1(cval))
4727
0
      from = "CP1252";
4728
4729
0
  native_str = reEnc3(CHAR(cval), from, "", 1);
4730
0
  if (actionWhenInvalid == 1)
4731
0
      warning("invalid string %s", native_str);
4732
0
  else if (actionWhenInvalid == 2)
4733
0
      error("invalid string %s", native_str);
4734
0
  vmaxset(vmax);
4735
0
    }
4736
0
}
4737
4738
/* mkCharLenCE - make a character (CHARSXP) variable and set its
4739
   encoding bit.  If a CHARSXP with the same string already exists in
4740
   the global CHARSXP cache, R_StringHash, it is returned.  Otherwise,
4741
   a new CHARSXP is created, added to the cache and then returned. */
4742
4743
SEXP mkCharLenCE(const char *name, int len, cetype_t enc)
4744
3.57M
{
4745
3.57M
    SEXP cval, chain;
4746
3.57M
    unsigned int hashcode;
4747
3.57M
    int need_enc;
4748
3.57M
    Rboolean embedNul = FALSE, is_ascii = TRUE;
4749
3.57M
    static int checkValid = -1;
4750
3.57M
    static int actionWhenInvalid = 0;
4751
4752
3.57M
    switch(enc){
4753
2.44M
    case CE_NATIVE:
4754
3.57M
    case CE_UTF8:
4755
3.57M
    case CE_LATIN1:
4756
3.57M
    case CE_BYTES:
4757
3.57M
    case CE_SYMBOL:
4758
3.57M
    case CE_ANY:
4759
3.57M
  break;
4760
0
    default:
4761
0
  error(_("unknown encoding: %d"), enc);
4762
3.57M
    }
4763
105M
    for (int slen = 0; slen < len; slen++) {
4764
101M
  if ((unsigned int) name[slen] > 127) is_ascii = FALSE;
4765
101M
  if (!name[slen]) embedNul = TRUE;
4766
101M
    }
4767
3.57M
    if (embedNul) {
4768
583
  SEXP c;
4769
  /* This is tricky: we want to make a reasonable job of
4770
     representing this string, and EncodeString() is the most
4771
     comprehensive */
4772
583
  c = allocCharsxp(len);
4773
583
  if (len) memcpy(CHAR_RW(c), name, len);
4774
583
  switch(enc) {
4775
348
  case CE_UTF8: SET_UTF8(c); break;
4776
32
  case CE_LATIN1: SET_LATIN1(c); break;
4777
41
  case CE_BYTES: SET_BYTES(c); break;
4778
162
  default: break;
4779
583
  }
4780
583
  if (is_ascii) SET_ASCII(c);
4781
583
  error(_("embedded nul in string: '%s'"),
4782
583
        EncodeString(c, 0, 0, Rprt_adj_none));
4783
583
    }
4784
4785
3.57M
    if (enc && is_ascii) enc = CE_NATIVE;
4786
3.57M
    switch(enc) {
4787
1.37k
    case CE_UTF8: need_enc = UTF8_MASK; break;
4788
67
    case CE_LATIN1: need_enc = LATIN1_MASK; break;
4789
3
    case CE_BYTES: need_enc = BYTES_MASK; break;
4790
3.57M
    default: need_enc = 0;
4791
3.57M
    }
4792
4793
3.57M
    hashcode = char_hash(name, len) & char_hash_mask;
4794
4795
    /* Search for a cached value */
4796
3.57M
    cval = R_NilValue;
4797
3.57M
    chain = VECTOR_ELT(R_StringHash, hashcode);
4798
3.70M
    for (; !ISNULL(chain) ; chain = CXTAIL(chain)) {
4799
3.55M
  SEXP val = CXHEAD(chain);
4800
3.55M
  if (TYPEOF(val) != CHARSXP) break; /* sanity check */
4801
3.55M
  if (need_enc == (ENC_KNOWN(val) | IS_BYTES(val)) &&
4802
3.55M
      LENGTH(val) == len &&  /* quick pretest */
4803
3.43M
      (!len || (memcmp(CHAR(val), name, len) == 0))) { // called with len = 0
4804
3.42M
      cval = val;
4805
3.42M
      break;
4806
3.42M
  }
4807
3.55M
    }
4808
3.57M
    if (cval == R_NilValue) {
4809
  /* no cached value; need to allocate one and add to the cache */
4810
151k
  PROTECT(cval = allocCharsxp(len));
4811
151k
  if (len) memcpy(CHAR_RW(cval), name, len);
4812
151k
  switch(enc) {
4813
150k
  case CE_NATIVE:
4814
150k
      break;          /* don't set encoding */
4815
801
  case CE_UTF8:
4816
801
      SET_UTF8(cval);
4817
801
      break;
4818
63
  case CE_LATIN1:
4819
63
      SET_LATIN1(cval);
4820
63
      break;
4821
3
  case CE_BYTES:
4822
3
      SET_BYTES(cval);
4823
3
      break;
4824
0
  default:
4825
0
      error("unknown encoding mask: %d", enc);
4826
151k
  }
4827
151k
  if (is_ascii) SET_ASCII(cval);
4828
151k
  SET_CACHED(cval);  /* Mark it */
4829
  /* add the new value to the cache */
4830
151k
  chain = VECTOR_ELT(R_StringHash, hashcode);
4831
151k
  if (ISNULL(chain))
4832
138k
      SET_HASHPRI(R_StringHash, HASHPRI(R_StringHash) + 1);
4833
  /* this is a destructive modification */
4834
151k
  chain = SET_CXTAIL(cval, chain);
4835
151k
  SET_VECTOR_ELT(R_StringHash, hashcode, chain);
4836
4837
  /* resize the hash table if necessary with the new entry still
4838
     protected.
4839
     Maximum possible power of two is 2^30 for a VECSXP.
4840
     FIXME: this has changed with long vectors.
4841
  */
4842
151k
  if (R_HashSizeCheck(R_StringHash)
4843
0
      && char_hash_size < 1073741824 /* 2^30 */)
4844
0
      R_StringHash_resize(char_hash_size * 2);
4845
4846
151k
  if (checkValid && !IS_ASCII(cval)) {
4847
5
      if (checkValid == -1) {
4848
5
    checkValid = 0;
4849
    /* _R_CHECK_STRING_VALIDITY_ = XY (decimal)
4850
4851
       Y = 0 ... no checks
4852
       Y = 1 ... check marked strings
4853
       Y = 2 ... check also native strings
4854
4855
       X = 0 ... just print
4856
       X = 1 ... print + issue a warning
4857
       X = 2 ... print + throw R error
4858
       X = 3 ... print + abort R
4859
4860
       This is experimental and will be likely changed or
4861
       removed.
4862
    */
4863
5
    const char *p = getenv("_R_CHECK_STRING_VALIDITY_");
4864
5
    if (p) {
4865
0
        checkValid = atoi(p);
4866
0
        actionWhenInvalid = checkValid / 10;
4867
0
        checkValid -= actionWhenInvalid * 10;
4868
4869
0
        if (checkValid < 0 || checkValid > 2) {
4870
0
      checkValid = 0;
4871
0
      actionWhenInvalid = 0;
4872
0
        }
4873
0
        if (actionWhenInvalid < 0 || actionWhenInvalid > 3)
4874
0
      actionWhenInvalid = 0;
4875
0
    }
4876
5
      }
4877
5
      if (checkValid >= 1) {
4878
    /* check strings flagged UTF-8 and latin1 */
4879
0
    if (IS_UTF8(cval)) {
4880
0
        if (!utf8Valid(CHAR(cval)))
4881
0
      reportInvalidString(cval, actionWhenInvalid);
4882
0
        UNPROTECT(1);
4883
0
        return cval;
4884
0
    } else if (IS_LATIN1(cval)) {
4885
0
        const void *vmax = vmaxget();
4886
0
        const wchar_t *dummy = wtransChar2(cval);
4887
0
        if (!dummy)
4888
0
      reportInvalidString(cval, actionWhenInvalid);
4889
0
        vmaxset(vmax);
4890
0
        UNPROTECT(1);
4891
0
        return cval;
4892
0
    }
4893
0
      }
4894
5
      if (checkValid >= 2 && !IS_BYTES(cval)) {
4895
    /* check strings flagged native/unknown */
4896
0
    if (known_to_be_utf8) {
4897
0
        if (!utf8Valid(CHAR(cval)))
4898
0
      reportInvalidString(cval, actionWhenInvalid);
4899
0
        UNPROTECT(1);
4900
0
        return cval;
4901
0
    } else if (!mbcsValid(CHAR(cval))) {
4902
0
        reportInvalidString(cval, actionWhenInvalid);
4903
0
        UNPROTECT(1);
4904
0
        return cval;
4905
0
    }
4906
0
      }
4907
5
  }
4908
4909
151k
  UNPROTECT(1);
4910
151k
    }
4911
3.57M
    return cval;
4912
3.57M
}
4913
4914
4915
#ifdef DEBUG_SHOW_CHARSXP_CACHE
4916
/* Call this from gdb with
4917
4918
       call do_show_cache(10)
4919
4920
   for the first 10 cache chains in use. */
4921
void do_show_cache(int n)
4922
{
4923
    int i, j;
4924
    Rprintf("Cache size: %d\n", LENGTH(R_StringHash));
4925
    Rprintf("Cache pri:  %d\n", HASHPRI(R_StringHash));
4926
    for (i = 0, j = 0; j < n && i < LENGTH(R_StringHash); i++) {
4927
  SEXP chain = VECTOR_ELT(R_StringHash, i);
4928
  if (! ISNULL(chain)) {
4929
      Rprintf("Line %d: ", i);
4930
      do {
4931
    if (IS_UTF8(CXHEAD(chain)))
4932
        Rprintf("U");
4933
    else if (IS_LATIN1(CXHEAD(chain)))
4934
        Rprintf("L");
4935
    else if (IS_BYTES(CXHEAD(chain)))
4936
        Rprintf("B");
4937
    Rprintf("|%s| ", CHAR(CXHEAD(chain)));
4938
    chain = CXTAIL(chain);
4939
      } while(! ISNULL(chain));
4940
      Rprintf("\n");
4941
      j++;
4942
  }
4943
    }
4944
}
4945
4946
void do_write_cache()
4947
{
4948
    int i;
4949
    FILE *f = fopen("/tmp/CACHE", "w");
4950
    if (f != NULL) {
4951
  fprintf(f, "Cache size: %d\n", LENGTH(R_StringHash));
4952
  fprintf(f, "Cache pri:  %d\n", HASHPRI(R_StringHash));
4953
  for (i = 0; i < LENGTH(R_StringHash); i++) {
4954
      SEXP chain = VECTOR_ELT(R_StringHash, i);
4955
      if (! ISNULL(chain)) {
4956
    fprintf(f, "Line %d: ", i);
4957
    do {
4958
        if (IS_UTF8(CXHEAD(chain)))
4959
      fprintf(f, "U");
4960
        else if (IS_LATIN1(CXHEAD(chain)))
4961
      fprintf(f, "L");
4962
        else if (IS_BYTES(CXHEAD(chain)))
4963
      fprintf(f, "B");
4964
        fprintf(f, "|%s| ", CHAR(CXHEAD(chain)));
4965
        chain = CXTAIL(chain);
4966
    } while(! ISNULL(chain));
4967
    fprintf(f, "\n");
4968
      }
4969
  }
4970
  fclose(f);
4971
    }
4972
}
4973
#endif /* DEBUG_SHOW_CHARSXP_CACHE */
4974
4975
// topenv
4976
4977
1.99M
SEXP topenv(SEXP target, SEXP envir) {
4978
1.99M
    SEXP env = envir;
4979
6.11M
    while (env != R_EmptyEnv) {
4980
6.11M
  if (env == target || env == R_GlobalEnv ||
4981
6.10M
      env == R_BaseEnv || env == R_BaseNamespace ||
4982
4.12M
      R_IsPackageEnv(env) || R_IsNamespaceEnv(env) ||
4983
4.12M
      R_existsVarInFrame(env, R_dot_packageName)) {
4984
1.99M
      return env;
4985
4.12M
  } else {
4986
4.12M
      env = ENCLOS(env);
4987
4.12M
  }
4988
6.11M
    }
4989
0
    return R_GlobalEnv;
4990
1.99M
}
4991
4992
/** topenv():
4993
 *
4994
 * .Internal(topenv(envir, matchThisEnv))
4995
 *
4996
 * @return
4997
 */
4998
0
attribute_hidden SEXP do_topenv(SEXP call, SEXP op, SEXP args, SEXP rho) {
4999
0
    checkArity(op, args);
5000
0
    SEXP envir = CAR(args);
5001
0
    SEXP target = CADR(args); // = matchThisEnv, typically NULL (R_NilValue)
5002
0
    if (TYPEOF(envir) != ENVSXP) envir = rho; // envir = parent.frame()
5003
0
    if (target != R_NilValue && TYPEOF(target) != ENVSXP)  target = R_NilValue;
5004
0
    return topenv(target, envir);
5005
0
}
5006
5007
0
attribute_hidden Rboolean isUnmodifiedSpecSym(SEXP sym, SEXP env) {
5008
0
    if (!IS_SPECIAL_SYMBOL(sym))
5009
0
  return FALSE;
5010
0
    for(;env != R_EmptyEnv; env = ENCLOS(env))
5011
0
  if (!NO_SPECIAL_SYMBOLS(env) && env != R_BaseEnv
5012
0
    && env != R_BaseNamespace && R_existsVarInFrame(env, sym))
5013
0
      return FALSE;
5014
0
    return TRUE;
5015
0
}
5016
5017
attribute_hidden
5018
0
void findFunctionForBodyInNamespace(SEXP body, SEXP nsenv, SEXP nsname) {
5019
0
    if (R_IsNamespaceEnv(nsenv) != TRUE)
5020
0
  error("argument 'nsenv' is not a namespace");
5021
0
    SEXP args = PROTECT(list3(nsenv /* x */,
5022
0
  R_TrueValue /* all.names */,
5023
0
  R_FalseValue /* sorted */));
5024
0
    SEXP env2listOp = INTERNAL(install("env2list"));
5025
5026
0
    SEXP elist = do_env2list(R_NilValue, env2listOp, args, R_NilValue);
5027
0
    PROTECT(elist);
5028
0
    R_xlen_t n = xlength(elist);
5029
0
    R_xlen_t i;
5030
0
    SEXP names = PROTECT(getAttrib(elist, R_NamesSymbol));
5031
0
    for(i = 0; i < n; i++) {
5032
0
  SEXP value = VECTOR_ELT(elist, i);
5033
0
  const char *vname = CHAR(STRING_ELT(names, i));
5034
  /* the constants checking requires shallow comparison */
5035
0
  if (TYPEOF(value) == CLOSXP && R_ClosureExpr(value) == body)
5036
0
      REprintf("Function %s in namespace %s has this body.\n",
5037
0
    vname,
5038
0
    CHAR(PRINTNAME(nsname)));
5039
  /* search S4 registry */
5040
0
  const char *s4prefix = ".__T__";
5041
0
  if (TYPEOF(value) == ENVSXP &&
5042
0
    !strncmp(vname, s4prefix, strlen(s4prefix))) {
5043
0
      SETCAR(args, value); /* re-use args */
5044
0
      SEXP rlist = do_env2list(R_NilValue, env2listOp, args, R_NilValue);
5045
0
      PROTECT(rlist);
5046
0
      R_xlen_t rn = xlength(rlist);
5047
0
      R_xlen_t ri;
5048
0
      SEXP rnames = PROTECT(getAttrib(rlist, R_NamesSymbol));
5049
0
      for(ri = 0; ri < rn; ri++) {
5050
0
    SEXP rvalue = VECTOR_ELT(rlist, ri);
5051
    /* the constants checking requires shallow comparison */
5052
0
    if (TYPEOF(rvalue) == CLOSXP &&
5053
0
      R_ClosureExpr(rvalue) == body)
5054
0
        REprintf("S4 Method %s defined in namespace %s with "
5055
0
      "signature %s has this body.\n",
5056
0
      vname + strlen(s4prefix),
5057
0
      CHAR(PRINTNAME(nsname)),
5058
0
      CHAR(STRING_ELT(rnames, ri)));
5059
0
      }
5060
0
      UNPROTECT(2); /* rlist, rnames */
5061
0
  }
5062
0
    }
5063
0
    UNPROTECT(3); /* names, elist, args */
5064
0
}
5065
5066
/*  findFunctionForBody - for a given function body, try to find a closure and
5067
    the name of its binding (and the name of the package). For debugging. */
5068
0
attribute_hidden void findFunctionForBody(SEXP body) {
5069
0
    SEXP nstable = HASHTAB(R_NamespaceRegistry);
5070
0
    CHECK_HASH_TABLE(nstable);
5071
0
    int n = length(nstable);
5072
0
    int i;
5073
0
    for(i = 0; i < n; i++) {
5074
0
  SEXP frame = VECTOR_ELT(nstable, i);
5075
0
  while (frame != R_NilValue) {
5076
0
      findFunctionForBodyInNamespace(body, CAR(frame), TAG(frame));
5077
0
      frame = CDR(frame);
5078
0
  }
5079
0
    }
5080
0
}