@Specialization protected Object getDimNames(RAbstractContainer container) { controlVisibility(); RList names; if (container instanceof RDataFrame) { dataframeProfile.enter(); names = ((RDataFrame) container).getVector().getDimNames(); } else if (container instanceof RFactor) { factorProfile.enter(); names = ((RFactor) container).getVector().getDimNames(); } else { otherProfile.enter(); names = container.getDimNames(attrProfiles); } return nullProfile.profile(names == null) ? RNull.instance : names; }
// TODO Figure out how to distinguish f(,,a) from f(a) - RMissing is used in both contexts @RBuiltin( name = "nargs", kind = PRIMITIVE, parameterNames = {}) public abstract class NArgs extends RBuiltinNode { private final BranchProfile isPromiseProfile = BranchProfile.create(); @Specialization protected int doNArgs(VirtualFrame frame) { int result = 0; if (RArguments.getFunction(frame) == null) { return RRuntime.INT_NA; } int l = RArguments.getArgumentsLength(frame); for (int i = 0; i < l; i++) { Object arg = RArguments.getArgument(frame, i); if (arg instanceof RPromise) { isPromiseProfile.enter(); RPromise promise = (RPromise) arg; if (!promise.isDefault()) { result++; } } else if (arg instanceof RArgsValuesAndNames) { result += ((RArgsValuesAndNames) arg).getLength(); } else if (!(arg instanceof RMissing)) { result++; } } return result; } }
@Specialization public Object callNamedFunctionWithPackage( String name, RArgsValuesAndNames args, String packageName) { controlVisibility(); SymbolInfo symbolInfo = DLL.findSymbolInfo(name, packageName); if (symbolInfo == null) { errorProfile.enter(); throw RError.error(this, Message.C_SYMBOL_NOT_IN_TABLE, name); } return RFFIFactory.getRFFI() .getCallRFFI() .invokeCall(symbolInfo.address, symbolInfo.symbol, args.getArguments()); }
@Specialization public Object callNamedFunctionWithPackage( String name, RArgsValuesAndNames args, String packageName) { controlVisibility(); SymbolInfo symbolInfo = DLL.findSymbolInfo(name, packageName); if (symbolInfo == null) { errorProfile.enter(); throw RError.error(this, Message.C_SYMBOL_NOT_IN_TABLE, name); } Object list = encodeArgumentPairList(args, symbolInfo.symbol); // TODO: provide proper values for the CALL, OP and RHO parameters return RFFIFactory.getRFFI() .getCallRFFI() .invokeCall(symbolInfo.address, symbolInfo.symbol, new Object[] {CALL, OP, list, RHO}); }
@RBuiltin( name = "dimnames", kind = PRIMITIVE, parameterNames = {"x"}, dispatch = INTERNAL_GENERIC) public abstract class DimNames extends RBuiltinNode { private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final ConditionProfile nullProfile = ConditionProfile.createBinaryProfile(); private final BranchProfile dataframeProfile = BranchProfile.create(); private final BranchProfile factorProfile = BranchProfile.create(); private final BranchProfile otherProfile = BranchProfile.create(); @Specialization protected RNull getDimNames(@SuppressWarnings("unused") RNull operand) { controlVisibility(); return RNull.instance; } @Specialization protected Object getDimNames(RAbstractContainer container) { controlVisibility(); RList names; if (container instanceof RDataFrame) { dataframeProfile.enter(); names = ((RDataFrame) container).getVector().getDimNames(); } else if (container instanceof RFactor) { factorProfile.enter(); names = ((RFactor) container).getVector().getDimNames(); } else { otherProfile.enter(); names = container.getDimNames(attrProfiles); } return nullProfile.profile(names == null) ? RNull.instance : names; } }
@Specialization protected RList c( String f, RArgsValuesAndNames args, byte naok, byte dup, @SuppressWarnings("unused") RMissing rPackage, @SuppressWarnings("unused") RMissing encoding, // @Cached("create()") BranchProfile errorProfile) { controlVisibility(); SymbolInfo symbolInfo = DLL.findRegisteredSymbolinInDLL(f, null, ""); if (symbolInfo == null) { errorProfile.enter(); throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, f); } return DotC.dispatch( this, symbolInfo.address, symbolInfo.symbol, naok, dup, args.getArguments()); }
@Specialization protected int doNArgs(VirtualFrame frame) { int result = 0; if (RArguments.getFunction(frame) == null) { return RRuntime.INT_NA; } int l = RArguments.getArgumentsLength(frame); for (int i = 0; i < l; i++) { Object arg = RArguments.getArgument(frame, i); if (arg instanceof RPromise) { isPromiseProfile.enter(); RPromise promise = (RPromise) arg; if (!promise.isDefault()) { result++; } } else if (arg instanceof RArgsValuesAndNames) { result += ((RArgsValuesAndNames) arg).getLength(); } else if (!(arg instanceof RMissing)) { result++; } } return result; }
@RBuiltin( name = ".Call.graphics", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "...", "PACKAGE"}) public abstract static class DotCallGraphics extends LookupAdapter { private final BranchProfile errorProfile = BranchProfile.create(); @Override public Object[] getDefaultParameterValues() { return new Object[] {RMissing.instance, RArgsValuesAndNames.EMPTY, RMissing.instance}; } @Override protected RExternalBuiltinNode lookupBuiltin(RList f) { switch (lookupName(f)) { default: return null; } } @SuppressWarnings("unused") @Specialization( limit = "1", guards = {"cached == f", "builtin != null"}) protected Object doExternal( RList f, RArgsValuesAndNames args, RMissing packageName, // @Cached("f") RList cached, // @Cached("lookupBuiltin(f)") RExternalBuiltinNode builtin) { controlVisibility(); return builtin.call(args); } @Specialization public Object callNamedFunction( VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) { return RFFIFactory.getRFFI() .getCallRFFI() .invokeCall( getAddressFromSymbolInfo(frame, symbol), getNameFromSymbolInfo(frame, symbol), args.getArguments()); } @Specialization public Object callNamedFunction( String name, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { return callNamedFunctionWithPackage(name, args, null); } @Specialization public Object callNamedFunctionWithPackage( String name, RArgsValuesAndNames args, String packageName) { controlVisibility(); SymbolInfo symbolInfo = DLL.findSymbolInfo(name, packageName); if (symbolInfo == null) { errorProfile.enter(); throw RError.error(this, Message.C_SYMBOL_NOT_IN_TABLE, name); } return RFFIFactory.getRFFI() .getCallRFFI() .invokeCall(symbolInfo.address, symbolInfo.symbol, args.getArguments()); } @Fallback protected Object dotCallFallback( Object fobj, @SuppressWarnings("unused") Object args, @SuppressWarnings("unused") Object packageName) { throw fallback(fobj); } }
@RBuiltin( name = ".External.graphics", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "...", "PACKAGE"}) public abstract static class DotExternalGraphics extends LookupAdapter { private final BranchProfile errorProfile = BranchProfile.create(); @Override protected RExternalBuiltinNode lookupBuiltin(RList f) { if (FastROptions.UseInternalGraphics.getBooleanValue()) { switch (lookupName(f)) { case "C_mtext": return new GraphicsCCalls.C_mtext(); case "C_plotXY": return new C_PlotXY(); } } return null; } @SuppressWarnings("unused") @Specialization( limit = "1", guards = {"cached == f", "builtin != null"}) protected Object doExternal( RList f, RArgsValuesAndNames args, RMissing packageName, // @Cached("f") RList cached, // @Cached("lookupBuiltin(f)") RExternalBuiltinNode builtin) { controlVisibility(); return builtin.call(args); } @Specialization public Object callNamedFunction( VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) { String name = getNameFromSymbolInfo(frame, symbol); Object list = encodeArgumentPairList(args, name); return RFFIFactory.getRFFI() .getCallRFFI() .invokeCall(getAddressFromSymbolInfo(frame, symbol), name, new Object[] {list}); } @Specialization public Object callNamedFunction( String name, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { return callNamedFunctionWithPackage(name, args, null); } @Specialization public Object callNamedFunctionWithPackage( String name, RArgsValuesAndNames args, String packageName) { controlVisibility(); SymbolInfo symbolInfo = DLL.findSymbolInfo(name, packageName); if (symbolInfo == null) { errorProfile.enter(); throw RError.error(this, Message.C_SYMBOL_NOT_IN_TABLE, name); } Object list = encodeArgumentPairList(args, symbolInfo.symbol); return RFFIFactory.getRFFI() .getCallRFFI() .invokeCall(symbolInfo.address, symbolInfo.symbol, new Object[] {list}); } @Fallback protected Object fallback( Object f, @SuppressWarnings("unused") Object args, @SuppressWarnings("unused") Object packageName) { throw fallback(f); } }
@RBuiltin( name = ".External2", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "...", "PACKAGE"}) public abstract static class DotExternal2 extends LookupAdapter { private static final Object CALL = "call"; private static final Object OP = "op"; private static final Object RHO = "rho"; private final BranchProfile errorProfile = BranchProfile.create(); @Override protected RExternalBuiltinNode lookupBuiltin(RList f) { if (FastROptions.UseInternalGraphics.getBooleanValue()) { switch (lookupName(f)) { case "C_par": return new C_Par(); } } String name = lookupName(f); switch (name) { // tools case "writetable": return new WriteTable(); case "typeconvert": return TypeConvertNodeGen.create(); case "C_parseRd": return C_ParseRdNodeGen.create(); default: return null; } } @SuppressWarnings("unused") @Specialization( limit = "1", guards = {"cached == f", "builtin != null"}) protected Object doExternal( RList f, RArgsValuesAndNames args, RMissing packageName, // @Cached("f") RList cached, // @Cached("lookupBuiltin(f)") RExternalBuiltinNode builtin) { controlVisibility(); return builtin.call(args); } @Specialization public Object callNamedFunction( VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) { String name = getNameFromSymbolInfo(frame, symbol); Object list = encodeArgumentPairList(args, name); // TODO: provide proper values for the CALL, OP and RHO parameters return RFFIFactory.getRFFI() .getCallRFFI() .invokeCall( getAddressFromSymbolInfo(frame, symbol), name, new Object[] {CALL, OP, list, RHO}); } @Specialization public Object callNamedFunction( String name, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { return callNamedFunctionWithPackage(name, args, null); } @Specialization public Object callNamedFunctionWithPackage( String name, RArgsValuesAndNames args, String packageName) { controlVisibility(); SymbolInfo symbolInfo = DLL.findSymbolInfo(name, packageName); if (symbolInfo == null) { errorProfile.enter(); throw RError.error(this, Message.C_SYMBOL_NOT_IN_TABLE, name); } Object list = encodeArgumentPairList(args, symbolInfo.symbol); // TODO: provide proper values for the CALL, OP and RHO parameters return RFFIFactory.getRFFI() .getCallRFFI() .invokeCall(symbolInfo.address, symbolInfo.symbol, new Object[] {CALL, OP, list, RHO}); } @Fallback protected Object fallback( Object f, @SuppressWarnings("unused") Object args, @SuppressWarnings("unused") Object packageName) { throw fallback(f); } }
@RBuiltin( name = ".External", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "...", "PACKAGE"}) public abstract static class DotExternal extends LookupAdapter { private final BranchProfile errorProfile = BranchProfile.create(); @Override protected RExternalBuiltinNode lookupBuiltin(RList f) { String name = lookupName(f); if (FastROptions.UseInternalGraphics.getBooleanValue()) { switch (name) { case "PDF": return new DevicesCCalls.C_PDF(); case "devoff": return new DevicesCCalls.C_DevOff(); case "devcur": return new DevicesCCalls.C_DevCur(); } } switch (name) { case "compcases": return new CompleteCases(); // utils case "countfields": return new CountFields(); case "readtablehead": return new ReadTableHead(); case "rnorm": return RnormNodeGen.create(); case "runif": return RunifNodeGen.create(); case "qgamma": return QgammaNodeGen.create(); case "download": return new Download(); case "unzip": case "Rprof": case "Rprofmem": case "addhistory": case "loadhistory": case "savehistory": case "dataentry": case "dataviewer": case "edit": case "fileedit": case "selectlist": return new UnimplementedExternal(name); default: return null; } } @SuppressWarnings("unused") @Specialization( limit = "1", guards = {"cached == f", "builtin != null"}) protected Object doExternal( RList f, RArgsValuesAndNames args, RMissing packageName, // @Cached("f") RList cached, // @Cached("lookupBuiltin(f)") RExternalBuiltinNode builtin) { controlVisibility(); return builtin.call(args); } @Specialization public Object callNamedFunction( VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) { String name = getNameFromSymbolInfo(frame, symbol); Object list = encodeArgumentPairList(args, name); return RFFIFactory.getRFFI() .getCallRFFI() .invokeCall(getAddressFromSymbolInfo(frame, symbol), name, new Object[] {list}); } @Specialization public Object callNamedFunction( String name, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { return callNamedFunctionWithPackage(name, args, null); } @Specialization public Object callNamedFunctionWithPackage( String name, RArgsValuesAndNames args, String packageName) { controlVisibility(); SymbolInfo symbolInfo = DLL.findSymbolInfo(name, packageName); if (symbolInfo == null) { errorProfile.enter(); throw RError.error(this, Message.C_SYMBOL_NOT_IN_TABLE, name); } Object list = encodeArgumentPairList(args, symbolInfo.symbol); return RFFIFactory.getRFFI() .getCallRFFI() .invokeCall(symbolInfo.address, symbolInfo.symbol, new Object[] {list}); } @Fallback protected Object fallback( Object f, @SuppressWarnings("unused") Object args, @SuppressWarnings("unused") Object packageName) { throw fallback(f); } }
/** * Handles the generic case, but also many special case functions that are called from the default * packages. */ @RBuiltin( name = ".Call", kind = RBuiltinKind.PRIMITIVE, parameterNames = {".NAME", "...", "PACKAGE"}) public abstract static class DotCall extends LookupAdapter { private final BranchProfile errorProfile = BranchProfile.create(); @Override public Object[] getDefaultParameterValues() { return new Object[] {RMissing.instance, RArgsValuesAndNames.EMPTY, RMissing.instance}; } @Override protected RExternalBuiltinNode lookupBuiltin(RList f) { String name = lookupName(f); switch (name) { // methods case "R_initMethodDispatch": return R_initMethodDispatchNodeGen.create(); case "R_methodsPackageMetaName": return R_methodsPackageMetaNameNodeGen.create(); case "R_set_method_dispatch": return R_set_method_dispatchNodeGen.create(); case "R_M_setPrimitiveMethods": return R_M_setPrimitiveMethodsNodeGen.create(); case "R_getClassFromCache": return R_getClassFromCacheNodeGen.create(); case "R_clear_method_selection": case "R_dummy_extern_place": case "R_el_named": return new UnimplementedExternal(name); case "R_externalptr_prototype_object": return R_externalPtrPrototypeObjectNodeGen.create(); case "R_getGeneric": return R_getGenericNodeGen.create(); case "R_get_slot": return R_getSlotNodeGen.create(); case "R_hasSlot": return new UnimplementedExternal(name); case "R_identC": return R_identCNodeGen.create(); case "R_methods_test_MAKE_CLASS": case "R_methods_test_NEW": case "R_missingArg": case "R_nextMethodCall": return R_nextMethodCallNodeGen.create(); case "R_quick_method_check": case "R_selectMethod": case "R_set_el_named": return new UnimplementedExternal(name); case "R_set_slot": return R_setSlotNodeGen.create(); case "R_standardGeneric": return new UnimplementedExternal(name); case "do_substitute_direct": return SubstituteDirectNodeGen.create(); case "Rf_allocS4Object": case "R_get_primname": return new UnimplementedExternal(name); case "new_object": return NewObjectNodeGen.create(); // stats case "fft": return new Fft(); case "cov": return new Covcor(false); case "cor": return new Covcor(true); case "SplineCoef": return SplineCoefNodeGen.create(); case "SplineEval": return SplineEvalNodeGen.create(); case "cutree": case "isoreg": case "monoFC_m": case "numeric_deriv": case "nls_iter": case "setup_starma": case "free_starma": case "set_trans": case "arma0fa": case "get_s2": case "get_resid": case "Dotrans": case "arma0_kfore": case "Starma_method": case "Invtrans": case "Gradtrans": case "ARMAtoMA": case "KalmanLike": case "KalmanFore": case "KalmanSmooth": case "ARIMA_undoPars": case "ARIMA_transPars": case "ARIMA_Invtrans": case "ARIMA_Gradtrans": case "ARIMA_Like": case "ARIMA_CSS": case "TSconv": case "getQ0": case "getQ0bis": case "port_ivset": case "port_nlminb": case "port_nlsb": case "logit_link": case "logit_linkinv": case "logit_mu_eta": case "binomial_dev_resids": case "rWishart": case "Cdqrls": case "Cdist": case "updateform": case "mvfft": case "nextn": case "r2dtable": case "cfilter": case "rfilter": case "lowess": case "DoubleCentre": case "BinDist": case "Rsm": case "tukeyline": case "runmed": case "influence": case "pSmirnov2x": case "pKolmogorov2x": case "pKS2": case "ksmooth": case "Approx": case "ApproxTest": case "LogLin": case "pAnsari": case "qAnsari": case "pKendall": case "pRho": case "SWilk": case "bw_den": case "bw_ucv": case "bw_bcv": case "bw_phi4": case "bw_phi6": case "acf": case "pacf1": case "ar2ma": case "Burg": case "intgrt_vec": case "pp_sum": case "Fexact": case "Fisher_sim": case "chisq_sim": case "d2x2xk": return new UnimplementedExternal(name); // tools case "doTabExpand": return DoTabExpandNodeGen.create(); case "codeFilesAppend": return CodeFilesAppendNodeGen.create(); case "Rmd5": return Rmd5NodeGen.create(); case "dirchmod": return DirChmodNodeGen.create(); case "delim_match": case "C_getfmts": case "check_nonASCII": case "check_nonASCII2": case "ps_kill": case "ps_sigs": case "ps_priority": case "startHTTPD": case "stopHTTPD": case "C_deparseRd": return new UnimplementedExternal(name); // utils case "crc64": return Crc64NodeGen.create(); case "flushconsole": return new Flushconsole(); case "menu": return MenuNodeGen.create(); case "nsl": case "objectSize": case "processevents": case "octsize": case "sockconnect": case "sockread": case "sockclose": case "sockopen": case "socklisten": case "sockwrite": return new UnimplementedExternal(name); // grDevices case "cairoProps": return CairoPropsNodeGen.create(); case "makeQuartzDefault": return new MakeQuartzDefault(); // grid case "L_initGrid": return InitGridNodeGen.create(); default: return null; } } @SuppressWarnings("unused") @Specialization( limit = "1", guards = {"cached == f", "builtin != null"}) protected Object doExternal( RList f, RArgsValuesAndNames args, RMissing packageName, // @Cached("f") RList cached, // @Cached("lookupBuiltin(f)") RExternalBuiltinNode builtin) { controlVisibility(); return builtin.call(args); } @Specialization public Object callNamedFunction( VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) { controlVisibility(); return RFFIFactory.getRFFI() .getCallRFFI() .invokeCall( getAddressFromSymbolInfo(frame, symbol), getNameFromSymbolInfo(frame, symbol), args.getArguments()); } @Specialization public Object callNamedFunction( String name, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { return callNamedFunctionWithPackage(name, args, null); } @Specialization public Object callNamedFunctionWithPackage( String name, RArgsValuesAndNames args, String packageName) { controlVisibility(); SymbolInfo symbolInfo = DLL.findSymbolInfo(name, packageName); if (symbolInfo == null) { errorProfile.enter(); throw RError.error(this, Message.C_SYMBOL_NOT_IN_TABLE, name); } return RFFIFactory.getRFFI() .getCallRFFI() .invokeCall(symbolInfo.address, symbolInfo.symbol, args.getArguments()); } @Fallback protected Object dotCallFallback( Object fobj, @SuppressWarnings("unused") Object args, @SuppressWarnings("unused") Object packageName) { throw fallback(fobj); } }
/** * {@link WriteSuperFrameVariableNode} captures a write to a variable in some parent frame. * * <p>The state starts out a "unresolved" and transforms to "resolved". */ @SuppressWarnings("unused") @NodeChildren({ @NodeChild(value = "enclosingFrame", type = AccessEnclosingFrameNode.class), @NodeChild(value = "frameSlotNode", type = FrameSlotNode.class) }) @NodeField(name = "mode", type = Mode.class) public abstract class WriteSuperFrameVariableNode extends WriteSuperFrameVariableNodeHelper { private final ValueProfile storedObjectProfile = ValueProfile.createClassProfile(); private final BranchProfile invalidateProfile = BranchProfile.create(); private final ValueProfile enclosingFrameProfile = ValueProfile.createClassProfile(); protected abstract FrameSlotNode getFrameSlotNode(); public abstract Mode getMode(); public static WriteVariableNode create(String name, RNode rhs, Mode mode) { return new UnresolvedWriteSuperFrameVariableNode(name, rhs, mode); } @Specialization(guards = "isLogicalKind(frame, frameSlot)") protected void doLogical( VirtualFrame frame, byte value, MaterializedFrame enclosingFrame, FrameSlot frameSlot) { FrameSlotChangeMonitor.setByteAndInvalidate( enclosingFrameProfile.profile(enclosingFrame), frameSlot, value, true, invalidateProfile); } @Specialization(guards = "isIntegerKind(frame, frameSlot)") protected void doInteger( VirtualFrame frame, int value, MaterializedFrame enclosingFrame, FrameSlot frameSlot) { FrameSlotChangeMonitor.setIntAndInvalidate( enclosingFrameProfile.profile(enclosingFrame), frameSlot, value, true, invalidateProfile); } @Specialization(guards = "isDoubleKind(frame, frameSlot)") protected void doDouble( VirtualFrame frame, double value, MaterializedFrame enclosingFrame, FrameSlot frameSlot) { FrameSlotChangeMonitor.setDoubleAndInvalidate( enclosingFrameProfile.profile(enclosingFrame), frameSlot, value, true, invalidateProfile); } @Specialization protected void doObject( VirtualFrame frame, Object value, MaterializedFrame enclosingFrame, FrameSlot frameSlot) { MaterializedFrame profiledFrame = enclosingFrameProfile.profile(enclosingFrame); Object newValue = shareObjectValue( profiledFrame, frameSlot, storedObjectProfile.profile(value), getMode(), true); FrameSlotChangeMonitor.setObjectAndInvalidate( profiledFrame, frameSlot, newValue, true, invalidateProfile); } public static class UnresolvedWriteSuperFrameVariableNode extends WriteSuperFrameVariableNodeHelper { @Child private RNode rhs; private final String symbol; private final BaseWriteVariableNode.Mode mode; public UnresolvedWriteSuperFrameVariableNode( String symbol, RNode rhs, BaseWriteVariableNode.Mode mode) { this.rhs = rhs; this.symbol = symbol; this.mode = mode; } @Override public String getName() { return symbol; } @Override public RNode getRhs() { return rhs; } @Override public void execute(VirtualFrame frame, Object value, MaterializedFrame enclosingFrame) { CompilerDirectives.transferToInterpreterAndInvalidate(); if (getName().isEmpty()) { throw RError.error(this, RError.Message.ZERO_LENGTH_VARIABLE); } final WriteSuperFrameVariableNodeHelper writeNode; if (REnvironment.isGlobalEnvFrame(enclosingFrame)) { /* * we've reached the global scope, do unconditional write. if this is the first node * in the chain, needs the rhs and enclosingFrame nodes */ AccessEnclosingFrameNode enclosingFrameNode = RArguments.getEnclosingFrame(frame) == enclosingFrame ? new AccessEnclosingFrameNode() : null; writeNode = WriteSuperFrameVariableNodeGen.create( getRhs(), enclosingFrameNode, FrameSlotNode.create( findOrAddFrameSlot( enclosingFrame.getFrameDescriptor(), symbol, FrameSlotKind.Illegal)), getName(), mode); } else { WriteSuperFrameVariableNode actualWriteNode = WriteSuperFrameVariableNodeGen.create( null, null, FrameSlotNode.create(symbol), this.getName(), mode); writeNode = new WriteSuperFrameVariableConditionalNode( actualWriteNode, new UnresolvedWriteSuperFrameVariableNode(symbol, null, mode), getRhs()); } replace(writeNode).execute(frame, value, enclosingFrame); } @Override public void execute(VirtualFrame frame, Object value) { CompilerDirectives.transferToInterpreterAndInvalidate(); MaterializedFrame enclosingFrame = RArguments.getEnclosingFrame(frame); if (enclosingFrame != null) { execute(frame, value, enclosingFrame); } else { // we're in global scope, do a local write instead replace(UnresolvedWriteLocalFrameVariableNodeGen.create(getRhs(), symbol, mode)) .execute(frame, value); } } } public static class WriteSuperFrameVariableConditionalNode extends WriteSuperFrameVariableNodeHelper { @Child private WriteSuperFrameVariableNode writeNode; @Child private WriteSuperFrameVariableNodeHelper nextNode; @Child private RNode rhs; private final ValueProfile enclosingFrameProfile = ValueProfile.createClassProfile(); private final ConditionProfile hasValueProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile nullSuperFrameProfile = ConditionProfile.createBinaryProfile(); WriteSuperFrameVariableConditionalNode( WriteSuperFrameVariableNode writeNode, WriteSuperFrameVariableNodeHelper nextNode, RNode rhs) { this.writeNode = writeNode; this.nextNode = nextNode; this.rhs = rhs; } @Override public Object getName() { return writeNode.getName(); } @Override public RNode getRhs() { return rhs; } @Override public void execute(VirtualFrame frame, Object value, MaterializedFrame enclosingFrame) { MaterializedFrame profiledEnclosingFrame = enclosingFrameProfile.profile(enclosingFrame); if (hasValueProfile.profile(writeNode.getFrameSlotNode().hasValue(profiledEnclosingFrame))) { writeNode.execute(frame, value, profiledEnclosingFrame); } else { MaterializedFrame superFrame = RArguments.getEnclosingFrame(profiledEnclosingFrame); if (nullSuperFrameProfile.profile(superFrame == null)) { // Might be the case if "{ x <<- 42 }": This is in globalEnv! superFrame = REnvironment.globalEnv().getFrame(); } nextNode.execute(frame, value, superFrame); } } @Override public void execute(VirtualFrame frame, Object value) { assert RArguments.getEnclosingFrame(frame) != null; execute(frame, value, RArguments.getEnclosingFrame(frame)); } } }
abstract class PositionCheckNode extends Node { protected final Class<?> positionClass; protected final int dimensionIndex; protected final int numDimensions; protected final VectorLengthProfile positionLengthProfile = VectorLengthProfile.create(); protected final BranchProfile error = BranchProfile.create(); protected final boolean replace; protected final RType containerType; @Child private PositionCastNode castNode; @Child private RLengthNode positionLengthNode = RLengthNode.create(); @Child private PositionCharacterLookupNode characterLookup; PositionCheckNode( ElementAccessMode mode, RType containerType, Object positionValue, int dimensionIndex, int numDimensions, boolean exact, boolean replace) { this.positionClass = positionValue.getClass(); this.dimensionIndex = dimensionIndex; this.numDimensions = numDimensions; this.replace = replace; this.containerType = containerType; this.castNode = PositionCastNode.create(mode, replace); if (positionValue instanceof String || positionValue instanceof RAbstractStringVector) { boolean useNAForNotFound = !replace && isListLike(containerType) && mode.isSubscript(); characterLookup = new PositionCharacterLookupNode( mode, numDimensions, dimensionIndex, useNAForNotFound, exact); } } protected static boolean isListLike(RType type) { switch (type) { case Language: case DataFrame: case Expression: case PairList: case List: return true; } return false; } public boolean isIgnoreDimension() { return positionClass == RMissing.class; } public Class<?> getPositionClass() { return positionClass; } public final boolean isSupported(Object object) { return object.getClass() == positionClass; } public static PositionCheckNode createNode( ElementAccessMode mode, RType containerType, Object position, int positionIndex, int numDimensions, boolean exact, boolean replace, boolean recursive) { if (mode.isSubset()) { return PositionCheckSubsetNodeGen.create( mode, containerType, position, positionIndex, numDimensions, exact, replace); } else { return PositionCheckSubscriptNodeGen.create( mode, containerType, position, positionIndex, numDimensions, exact, replace, recursive); } } protected boolean isMultiDimension() { return numDimensions > 1; } public final Object execute( PositionProfile profile, RAbstractContainer vector, int[] vectorDimensions, int vectorLength, Object position) { Object castPosition = castNode.execute(positionClass.cast(position)); int dimensionLength; if (numDimensions == 1) { dimensionLength = vectorLength; } else { assert vectorDimensions != null; assert vectorDimensions.length == numDimensions; dimensionLength = vectorDimensions[dimensionIndex]; } if (characterLookup != null) { castPosition = characterLookup.execute(vector, (RAbstractStringVector) castPosition, dimensionLength); } RTypedValue positionVector = (RTypedValue) profilePosition(castPosition); int positionLength; if (positionVector instanceof RMissing) { positionLength = -1; } else { positionLength = positionLengthProfile.profile(((RAbstractVector) positionVector).getLength()); } assert isValidCastedType(positionVector) : "result type of a position cast node must be integer or logical"; return execute(profile, dimensionLength, positionVector, positionLength); } private final ValueProfile castedValue = ValueProfile.createClassProfile(); Object profilePosition(Object positionVector) { return castedValue.profile(positionVector); } private static boolean isValidCastedType(RTypedValue positionVector) { RType type = positionVector.getRType(); return type == RType.Integer || type == RType.Logical || type == RType.Character || type == RType.Double || type == RType.Null; } public abstract Object execute( PositionProfile statistics, int dimensionLength, Object position, int positionLength); }