7878import com .oracle .graal .python .nodes .util .CastToIndexNode ;
7979import com .oracle .graal .python .runtime .PythonCore ;
8080import com .oracle .graal .python .runtime .exception .PythonErrorType ;
81- import com .oracle .truffle .api .CompilerAsserts ;
8281import com .oracle .truffle .api .CompilerDirectives ;
8382import com .oracle .truffle .api .CompilerDirectives .CompilationFinal ;
8483import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
9291import com .oracle .truffle .api .interop .InteropException ;
9392import com .oracle .truffle .api .interop .Message ;
9493import com .oracle .truffle .api .interop .TruffleObject ;
94+ import com .oracle .truffle .api .interop .UnknownIdentifierException ;
9595import com .oracle .truffle .api .interop .UnsupportedMessageException ;
9696import com .oracle .truffle .api .interop .UnsupportedTypeException ;
9797import com .oracle .truffle .api .nodes .ExplodeLoop ;
9898import com .oracle .truffle .api .nodes .Node ;
99+ import com .oracle .truffle .api .profiles .BranchProfile ;
99100
100101public abstract class CExtNodes {
101102
@@ -105,30 +106,40 @@ public abstract class CExtNodes {
105106 * will call that subtype C function with two arguments, the C type object and an object
106107 * argument to fill in from.
107108 */
108- public static class SubtypeNew extends PBaseNode {
109- private final TruffleObject subtypeFunc ;
109+ public static class SubtypeNew extends CExtBaseNode {
110110 @ Child private Node executeNode = Message .EXECUTE .createNode ();
111111 @ Child private ToSulongNode toSulongNode = ToSulongNode .create ();
112112 @ Child private ToJavaNode toJavaNode = ToJavaNode .create ();
113113
114+ private final String functionName ;
115+
116+ @ CompilationFinal private TruffleObject subtypeFunc ;
117+
114118 /**
115119 * @param typenamePrefix the <code>typename</code> in <code>typename_subtype_new</code>
116120 */
117121 public SubtypeNew (String typenamePrefix ) {
118- subtypeFunc = (TruffleObject ) getContext ().getEnv ().importSymbol (typenamePrefix + "_subtype_new" );
119- assert subtypeFunc != null ;
122+ functionName = typenamePrefix + "_subtype_new" ;
120123 }
121124
122125 public Object execute (PythonNativeClass object , Object arg ) {
123126 try {
124- return toJavaNode .execute (ForeignAccess .sendExecute (executeNode , subtypeFunc , toSulongNode .execute (object ), arg ));
127+ return toJavaNode .execute (ForeignAccess .sendExecute (executeNode , getFunction () , toSulongNode .execute (object ), arg ));
125128 } catch (UnsupportedMessageException | UnsupportedTypeException | ArityException e ) {
126129 throw new IllegalStateException ("C subtype_new function failed" , e );
127130 }
128131 }
132+
133+ private TruffleObject getFunction () {
134+ if (subtypeFunc == null ) {
135+ CompilerDirectives .transferToInterpreterAndInvalidate ();
136+ subtypeFunc = importCAPISymbol (functionName );
137+ }
138+ return subtypeFunc ;
139+ }
129140 }
130141
131- public static class FromNativeSubclassNode <T > extends PBaseNode {
142+ public static class FromNativeSubclassNode <T > extends CExtBaseNode {
132143 private final PythonBuiltinClassType expectedType ;
133144 private final String conversionFuncName ;
134145 @ CompilationFinal private TruffleObject conversionFunc ;
@@ -157,7 +168,7 @@ private Node getExecNode() {
157168 private TruffleObject getConversionFunc () {
158169 if (conversionFunc == null ) {
159170 CompilerDirectives .transferToInterpreterAndInvalidate ();
160- conversionFunc = ( TruffleObject ) getContext (). getEnv (). importSymbol (conversionFuncName );
171+ conversionFunc = importCAPISymbol (conversionFuncName );
161172 }
162173 return conversionFunc ;
163174 }
@@ -193,11 +204,26 @@ public static <T> FromNativeSubclassNode<T> create(PythonBuiltinClassType expect
193204
194205 @ ImportStatic (PGuards .class )
195206 abstract static class CExtBaseNode extends PBaseNode {
207+ @ Child private Node readSymbolNode ;
196208
197209 protected static boolean isNativeWrapper (Object obj ) {
198210 return obj instanceof PythonNativeWrapper ;
199211 }
200212
213+ protected TruffleObject importCAPISymbol (String name ) {
214+ TruffleObject capiLibrary = (TruffleObject ) getContext ().getCapiLibrary ();
215+ if (readSymbolNode == null ) {
216+ CompilerDirectives .transferToInterpreterAndInvalidate ();
217+ readSymbolNode = insert (Message .READ .createNode ());
218+ }
219+ try {
220+ return (TruffleObject ) ForeignAccess .sendRead (readSymbolNode , capiLibrary , name );
221+ } catch (UnknownIdentifierException | UnsupportedMessageException e ) {
222+ CompilerDirectives .transferToInterpreter ();
223+ throw e .raise ();
224+ }
225+ }
226+
201227 }
202228
203229 public abstract static class ToSulongNode extends CExtBaseNode {
@@ -407,7 +433,7 @@ Object doForeign(Object value) {
407433 }
408434 if (nativeToJavaFunction == null ) {
409435 CompilerDirectives .transferToInterpreterAndInvalidate ();
410- nativeToJavaFunction = ( TruffleObject ) getContext (). getEnv (). importSymbol (NativeCAPISymbols .FUN_NATIVE_TO_JAVA );
436+ nativeToJavaFunction = importCAPISymbol (NativeCAPISymbols .FUN_NATIVE_TO_JAVA );
411437 }
412438 return toJavaNode .execute (callNativeNode .execute (nativeToJavaFunction , new Object []{value }));
413439 }
@@ -453,15 +479,15 @@ Object doByteArray(byte[] arr,
453479 TruffleObject getTruffleStringToCstr () {
454480 if (truffle_string_to_cstr == null ) {
455481 CompilerDirectives .transferToInterpreterAndInvalidate ();
456- truffle_string_to_cstr = ( TruffleObject ) getContext (). getEnv (). importSymbol (NativeCAPISymbols .FUN_PY_TRUFFLE_STRING_TO_CSTR );
482+ truffle_string_to_cstr = importCAPISymbol (NativeCAPISymbols .FUN_PY_TRUFFLE_STRING_TO_CSTR );
457483 }
458484 return truffle_string_to_cstr ;
459485 }
460486
461487 TruffleObject getTruffleByteArrayToNative () {
462488 if (truffle_byte_array_to_native == null ) {
463489 CompilerDirectives .transferToInterpreterAndInvalidate ();
464- truffle_byte_array_to_native = ( TruffleObject ) getContext (). getEnv (). importSymbol (NativeCAPISymbols .FUN_PY_TRUFFLE_BYTE_ARRAY_TO_NATIVE );
490+ truffle_byte_array_to_native = importCAPISymbol (NativeCAPISymbols .FUN_PY_TRUFFLE_BYTE_ARRAY_TO_NATIVE );
465491 }
466492 return truffle_byte_array_to_native ;
467493 }
@@ -483,7 +509,7 @@ public static class FromCharPointerNode extends CExtBaseNode {
483509 TruffleObject getTruffleStringToCstr () {
484510 if (truffle_cstr_to_string == null ) {
485511 CompilerDirectives .transferToInterpreterAndInvalidate ();
486- truffle_cstr_to_string = ( TruffleObject ) getContext (). getEnv (). importSymbol (NativeCAPISymbols .FUN_PY_TRUFFLE_CSTR_TO_STRING );
512+ truffle_cstr_to_string = importCAPISymbol (NativeCAPISymbols .FUN_PY_TRUFFLE_CSTR_TO_STRING );
487513 }
488514 return truffle_cstr_to_string ;
489515 }
@@ -541,7 +567,7 @@ private PCallNativeNode getCallGetObTypeNode() {
541567 TruffleObject getObTypeFunction () {
542568 if (func == null ) {
543569 CompilerDirectives .transferToInterpreterAndInvalidate ();
544- func = ( TruffleObject ) getContext (). getEnv (). importSymbol (NativeCAPISymbols .FUN_GET_OB_TYPE );
570+ func = importCAPISymbol (NativeCAPISymbols .FUN_GET_OB_TYPE );
545571 }
546572 return func ;
547573 }
@@ -559,7 +585,7 @@ public long execute() {
559585 if (wcharSize < 0 ) {
560586 CompilerDirectives .transferToInterpreterAndInvalidate ();
561587 try {
562- wcharSize = (long ) ForeignAccess .sendExecute (Message .EXECUTE .createNode (), getNativeFunction ( ));
588+ wcharSize = (long ) ForeignAccess .sendExecute (Message .EXECUTE .createNode (), importCAPISymbol ( NativeCAPISymbols . FUN_WHCAR_SIZE ));
563589 assert wcharSize >= 0L ;
564590 } catch (InteropException e ) {
565591 throw e .raise ();
@@ -568,11 +594,6 @@ public long execute() {
568594 return wcharSize ;
569595 }
570596
571- TruffleObject getNativeFunction () {
572- CompilerAsserts .neverPartOfCompilation ();
573- return (TruffleObject ) getContext ().getEnv ().importSymbol (NativeCAPISymbols .FUN_WHCAR_SIZE );
574- }
575-
576597 public static SizeofWCharNode create () {
577598 return new SizeofWCharNode ();
578599 }
@@ -591,10 +612,10 @@ public boolean execute(PythonNativeObject a, PythonNativeObject b) {
591612 }
592613 }
593614
594- TruffleObject getNativeFunction () {
615+ private TruffleObject getNativeFunction () {
595616 if (isFunc == null ) {
596617 CompilerDirectives .transferToInterpreterAndInvalidate ();
597- isFunc = ( TruffleObject ) getContext (). getEnv (). importSymbol (NativeCAPISymbols .FUN_PTR_COMPARE );
618+ isFunc = importCAPISymbol (NativeCAPISymbols .FUN_PTR_COMPARE );
598619 }
599620 return isFunc ;
600621 }
@@ -914,4 +935,47 @@ public static AsLong create() {
914935 }
915936 }
916937
938+ public static class PCallBinaryCapiFunction extends CExtBaseNode {
939+
940+ @ Child private Node callNode ;
941+
942+ private final String name ;
943+ private final BranchProfile profile = BranchProfile .create ();
944+
945+ @ CompilationFinal TruffleObject receiver ;
946+
947+ public PCallBinaryCapiFunction (String name ) {
948+ this .name = name ;
949+ }
950+
951+ public Object execute (Object arg0 , Object arg1 ) {
952+ try {
953+ return ForeignAccess .sendExecute (getCallNode (), getFunction (), arg0 , arg1 );
954+ } catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e ) {
955+ profile .enter ();
956+ throw e .raise ();
957+ }
958+ }
959+
960+ private Node getCallNode () {
961+ if (callNode == null ) {
962+ CompilerDirectives .transferToInterpreterAndInvalidate ();
963+ callNode = insert (Message .EXECUTE .createNode ());
964+ }
965+ return callNode ;
966+ }
967+
968+ private TruffleObject getFunction () {
969+ if (receiver == null ) {
970+ CompilerDirectives .transferToInterpreterAndInvalidate ();
971+ receiver = importCAPISymbol (name );
972+ }
973+ return receiver ;
974+ }
975+
976+ public static PCallBinaryCapiFunction create (String name ) {
977+ return new PCallBinaryCapiFunction (name );
978+ }
979+ }
980+
917981}
0 commit comments