5454import com .oracle .graal .python .builtins .Builtin ;
5555import com .oracle .graal .python .builtins .CoreFunctions ;
5656import com .oracle .graal .python .builtins .PythonBuiltins ;
57- import com .oracle .graal .python .builtins .modules .TruffleCextBuiltinsFactory .AsPythonObjectNodeFactory ;
5857import com .oracle .graal .python .builtins .modules .TruffleCextBuiltinsFactory .PNativeToPTypeNodeGen ;
59- import com .oracle .graal .python .builtins .modules .TruffleCextBuiltinsFactory .ToSulongNodeFactory ;
6058import com .oracle .graal .python .builtins .objects .PNone ;
6159import com .oracle .graal .python .builtins .objects .PythonAbstractObject ;
6260import com .oracle .graal .python .builtins .objects .bytes .BytesBuiltins ;
8280import com .oracle .graal .python .nodes .call .special .LookupAndCallUnaryNode ;
8381import com .oracle .graal .python .nodes .expression .BinaryComparisonNode ;
8482import com .oracle .graal .python .nodes .function .PythonBuiltinNode ;
83+ import com .oracle .graal .python .nodes .function .builtins .PythonTernaryBuiltinNode ;
8584import com .oracle .graal .python .nodes .function .builtins .PythonUnaryBuiltinNode ;
8685import com .oracle .graal .python .nodes .interop .PForeignToPTypeNode ;
8786import com .oracle .graal .python .nodes .object .GetClassNode ;
@@ -347,23 +346,35 @@ int doLOvf(PTuple tuple, long position, Object element) {
347346 }
348347 }
349348
350- @ Builtin (name = "CreateFunction" , fixedNumOfArguments = 2 )
349+ @ Builtin (name = "CreateFunction" , minNumOfArguments = 2 , maxNumOfArguments = 3 )
351350 @ GenerateNodeFactory
352- abstract static class AddFunctionNode extends PythonBuiltinNode {
353- @ Specialization
351+ abstract static class CreateFunctionNode extends PythonTernaryBuiltinNode {
352+ @ Specialization (guards = "isNoValue(cwrapper)" )
353+ @ TruffleBoundary
354+ Object runWithoutCWrapper (String name , TruffleObject callable , @ SuppressWarnings ("unused" ) PNone cwrapper ) {
355+ RootCallTarget callTarget = Truffle .getRuntime ().createCallTarget (new ExternalFunctionNode (getRootNode ().getLanguage (PythonLanguage .class ), name , null , callable ));
356+ return factory ().createBuiltinFunction (name , createArity (name ), callTarget );
357+ }
358+
359+ @ Specialization (guards = "!isNoValue(cwrapper)" )
354360 @ TruffleBoundary
355- Object run (String name , TruffleObject callable ) {
356- RootCallTarget callTarget = Truffle .getRuntime ().createCallTarget (new ExternalFunctionNode (getRootNode ().getLanguage (PythonLanguage .class ), name , callable ));
361+ Object run (String name , TruffleObject callable , TruffleObject cwrapper ) {
362+ RootCallTarget callTarget = Truffle .getRuntime ().createCallTarget (new ExternalFunctionNode (getRootNode ().getLanguage (PythonLanguage .class ), name , cwrapper , callable ));
357363 return factory ().createBuiltinFunction (name , createArity (name ), callTarget );
358364 }
359365
360366 private static Arity createArity (String name ) {
361367 return new Arity (name , 0 , 0 , true , true , new ArrayList <>(), new ArrayList <>());
362368 }
363369
364- @ Specialization
365- Object run (PString name , TruffleObject callable ) {
366- return run (name .getValue (), callable );
370+ @ Specialization (guards = "!isNoValue(cwrapper)" )
371+ Object runWithoutCWrapper (PString name , TruffleObject callable , PNone cwrapper ) {
372+ return runWithoutCWrapper (name .getValue (), callable , cwrapper );
373+ }
374+
375+ @ Specialization (guards = "!isNoValue(cwrapper)" )
376+ Object run (PString name , TruffleObject callable , TruffleObject cwrapper ) {
377+ return run (name .getValue (), callable , cwrapper );
367378 }
368379 }
369380
@@ -512,22 +523,28 @@ PythonClass run(TruffleObject typestruct, PythonClass metaClass, PTuple baseClas
512523 }
513524
514525 static class ExternalFunctionNode extends RootNode {
526+ private final TruffleObject cwrapper ;
515527 private final TruffleObject callable ;
516528 private final String name ;
517529 @ CompilationFinal PythonContext ctxt ;
518- @ Child private Node executeNode = Message . createExecute ( 0 ). createNode () ;
519- @ Child ToSulongNode toSulongNode = ToSulongNodeFactory . create (null );
520- @ Child AsPythonObjectNode asPythonObjectNode = AsPythonObjectNodeFactory . create (null );
530+ @ Child private Node executeNode ;
531+ @ Child CExtNodes . ToSulongNode toSulongNode = CExtNodes . ToSulongNode . create ();
532+ @ Child CExtNodes . AsPythonObjectNode asPythonObjectNode = CExtNodes . AsPythonObjectNode . create ();
521533 @ Child private Node isNullNode = Message .IS_NULL .createNode ();
522534 @ Child private PNativeToPTypeNode fromForeign = PNativeToPTypeNode .create ();
523535
524536 @ Child private PythonObjectFactory factory = PythonObjectFactory .create ();
525537
526- public ExternalFunctionNode (PythonLanguage lang , String name , TruffleObject callable ) {
538+ public ExternalFunctionNode (PythonLanguage lang , String name , TruffleObject cwrapper , TruffleObject callable ) {
527539 super (lang );
528540 this .name = name ;
541+ this .cwrapper = cwrapper ;
529542 this .callable = callable ;
530- this .executeNode = Message .createExecute (2 ).createNode ();
543+ if (cwrapper != null ) {
544+ this .executeNode = Message .createExecute (3 ).createNode ();
545+ } else {
546+ this .executeNode = Message .createExecute (2 ).createNode ();
547+ }
531548 }
532549
533550 public TruffleObject getCallable () {
@@ -537,12 +554,25 @@ public TruffleObject getCallable() {
537554 @ Override
538555 public Object execute (VirtualFrame frame ) {
539556 Object [] frameArgs = frame .getArguments ();
540- Object [] arguments = new Object [frameArgs .length - PArguments .USER_ARGUMENTS_OFFSET ];
541- for (int i = 0 ; i < arguments .length ; i ++) {
542- arguments [i ] = toSulongNode .execute (frameArgs [i + PArguments .USER_ARGUMENTS_OFFSET ]);
543- }
544557 try {
545- return fromNative (asPythonObjectNode .execute (checkFunctionResult (ForeignAccess .sendExecute (executeNode , callable , arguments ))));
558+ TruffleObject fun ;
559+ Object [] arguments ;
560+
561+ if (cwrapper != null ) {
562+ fun = cwrapper ;
563+ arguments = new Object [1 + frameArgs .length - PArguments .USER_ARGUMENTS_OFFSET ];
564+ arguments [0 ] = callable ;
565+ for (int i = 1 ; i < arguments .length ; i ++) {
566+ arguments [i ] = toSulongNode .execute (frameArgs [i + PArguments .USER_ARGUMENTS_OFFSET - 1 ]);
567+ }
568+ } else {
569+ fun = callable ;
570+ arguments = new Object [frameArgs .length - PArguments .USER_ARGUMENTS_OFFSET ];
571+ for (int i = 0 ; i < arguments .length ; i ++) {
572+ arguments [i ] = toSulongNode .execute (frameArgs [i + PArguments .USER_ARGUMENTS_OFFSET ]);
573+ }
574+ }
575+ return fromNative (asPythonObjectNode .execute (checkFunctionResult (ForeignAccess .sendExecute (executeNode , fun , arguments ))));
546576 } catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e ) {
547577 CompilerDirectives .transferToInterpreter ();
548578 throw new RuntimeException (e .toString ());
0 commit comments