Commit d84b5751 authored by Radford Neal's avatar Radford Neal

Merge branch '51-safeguard-call' into 52-opt

parents e9bb8bdb f2629fe5
......@@ -5,3 +5,6 @@ that are atomic scalars with no attributes if they have NAMEDCNT > 1.
Also re-organizes stuff in dotcode.c, and handling of builtins in
eval. .C, .Fortran, .Call, and .External are now "specials", and
evaluate their own arguments, and create their own contexts.
Somewhat motivated by the above changes, the 'methods' package now
uses new .Internals called get_slot.internal and set_slot.internal.
......@@ -264,7 +264,7 @@ slot <-
## Because slots are stored as attributes, the validity check is not 100% guaranteed,
## but should be OK if nobody has "cheated" (e.g., by setting other attributes directly).
function(object, name)
.Call("R_get_slot", object, name, PACKAGE = "methods")
.Internal (get_slot.internal (object, name))
"slot<-" <-
## Set the value of the named slot. Must be one of the slots in the class's
......@@ -681,12 +681,13 @@ initialize <- function(.Object, ...) {
firstTime <- FALSE
} else {
## Do the assignment in-place. .Object should be unshared
## now, which is good, since R_set_slot modifies it
## regardless. The assignment of the result of .Call to
## now, which is good, since set_slot.internal modifies it
## regardless. The assignment of the result to
## .Object is therefore redundant, but is done so that this
## code will work even if the setup is someday fixed to
## work as it should.
.Object <- .Call ("R_set_slot", .Object, slotName, slotVal)
.Object <-
.Internal (set_slot.internal (.Object, slotName, slotVal))
}
}
}
......
......@@ -1569,10 +1569,28 @@ int R_has_slot(SEXP obj, SEXP name) {
return(getAttrib(obj, name) != R_NilValue);
}
/* the @ operator, and its assignment form. Processed much like $
/* The @ operator, and its assignment form. Processed much like $
(see do_subset3) but without S3-style methods.
*/
/* currently, R_get_slot() ["methods"] is a trivial wrapper for this: */
/* Slot getting for the 'methods' package. In pqR, the 'method'
package has been changed to call R_do_slot via .Internal, in order
to bypass the safeguarding of .Call argument modification that is
now done (to avoid this overhead), and because it also makes more
sense given the dependence of 'methods' on the interpreter.
R_do_slot can be called with .Call, which is done by the 'Matrix'
package via GET_SLOT (defined in Rdefines.h, but not mentioned in
the manuals). */
static SEXP do_get_slot (SEXP call, SEXP op, SEXP args, SEXP env)
{
checkArity (op, args);
return R_do_slot (CAR(args), CADR(args));
}
SEXP R_do_slot(SEXP obj, SEXP name) {
R_SLOT_INIT;
if(name == s_dot_Data)
......@@ -1621,7 +1639,7 @@ SEXP R_do_slot(SEXP obj, SEXP name) {
makes more sense given the dependence of 'methods' on the interpreter.
R_do_slot_assign can be called with .Call, which is done by the
'Matrix' package (often via SET_SLOT, defined in Rdefines.h, but
'Matrix' package, often via SET_SLOT (defined in Rdefines.h, but
not mentioned in the manuals). */
static SEXP do_set_slot (SEXP call, SEXP op, SEXP args, SEXP env)
......@@ -1806,6 +1824,7 @@ attribute_hidden FUNTAB R_FunTab_attrib[] =
{"@", do_AT, 0, 0, 2, {PP_DOLLAR, PREC_DOLLAR, 0}},
{"set_slot.internal", do_set_slot, 0, 11, 3, {PP_FUNCALL, PREC_FN, }},
{"get_slot.internal", do_get_slot, 0, 11, 2, {PP_FUNCALL, PREC_FN, }},
{NULL, NULL, 0, 0, 0, {PP_INVALID, PREC_FN, 0}}
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment