diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java index 6f96dfae9a811e10c15b5cbc3b0b668ac538577b..f05db2645238af1a811fc35558b8746c4b71d8bf 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java @@ -1650,11 +1650,36 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { throw implementedAsNode(); } + @Override + public Object FORMALS(Object x) { + throw implementedAsNode(); + } + + @Override + public Object BODY(Object x) { + throw implementedAsNode(); + } + @Override public Object CLOENV(Object x) { throw implementedAsNode(); } + @Override + public void SET_FORMALS(Object x, Object y) { + throw implementedAsNode(); + } + + @Override + public void SET_BODY(Object x, Object y) { + throw implementedAsNode(); + } + + @Override + public void SET_CLOENV(Object x, Object y) { + throw implementedAsNode(); + } + @Override public Object octsize(Object size) { throw implementedAsNode(); diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java index 337ea568cd689585503b227ddb5001afbd5aa572..79eecdc8078f5bff3db1aa1d48989e59ae8177eb 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java @@ -23,17 +23,25 @@ package com.oracle.truffle.r.ffi.impl.nodes; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.TypeSystemReference; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.GetFunctionBodyNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.GetFunctionEnvironmentNodeGen; +import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.GetFunctionFormalsNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.LENGTHNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.OctSizeNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoNewObjectNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoSlotAssignNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoSlotNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RHasSlotNodeGen; +import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.SetFunctionBodyNodeGen; +import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.SetFunctionEnvironmentNodeGen; +import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.SetFunctionFormalsNodeGen; +import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.access.AccessSlotNode; import com.oracle.truffle.r.nodes.access.AccessSlotNodeGen; import com.oracle.truffle.r.nodes.access.HasSlotNode; @@ -43,6 +51,7 @@ import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNames import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctionsFactory.SetNamesAttributeNodeGen; import com.oracle.truffle.r.nodes.builtin.EnvironmentNodes.GetFunctionEnvironmentNode; import com.oracle.truffle.r.nodes.builtin.casts.fluent.CastNodeBuilder; +import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode; import com.oracle.truffle.r.nodes.objects.NewObject; import com.oracle.truffle.r.nodes.objects.NewObjectNodeGen; import com.oracle.truffle.r.nodes.unary.CastNode; @@ -240,12 +249,41 @@ public final class MiscNodes { } } + @TypeSystemReference(RTypes.class) + public abstract static class GetFunctionBody extends FFIUpCallNode.Arg1 { + + @Specialization + @TruffleBoundary + public static Object body(RFunction fun) { + RootNode root = fun.getRootNode(); + if (root instanceof FunctionDefinitionNode) { + return RASTUtils.createLanguageElement(((FunctionDefinitionNode) root).getBody()); + } else { + return RNull.instance; + } + } + + public static GetFunctionBody create() { + return GetFunctionBodyNodeGen.create(); + } + } + + @TypeSystemReference(RTypes.class) + public abstract static class GetFunctionFormals extends FFIUpCallNode.Arg1 { + + @Specialization + protected Object formals(RFunction fun) { + return RASTUtils.createFormals(fun); + } + + public static GetFunctionFormals create() { + return GetFunctionFormalsNodeGen.create(); + } + } + @TypeSystemReference(RTypes.class) public abstract static class GetFunctionEnvironment extends FFIUpCallNode.Arg1 { - /** - * Returns the environment that {@code func} was created in. - */ @Specialization protected Object environment(RFunction fun, @Cached("create()") GetFunctionEnvironmentNode getEnvNode) { @@ -257,6 +295,52 @@ public final class MiscNodes { } } + @TypeSystemReference(RTypes.class) + public abstract static class SetFunctionBody extends FFIUpCallNode.Arg2 { + + @Specialization + @TruffleBoundary + protected Object body(RFunction fun, Object body) { + RASTUtils.modifyFunction(fun, body, RASTUtils.createFormals(fun), fun.getEnclosingFrame()); + return RNull.instance; + } + + public static SetFunctionBody create() { + return SetFunctionBodyNodeGen.create(); + } + } + + @TypeSystemReference(RTypes.class) + public abstract static class SetFunctionFormals extends FFIUpCallNode.Arg2 { + + @Specialization + @TruffleBoundary + protected Object formals(RFunction fun, Object formals) { + RASTUtils.modifyFunction(fun, GetFunctionBody.body(fun), formals, fun.getEnclosingFrame()); + return RNull.instance; + } + + public static SetFunctionFormals create() { + return SetFunctionFormalsNodeGen.create(); + } + } + + @TypeSystemReference(RTypes.class) + public abstract static class SetFunctionEnvironment extends FFIUpCallNode.Arg2 { + + @Specialization + @TruffleBoundary + protected Object environment(RFunction fun, REnvironment env) { + RASTUtils.modifyFunction(fun, GetFunctionBody.body(fun), RASTUtils.createFormals(fun), env.getFrame()); + fun.reassignEnclosingFrame(env.getFrame()); + return RNull.instance; + } + + public static SetFunctionEnvironment create() { + return SetFunctionEnvironmentNodeGen.create(); + } + } + @TypeSystemReference(RTypes.class) public abstract static class OctSizeNode extends FFIUpCallNode.Arg1 { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java index d0d15300319f687893cf06d6516f37cc675a1e89..9a9572d03e317184658ddace304da097edcc50e6 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java @@ -242,6 +242,24 @@ public interface StdUpCallsRFFI { Object SETCDR(Object x, Object y); + @RFFIUpCallNode(MiscNodes.GetFunctionFormals.class) + Object FORMALS(Object x); + + @RFFIUpCallNode(MiscNodes.GetFunctionBody.class) + Object BODY(Object x); + + @RFFIUpCallNode(MiscNodes.GetFunctionEnvironment.class) + Object CLOENV(Object x); + + @RFFIUpCallNode(MiscNodes.SetFunctionFormals.class) + void SET_FORMALS(Object x, Object y); + + @RFFIUpCallNode(MiscNodes.SetFunctionBody.class) + void SET_BODY(Object x, Object y); + + @RFFIUpCallNode(MiscNodes.SetFunctionEnvironment.class) + void SET_CLOENV(Object x, Object y); + @RFFIUpCallNode(SETCADRNode.class) Object SETCADR(Object x, Object y); @@ -410,9 +428,6 @@ public interface StdUpCallsRFFI { @RFFIUpCallNode(MiscNodes.RHasSlotNode.class) int R_has_slot(Object container, Object name); - @RFFIUpCallNode(MiscNodes.GetFunctionEnvironment.class) - Object CLOENV(Object x); - @RFFIUpCallNode(MiscNodes.OctSizeNode.class) Object octsize(Object size); diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h index cc3ddaf77801fcbcf663e28e6f02d1be12094a4f..f472a5b7c8ea28d2c21ccfa7533b787079a154ec 100644 --- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h +++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h @@ -3,181 +3,186 @@ #define RFFI_UPCALLSINDEX_H #define ATTRIB_x 0 -#define CAAR_x 1 -#define CAD4R_x 2 -#define CADDDR_x 3 -#define CADDR_x 4 -#define CADR_x 5 -#define CAR_x 6 -#define CDAR_x 7 -#define CDDDR_x 8 -#define CDDR_x 9 -#define CDR_x 10 -#define CLOENV_x 11 -#define COMPLEX_x 12 -#define DUPLICATE_ATTRIB_x 13 -#define ENCLOS_x 14 -#define FASTR_getConnectionChar_x 15 -#define GetRNGstate_x 16 -#define INTEGER_x 17 -#define IS_S4_OBJECT_x 18 -#define LENGTH_x 19 -#define LOGICAL_x 20 -#define NAMED_x 21 -#define OBJECT_x 22 -#define PRCODE_x 23 -#define PRENV_x 24 -#define PRINTNAME_x 25 -#define PRSEEN_x 26 -#define PRVALUE_x 27 -#define PutRNGstate_x 28 -#define RAW_x 29 -#define RDEBUG_x 30 -#define REAL_x 31 -#define RSTEP_x 32 -#define R_BaseEnv_x 33 -#define R_BaseNamespace_x 34 -#define R_BindingIsLocked_x 35 -#define R_CHAR_x 36 -#define R_CleanUp_x 37 -#define R_ExternalPtrAddr_x 38 -#define R_ExternalPtrProtected_x 39 -#define R_ExternalPtrTag_x 40 -#define R_FindNamespace_x 41 -#define R_GetConnection_x 42 -#define R_GlobalContext_x 43 -#define R_GlobalEnv_x 44 -#define R_Home_x 45 -#define R_HomeDir_x 46 -#define R_Interactive_x 47 -#define R_LockBinding_x 48 -#define R_MakeExternalPtr_x 49 -#define R_MethodsNamespace_x 50 -#define R_NamespaceRegistry_x 51 -#define R_NewHashedEnv_x 52 -#define R_ParseVector_x 53 -#define R_PreserveObject_x 54 -#define R_PromiseExpr_x 55 -#define R_ProtectWithIndex_x 56 -#define R_ReadConnection_x 57 -#define R_ReleaseObject_x 58 -#define R_Reprotect_x 59 -#define R_SetExternalPtrAddr_x 60 -#define R_SetExternalPtrProtected_x 61 -#define R_SetExternalPtrTag_x 62 -#define R_TempDir_x 63 -#define R_ToplevelExec_x 64 -#define R_WriteConnection_x 65 -#define R_alloc_x 66 -#define R_compute_identical_x 67 -#define R_do_MAKE_CLASS_x 68 -#define R_do_new_object_x 69 -#define R_do_slot_x 70 -#define R_do_slot_assign_x 71 -#define R_getClassDef_x 72 -#define R_getContextCall_x 73 -#define R_getContextEnv_x 74 -#define R_getContextFun_x 75 -#define R_getContextSrcRef_x 76 -#define R_getGlobalFunctionContext_x 77 -#define R_getParentFunctionContext_x 78 -#define R_has_slot_x 79 -#define R_insideBrowser_x 80 -#define R_isEqual_x 81 -#define R_isGlobal_x 82 -#define R_lsInternal3_x 83 -#define R_new_custom_connection_x 84 -#define R_tryEval_x 85 -#define R_unLockBinding_x 86 -#define Rf_GetOption1_x 87 -#define Rf_NonNullStringMatch_x 88 -#define Rf_PairToVectorList_x 89 -#define Rf_ScalarDouble_x 90 -#define Rf_ScalarInteger_x 91 -#define Rf_ScalarLogical_x 92 -#define Rf_ScalarString_x 93 -#define Rf_VectorToPairList_x 94 -#define Rf_allocArray_x 95 -#define Rf_allocMatrix_x 96 -#define Rf_allocVector_x 97 -#define Rf_any_duplicated_x 98 -#define Rf_asChar_x 99 -#define Rf_asCharacterFactor_x 100 -#define Rf_asInteger_x 101 -#define Rf_asLogical_x 102 -#define Rf_asReal_x 103 -#define Rf_classgets_x 104 -#define Rf_coerceVector_x 105 -#define Rf_cons_x 106 -#define Rf_copyListMatrix_x 107 -#define Rf_copyMatrix_x 108 -#define Rf_copyMostAttrib_x 109 -#define Rf_defineVar_x 110 -#define Rf_dunif_x 111 -#define Rf_duplicate_x 112 -#define Rf_error_x 113 -#define Rf_errorcall_x 114 -#define Rf_eval_x 115 -#define Rf_findFun_x 116 -#define Rf_findVar_x 117 -#define Rf_findVarInFrame_x 118 -#define Rf_findVarInFrame3_x 119 -#define Rf_getAttrib_x 120 -#define Rf_gsetVar_x 121 -#define Rf_inherits_x 122 -#define Rf_install_x 123 -#define Rf_installChar_x 124 -#define Rf_isNull_x 125 -#define Rf_isString_x 126 -#define Rf_lengthgets_x 127 -#define Rf_match_x 128 -#define Rf_mkCharLenCE_x 129 -#define Rf_namesgets_x 130 -#define Rf_ncols_x 131 -#define Rf_nrows_x 132 -#define Rf_protect_x 133 -#define Rf_punif_x 134 -#define Rf_qunif_x 135 -#define Rf_runif_x 136 -#define Rf_setAttrib_x 137 -#define Rf_str2type_x 138 -#define Rf_unprotect_x 139 -#define Rf_unprotect_ptr_x 140 -#define Rf_warning_x 141 -#define Rf_warningcall_x 142 -#define Rprintf_x 143 -#define SETCADR_x 144 -#define SETCAR_x 145 -#define SETCDR_x 146 -#define SET_NAMED_FASTR_x 147 -#define SET_RDEBUG_x 148 -#define SET_RSTEP_x 149 -#define SET_S4_OBJECT_x 150 -#define SET_STRING_ELT_x 151 -#define SET_SYMVALUE_x 152 -#define SET_TAG_x 153 -#define SET_TYPEOF_FASTR_x 154 -#define SET_VECTOR_ELT_x 155 -#define STRING_ELT_x 156 -#define SYMVALUE_x 157 -#define TAG_x 158 -#define TYPEOF_x 159 -#define UNSET_S4_OBJECT_x 160 -#define VECTOR_ELT_x 161 -#define forceSymbols_x 162 -#define getCCallable_x 163 -#define getConnectionClassString_x 164 -#define getOpenModeString_x 165 -#define getSummaryDescription_x 166 -#define isSeekable_x 167 -#define octsize_x 168 -#define registerCCallable_x 169 -#define registerRoutines_x 170 -#define restoreHandlerStacks_x 171 -#define setDotSymbolValues_x 172 -#define unif_rand_x 173 -#define useDynamicSymbols_x 174 +#define BODY_x 1 +#define CAAR_x 2 +#define CAD4R_x 3 +#define CADDDR_x 4 +#define CADDR_x 5 +#define CADR_x 6 +#define CAR_x 7 +#define CDAR_x 8 +#define CDDDR_x 9 +#define CDDR_x 10 +#define CDR_x 11 +#define CLOENV_x 12 +#define COMPLEX_x 13 +#define DUPLICATE_ATTRIB_x 14 +#define ENCLOS_x 15 +#define FASTR_getConnectionChar_x 16 +#define FORMALS_x 17 +#define GetRNGstate_x 18 +#define INTEGER_x 19 +#define IS_S4_OBJECT_x 20 +#define LENGTH_x 21 +#define LOGICAL_x 22 +#define NAMED_x 23 +#define OBJECT_x 24 +#define PRCODE_x 25 +#define PRENV_x 26 +#define PRINTNAME_x 27 +#define PRSEEN_x 28 +#define PRVALUE_x 29 +#define PutRNGstate_x 30 +#define RAW_x 31 +#define RDEBUG_x 32 +#define REAL_x 33 +#define RSTEP_x 34 +#define R_BaseEnv_x 35 +#define R_BaseNamespace_x 36 +#define R_BindingIsLocked_x 37 +#define R_CHAR_x 38 +#define R_CleanUp_x 39 +#define R_ExternalPtrAddr_x 40 +#define R_ExternalPtrProtected_x 41 +#define R_ExternalPtrTag_x 42 +#define R_FindNamespace_x 43 +#define R_GetConnection_x 44 +#define R_GlobalContext_x 45 +#define R_GlobalEnv_x 46 +#define R_Home_x 47 +#define R_HomeDir_x 48 +#define R_Interactive_x 49 +#define R_LockBinding_x 50 +#define R_MakeExternalPtr_x 51 +#define R_MethodsNamespace_x 52 +#define R_NamespaceRegistry_x 53 +#define R_NewHashedEnv_x 54 +#define R_ParseVector_x 55 +#define R_PreserveObject_x 56 +#define R_PromiseExpr_x 57 +#define R_ProtectWithIndex_x 58 +#define R_ReadConnection_x 59 +#define R_ReleaseObject_x 60 +#define R_Reprotect_x 61 +#define R_SetExternalPtrAddr_x 62 +#define R_SetExternalPtrProtected_x 63 +#define R_SetExternalPtrTag_x 64 +#define R_TempDir_x 65 +#define R_ToplevelExec_x 66 +#define R_WriteConnection_x 67 +#define R_alloc_x 68 +#define R_compute_identical_x 69 +#define R_do_MAKE_CLASS_x 70 +#define R_do_new_object_x 71 +#define R_do_slot_x 72 +#define R_do_slot_assign_x 73 +#define R_getClassDef_x 74 +#define R_getContextCall_x 75 +#define R_getContextEnv_x 76 +#define R_getContextFun_x 77 +#define R_getContextSrcRef_x 78 +#define R_getGlobalFunctionContext_x 79 +#define R_getParentFunctionContext_x 80 +#define R_has_slot_x 81 +#define R_insideBrowser_x 82 +#define R_isEqual_x 83 +#define R_isGlobal_x 84 +#define R_lsInternal3_x 85 +#define R_new_custom_connection_x 86 +#define R_tryEval_x 87 +#define R_unLockBinding_x 88 +#define Rf_GetOption1_x 89 +#define Rf_NonNullStringMatch_x 90 +#define Rf_PairToVectorList_x 91 +#define Rf_ScalarDouble_x 92 +#define Rf_ScalarInteger_x 93 +#define Rf_ScalarLogical_x 94 +#define Rf_ScalarString_x 95 +#define Rf_VectorToPairList_x 96 +#define Rf_allocArray_x 97 +#define Rf_allocMatrix_x 98 +#define Rf_allocVector_x 99 +#define Rf_any_duplicated_x 100 +#define Rf_asChar_x 101 +#define Rf_asCharacterFactor_x 102 +#define Rf_asInteger_x 103 +#define Rf_asLogical_x 104 +#define Rf_asReal_x 105 +#define Rf_classgets_x 106 +#define Rf_coerceVector_x 107 +#define Rf_cons_x 108 +#define Rf_copyListMatrix_x 109 +#define Rf_copyMatrix_x 110 +#define Rf_copyMostAttrib_x 111 +#define Rf_defineVar_x 112 +#define Rf_dunif_x 113 +#define Rf_duplicate_x 114 +#define Rf_error_x 115 +#define Rf_errorcall_x 116 +#define Rf_eval_x 117 +#define Rf_findFun_x 118 +#define Rf_findVar_x 119 +#define Rf_findVarInFrame_x 120 +#define Rf_findVarInFrame3_x 121 +#define Rf_getAttrib_x 122 +#define Rf_gsetVar_x 123 +#define Rf_inherits_x 124 +#define Rf_install_x 125 +#define Rf_installChar_x 126 +#define Rf_isNull_x 127 +#define Rf_isString_x 128 +#define Rf_lengthgets_x 129 +#define Rf_match_x 130 +#define Rf_mkCharLenCE_x 131 +#define Rf_namesgets_x 132 +#define Rf_ncols_x 133 +#define Rf_nrows_x 134 +#define Rf_protect_x 135 +#define Rf_punif_x 136 +#define Rf_qunif_x 137 +#define Rf_runif_x 138 +#define Rf_setAttrib_x 139 +#define Rf_str2type_x 140 +#define Rf_unprotect_x 141 +#define Rf_unprotect_ptr_x 142 +#define Rf_warning_x 143 +#define Rf_warningcall_x 144 +#define Rprintf_x 145 +#define SETCADR_x 146 +#define SETCAR_x 147 +#define SETCDR_x 148 +#define SET_BODY_x 149 +#define SET_CLOENV_x 150 +#define SET_FORMALS_x 151 +#define SET_NAMED_FASTR_x 152 +#define SET_RDEBUG_x 153 +#define SET_RSTEP_x 154 +#define SET_S4_OBJECT_x 155 +#define SET_STRING_ELT_x 156 +#define SET_SYMVALUE_x 157 +#define SET_TAG_x 158 +#define SET_TYPEOF_FASTR_x 159 +#define SET_VECTOR_ELT_x 160 +#define STRING_ELT_x 161 +#define SYMVALUE_x 162 +#define TAG_x 163 +#define TYPEOF_x 164 +#define UNSET_S4_OBJECT_x 165 +#define VECTOR_ELT_x 166 +#define forceSymbols_x 167 +#define getCCallable_x 168 +#define getConnectionClassString_x 169 +#define getOpenModeString_x 170 +#define getSummaryDescription_x 171 +#define isSeekable_x 172 +#define octsize_x 173 +#define registerCCallable_x 174 +#define registerRoutines_x 175 +#define restoreHandlerStacks_x 176 +#define setDotSymbolValues_x 177 +#define unif_rand_x 178 +#define useDynamicSymbols_x 179 -#define UPCALLS_TABLE_SIZE 175 +#define UPCALLS_TABLE_SIZE 180 #endif // RFFI_UPCALLSINDEX_H diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h index 8d35f0b38cef269d07cb41e1c2be1b172c0c87e8..7cd01653107b217d3acc4cef2fdd5d7d27685406 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h +++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h @@ -788,17 +788,23 @@ SEXP SETCAD4R(SEXP e, SEXP y) { SEXP FORMALS(SEXP x) { TRACE0(); - return unimplemented("FORMALS"); + SEXP result = ((call_FORMALS) callbacks[FORMALS_x])(x); + checkExitCall(); + return result; } SEXP BODY(SEXP x) { TRACE0(); - return unimplemented("BODY"); + SEXP result = ((call_BODY) callbacks[BODY_x])(x); + checkExitCall(); + return result; } SEXP CLOENV(SEXP x) { TRACE(TARGp, x); - return ((call_CLOENV) callbacks[CLOENV_x])(x); + SEXP result = ((call_CLOENV) callbacks[CLOENV_x])(x); + checkExitCall(); + return result; } int RDEBUG(SEXP x) { @@ -840,17 +846,20 @@ void SET_RTRACE(SEXP x, int v) { void SET_FORMALS(SEXP x, SEXP v) { TRACE0(); - unimplemented("SET_FORMALS"); + ((call_SET_FORMALS) callbacks[SET_FORMALS_x])(x, v); + checkExitCall(); } void SET_BODY(SEXP x, SEXP v) { TRACE0(); - unimplemented("SET_BODY"); + ((call_SET_FORMALS) callbacks[SET_BODY_x])(x, v); + checkExitCall(); } void SET_CLOENV(SEXP x, SEXP v) { TRACE0(); - unimplemented("SET_CLOENV"); + ((call_SET_FORMALS) callbacks[SET_CLOENV_x])(x, v); + checkExitCall(); } SEXP SYMVALUE(SEXP x) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Formals.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Formals.java index 1e8e3815dcdb4a3e2fd1592fbbbc3b14bd0b8ca2..4c3532d781a50835124fd0a73fd05f89496bca6c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Formals.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Formals.java @@ -25,22 +25,18 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; -import com.oracle.truffle.r.nodes.function.FormalArguments; -import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RSymbol; -import com.oracle.truffle.r.runtime.nodes.RNode; +@ImportStatic(RASTUtils.class) @RBuiltin(name = "formals", kind = INTERNAL, parameterNames = {"fun"}, behavior = PURE) public abstract class Formals extends RBuiltinNode.Arg1 { @@ -59,7 +55,7 @@ public abstract class Formals extends RBuiltinNode.Arg1 { @Specialization(replaces = "formalsCached") protected Object formals(RFunction fun) { - return createFormals(fun); + return RASTUtils.createFormals(fun); } @Fallback @@ -67,21 +63,4 @@ public abstract class Formals extends RBuiltinNode.Arg1 { // for anything that is not a function, GnuR returns NULL return RNull.instance; } - - @TruffleBoundary - protected Object createFormals(RFunction fun) { - if (fun.isBuiltin()) { - return RNull.instance; - } - FunctionDefinitionNode fdNode = (FunctionDefinitionNode) fun.getTarget().getRootNode(); - FormalArguments formalArgs = fdNode.getFormalArguments(); - Object succ = RNull.instance; - for (int i = formalArgs.getSignature().getLength() - 1; i >= 0; i--) { - RNode argument = formalArgs.getDefaultArgument(i); - Object lang = argument == null ? RSymbol.MISSING : RASTUtils.createLanguageElement(argument.asRSyntaxNode()); - RSymbol name = RDataFactory.createSymbol(formalArgs.getSignature().getName(i)); - succ = RDataFactory.createPairList(lang, succ, name); - } - return succ; - } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java index f8c5cfe98d48a033d057efc83cdc2865c5c7625d..2bcce2dec7ca19d411b7a437b850ed87eb9427a3 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java @@ -23,31 +23,46 @@ package com.oracle.truffle.r.nodes; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode; +import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeUtil; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.nodes.access.AccessArgumentNode; import com.oracle.truffle.r.nodes.access.ConstantNode; import com.oracle.truffle.r.nodes.access.ReadVariadicComponentNode; +import com.oracle.truffle.r.nodes.access.WriteVariableNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.function.FormalArguments; +import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode; import com.oracle.truffle.r.nodes.function.PromiseNode.VarArgNode; import com.oracle.truffle.r.nodes.function.RCallNode; import com.oracle.truffle.r.nodes.function.RCallSpecialNode; +import com.oracle.truffle.r.nodes.function.SaveArgumentsNode; import com.oracle.truffle.r.nodes.function.WrapArgumentBaseNode; import com.oracle.truffle.r.nodes.function.WrapArgumentNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.Closure; +import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.REmpty; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RMissing; +import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.data.RSymbol; +import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.nodes.RInstrumentableNode; import com.oracle.truffle.r.runtime.nodes.RNode; @@ -172,22 +187,12 @@ public final class RASTUtils { public static RBaseNode createNodeForValue(Object value) { if (value instanceof RNode) { return (RNode) value; - } else if (value instanceof RSymbol) { - RSymbol symbol = (RSymbol) value; - if (symbol.isMissing()) { - return RContext.getASTBuilder().constant(RSyntaxNode.SOURCE_UNAVAILABLE, REmpty.instance).asRNode(); - } else { - return RContext.getASTBuilder().lookup(RSyntaxNode.SOURCE_UNAVAILABLE, ((RSymbol) value).getName(), false).asRNode(); - } - } else if (value instanceof RLanguage) { - RLanguage l = (RLanguage) value; - return RASTUtils.cloneNode(l.getRep()); } else if (value instanceof RPromise) { RPromise promise = (RPromise) value; RNode promiseRep = (RNode) unwrap(((RPromise) value).getRep()); if (promiseRep instanceof VarArgNode) { VarArgNode varArgNode = (VarArgNode) promiseRep; - RPromise varArgPromise = (RPromise) varArgNode.execute((VirtualFrame) promise.getFrame()); + RPromise varArgPromise = (RPromise) varArgNode.execute(promise.getFrame()); Node unwrappedRep = unwrap(varArgPromise.getRep()); if (unwrappedRep instanceof ConstantNode) { return (ConstantNode) unwrappedRep; @@ -201,6 +206,40 @@ public final class RASTUtils { } return RASTUtils.cloneNode(promiseRep); } else { + return createNodeForRValue(value); + } + } + + @TruffleBoundary + public static RBaseNode createNodeForRValue(Object value) { + if (value instanceof RSymbol) { + RSymbol symbol = (RSymbol) value; + if (symbol.isMissing()) { + return RContext.getASTBuilder().constant(RSyntaxNode.SOURCE_UNAVAILABLE, REmpty.instance).asRNode(); + } else { + return RContext.getASTBuilder().lookup(RSyntaxNode.SOURCE_UNAVAILABLE, symbol.getName(), false).asRNode(); + } + } else if (value instanceof RLanguage) { + return RASTUtils.cloneNode(((RLanguage) value).getRep()); + } else { + assert value instanceof String || value instanceof Integer || value instanceof Double || value instanceof Byte || value instanceof TruffleObject; + return ConstantNode.create(value); + } + } + + @TruffleBoundary + public static RSyntaxNode createSyntaxNodeForRValue(Object value) { + if (value instanceof RSymbol) { + RSymbol symbol = (RSymbol) value; + if (symbol.isMissing()) { + return RContext.getASTBuilder().constant(RSyntaxNode.SOURCE_UNAVAILABLE, REmpty.instance); + } else { + return RContext.getASTBuilder().lookup(RSyntaxNode.SOURCE_UNAVAILABLE, symbol.getName(), false); + } + } else if (value instanceof RLanguage) { + return RContext.getASTBuilder().process(((RLanguage) value).getSyntaxElement()); + } else { + assert value instanceof String || value instanceof Integer || value instanceof Double || value instanceof Byte || value instanceof TruffleObject; return ConstantNode.create(value); } } @@ -223,4 +262,91 @@ public final class RASTUtils { SourceSection sourceSection = sourceUnavailable ? RSyntaxNode.SOURCE_UNAVAILABLE : RSyntaxNode.LAZY_DEPARSE; return RCallSpecialNode.createCall(sourceSection, fnNode, signature, arguments); } + + @TruffleBoundary + public static Object createFormals(RFunction fun) { + if (fun.isBuiltin()) { + return RNull.instance; + } + FunctionDefinitionNode fdNode = (FunctionDefinitionNode) fun.getTarget().getRootNode(); + FormalArguments formalArgs = fdNode.getFormalArguments(); + Object succ = RNull.instance; + for (int i = formalArgs.getSignature().getLength() - 1; i >= 0; i--) { + RNode argument = formalArgs.getDefaultArgument(i); + Object lang = argument == null ? RSymbol.MISSING : RASTUtils.createLanguageElement(argument.asRSyntaxNode()); + RSymbol name = RDataFactory.createSymbol(formalArgs.getSignature().getName(i)); + succ = RDataFactory.createPairList(lang, succ, name); + } + return succ; + } + + @TruffleBoundary + public static void modifyFunction(RFunction fun, Object newBody, Object newFormals, MaterializedFrame newEnv) { + RootCallTarget target = fun.getTarget(); + FunctionDefinitionNode root = (FunctionDefinitionNode) target.getRootNode(); + + SaveArgumentsNode saveArguments; + FormalArguments formals; + int formalsLength = newFormals == RNull.instance ? 0 : ((RPairList) newFormals).getLength(); + String[] argumentNames = new String[formalsLength]; + RNode[] defaultValues = new RNode[formalsLength]; + AccessArgumentNode[] argAccessNodes = new AccessArgumentNode[formalsLength]; + RNode[] init = new RNode[formalsLength]; + + Object current = newFormals; + int i = 0; + while (current != RNull.instance) { + + final RSyntaxNode defaultValue; + Object arg = ((RPairList) current).car(); + if (arg == RMissing.instance) { + defaultValue = null; + } else if (arg == RNull.instance) { + defaultValue = RContext.getASTBuilder().constant(RSyntaxNode.LAZY_DEPARSE, RNull.instance); + } else if (arg instanceof RLanguage) { + defaultValue = RASTUtils.createSyntaxNodeForRValue(arg); + } else if (arg instanceof RSymbol) { + RSymbol symbol = (RSymbol) arg; + if (symbol.isMissing()) { + defaultValue = null; + } else { + defaultValue = RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, symbol.getName(), false); + } + } else if (RRuntime.convertScalarVectors(arg) instanceof RAttributable) { + defaultValue = RContext.getASTBuilder().constant(RSyntaxNode.LAZY_DEPARSE, arg); + } else { + throw RInternalError.unimplemented(); + } + AccessArgumentNode accessArg = AccessArgumentNode.create(i); + argAccessNodes[i] = accessArg; + Object tag = ((RPairList) current).getTag(); + String argName = ((RSymbol) tag).getName(); + init[i] = WriteVariableNode.createArgSave(argName, accessArg); + + // Store formal arguments + argumentNames[i] = argName; + defaultValues[i] = defaultValue.asRNode(); + current = ((RPairList) current).cdr(); + i++; + } + saveArguments = new SaveArgumentsNode(init); + formals = FormalArguments.createForFunction(defaultValues, ArgumentsSignature.get(argumentNames)); + for (AccessArgumentNode access : argAccessNodes) { + access.setFormals(formals); + } + + RSyntaxNode bodyNode = root.getBody(); + if (newBody != null) { + bodyNode = RASTUtils.createSyntaxNodeForRValue(newBody); + } + + FrameDescriptor descriptor = new FrameDescriptor(); + FrameSlotChangeMonitor.initializeFunctionFrameDescriptor("<SET_BODY/SET_FORMALS/SET_CLOENV>", descriptor); + FrameSlotChangeMonitor.initializeEnclosingFrame(descriptor, newEnv); + FunctionDefinitionNode rootNode = FunctionDefinitionNode.create(RContext.getInstance().getLanguage(), RSyntaxNode.LAZY_DEPARSE, descriptor, null, saveArguments, bodyNode, formals, + root.getName(), null); + RootCallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode); + fun.reassignTarget(callTarget); + fun.reassignEnclosingFrame(newEnv); + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/Closure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/Closure.java index 1dcc176048aff9be24149bf012a54eb4042ac814..158df899f7ac1edde853e90625af4225df428486 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/Closure.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/Closure.java @@ -37,6 +37,7 @@ import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; +import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; /** @@ -140,6 +141,10 @@ public final class Closure { return expr; } + public RSyntaxElement getSyntaxElement() { + return expr.asRSyntaxNode(); + } + public String asSymbol() { return symbol; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFunction.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFunction.java index 7f7bd897580a991874dfb294c3693ce0e0abf08c..50f46625f07ff3912bd450dde89a7bd91b9d3566 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFunction.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFunction.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime.data; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.nodes.RootNode; @@ -49,10 +50,10 @@ public final class RFunction extends RSharingAttributeStorage implements RTypedV private final String name; private final String packageName; - private final RootCallTarget target; + @CompilationFinal private RootCallTarget target; private final RBuiltinDescriptor builtin; - private final MaterializedFrame enclosingFrame; + @CompilationFinal private MaterializedFrame enclosingFrame; RFunction(String name, String packageName, RootCallTarget target, RBuiltinDescriptor builtin, MaterializedFrame enclosingFrame) { this.packageName = packageName; @@ -116,4 +117,12 @@ public final class RFunction extends RSharingAttributeStorage implements RTypedV newFunction.setTypedValueInfo(getTypedValueInfo()); return newFunction; } + + public void reassignTarget(RootCallTarget newTarget) { + this.target = newTarget; + } + + public void reassignEnclosingFrame(MaterializedFrame newEnclosingFrame) { + this.enclosingFrame = newEnclosingFrame; + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java index 43c77e0ca59aaf0dfc848b1af457ee091a24d531..ce3b22f6a8dfc17c1387524ccf5d6d2c70a9eeaa 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java @@ -34,6 +34,7 @@ import com.oracle.truffle.r.runtime.data.nodes.FastPathVectorAccess.FastPathFrom import com.oracle.truffle.r.runtime.data.nodes.SlowPathVectorAccess.SlowPathFromListAccess; import com.oracle.truffle.r.runtime.data.nodes.VectorAccess; import com.oracle.truffle.r.runtime.nodes.RBaseNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; /** * Denotes an (unevaluated) R language element. It is equivalent to a LANGSXP value in GnuR. It @@ -325,4 +326,9 @@ public final class RLanguage extends RSharingAttributeStorage implements RAbstra public VectorAccess slowPathAccess() { return SLOW_PATH_ACCESS; } + + public RSyntaxElement getSyntaxElement() { + regenerateFromList(); + return closure.getSyntaxElement(); + } }