124
124
import com .oracle .graal .python .builtins .objects .getsetdescriptor .DescriptorDeleteMarker ;
125
125
import com .oracle .graal .python .builtins .objects .ints .PInt ;
126
126
import com .oracle .graal .python .builtins .objects .method .PBuiltinMethod ;
127
+ import com .oracle .graal .python .builtins .objects .module .ModuleGetNameNode ;
127
128
import com .oracle .graal .python .builtins .objects .module .PythonModule ;
128
129
import com .oracle .graal .python .builtins .objects .object .PythonObjectLibrary ;
129
130
import com .oracle .graal .python .builtins .objects .str .NativeCharSequence ;
@@ -3555,8 +3556,28 @@ static TruffleObject doGeneric(TruffleObject ptr,
3555
3556
}
3556
3557
}
3557
3558
3559
+ abstract static class MultiPhaseExtensionModuleInitNode extends Node {
3560
+
3561
+ static final String M_NAME = "m_name" ;
3562
+ static final String M_DOC = "m_doc" ;
3563
+ static final String M_METHODS = "m_methods" ;
3564
+ static final String M_SLOTS = "m_slots" ;
3565
+ static final String M_SIZE = "m_size" ;
3566
+
3567
+ // according to definitions in 'moduleobject.h'
3568
+ static final int SLOT_PY_MOD_CREATE = 1 ;
3569
+ static final int SLOT_PY_MOD_EXEC = 2 ;
3570
+
3571
+ // member names of 'PyModuleDef_Slot'
3572
+ static final String MODULEDEF_SLOT = "slot" ;
3573
+ static final String MODULEDEF_VALUE = "value" ;
3574
+
3575
+ static final String FIELD_S_DID_NOT_RETURN_AN_ARRAY = "field '%s' did not return an array" ;
3576
+ }
3577
+
3558
3578
/**
3559
- * Creates a Python module from a module definition structure:
3579
+ * Equivalent of {@code PyModule_FromDefAndSpec2}. Creates a Python module from a module
3580
+ * definition structure:
3560
3581
*
3561
3582
* <pre>
3562
3583
* typedef struct PyModuleDef {
@@ -3573,24 +3594,14 @@ static TruffleObject doGeneric(TruffleObject ptr,
3573
3594
* </pre>
3574
3595
*/
3575
3596
@ GenerateUncached
3576
- public abstract static class CreateModuleNode extends Node {
3597
+ public abstract static class CreateModuleNode extends MultiPhaseExtensionModuleInitNode {
3577
3598
3578
- public static final String M_NAME = "m_name" ;
3579
- public static final String M_DOC = "m_doc" ;
3580
- public static final String M_METHODS = "m_methods" ;
3581
- public static final String M_SLOTS = "m_slots" ;
3582
-
3583
- // according to definitions in 'moduleobject.h'
3584
- public static final int SLOT_PY_MOD_CREATE = 1 ;
3585
- public static final int SLOT_PY_MOD_EXEC = 2 ;
3586
- public static final String M_SIZE = "m_size" ;
3587
- private static final String FIELD_S_DID_NOT_RETURN_AN_ARRAY = "field '%s' did not return an array" ;
3588
3599
private static final String CREATION_FAILD_WITHOUT_EXCEPTION = "creation of module %s failed without setting an exception" ;
3589
3600
private static final String CREATION_RAISED_EXCEPTION = "creation of module %s raised unreported exception" ;
3590
3601
public static final String NOT_A_MODULE_OBJECT_BUT_REQUESTS_MODULE_STATE = "module %s is not a module object, but requests module state" ;
3591
3602
3592
3603
@ TruffleBoundary
3593
- private static boolean checkLayout (Object moduleDef , InteropLibrary moduleDefLib ) {
3604
+ static boolean checkLayout (Object moduleDef , InteropLibrary moduleDefLib ) {
3594
3605
String [] members = new String []{"m_base" , M_NAME , M_DOC , M_SIZE , M_METHODS , M_SLOTS , "m_traverse" , "m_clear" , "m_free" };
3595
3606
for (String member : members ) {
3596
3607
if (!moduleDefLib .isMemberReadable (moduleDef , member )) {
@@ -3602,7 +3613,7 @@ private static boolean checkLayout(Object moduleDef, InteropLibrary moduleDefLib
3602
3613
3603
3614
public abstract Object execute (CApiContext capiContext , Object moduleSpec , Object moduleDef );
3604
3615
3605
- @ Specialization ( limit = "1" )
3616
+ @ Specialization
3606
3617
static Object doGeneric (CApiContext capiContext , Object moduleSpec , PythonAbstractNativeObject moduleDefWrapper ,
3607
3618
@ CachedLanguage PythonLanguage language ,
3608
3619
@ Cached PythonObjectFactory factory ,
@@ -3658,14 +3669,14 @@ static Object doGeneric(CApiContext capiContext, Object moduleSpec, PythonAbstra
3658
3669
for (long i = 0 ; i < nSlots ; i ++) {
3659
3670
Object slotDefinition = interopLib .readArrayElement (slotDefinitions , i );
3660
3671
3661
- Object slotIdObj = interopLib .readMember (slotDefinition , "slot" );
3672
+ Object slotIdObj = interopLib .readMember (slotDefinition , MODULEDEF_SLOT );
3662
3673
int slotId = interopLib .asInt (slotIdObj );
3663
3674
switch (slotId ) {
3664
3675
case SLOT_PY_MOD_CREATE :
3665
3676
if (createFunction != null ) {
3666
3677
throw raiseNode .raise (SystemError , "module %s has multiple create slots" , mName );
3667
3678
}
3668
- createFunction = interopLib .readMember (slotDefinition , "value" );
3679
+ createFunction = interopLib .readMember (slotDefinition , MODULEDEF_VALUE );
3669
3680
break ;
3670
3681
case SLOT_PY_MOD_EXEC :
3671
3682
hasExecutionSlots = true ;
@@ -3709,7 +3720,9 @@ static Object doGeneric(CApiContext capiContext, Object moduleSpec, PythonAbstra
3709
3720
throw CompilerDirectives .shouldNotReachHere ();
3710
3721
}
3711
3722
} else {
3712
- module = factory .createPythonModule (mName );
3723
+ PythonModule pythonModule = factory .createPythonModule (mName );
3724
+ pythonModule .setNativeModuleDef (moduleDef );
3725
+ module = pythonModule ;
3713
3726
}
3714
3727
3715
3728
// parse method definitions
@@ -3742,6 +3755,81 @@ static Object doGeneric(CApiContext capiContext, Object moduleSpec, PythonAbstra
3742
3755
}
3743
3756
}
3744
3757
3758
+ /**
3759
+ * Equivalent to {@code PyModule_ExecDef}.
3760
+ */
3761
+ @ GenerateUncached
3762
+ public abstract static class ExecModuleNode extends MultiPhaseExtensionModuleInitNode {
3763
+ private static final String EXECUTION_FAILED_WITHOUT_EXCEPTION = "execution of module %s failed without setting an exception" ;
3764
+ private static final String EXECUTION_RAISED_EXCEPTION = "execution of module %s raised unreported exception" ;
3765
+
3766
+ public abstract int execute (CApiContext capiContext , PythonModule module , Object moduleDef );
3767
+
3768
+ @ Specialization
3769
+ static int doGeneric (CApiContext capiContext , PythonModule module , Object moduleDef ,
3770
+ @ CachedLanguage PythonLanguage language ,
3771
+ @ Cached PythonObjectFactory factory ,
3772
+ @ Cached ModuleGetNameNode getNameNode ,
3773
+ @ Cached PCallCapiFunction callGetterNode ,
3774
+ @ CachedLibrary (limit = "3" ) InteropLibrary interopLib ,
3775
+ @ Cached ToBorrowedRefNode moduleToNativeNode ,
3776
+ @ Cached PRaiseNode raiseNode ) {
3777
+ // call to type the pointer
3778
+ assert CreateModuleNode .checkLayout (moduleDef , interopLib );
3779
+
3780
+ String mName = getNameNode .execute (module );
3781
+ int mSize ;
3782
+ try {
3783
+ Object mSizeObj = interopLib .readMember (moduleDef , M_SIZE );
3784
+ mSize = interopLib .asInt (mSizeObj );
3785
+ } catch (UnsupportedMessageException | UnknownIdentifierException e ) {
3786
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
3787
+ throw raiseNode .raise (PythonBuiltinClassType .SystemError , "Cannot create module from definition because: %m" , e );
3788
+ }
3789
+
3790
+ if (mSize >= 0 ) {
3791
+ // TODO(fa): allocate md_state
3792
+ }
3793
+
3794
+ // parse slot definitions
3795
+ try {
3796
+ Object slotDefinitions = callGetterNode .call (capiContext , FUN_GET_PYMODULEDEF_M_SLOTS , moduleDef );
3797
+ if (interopLib .isNull (slotDefinitions )) {
3798
+ return 0 ;
3799
+ }
3800
+ if (!interopLib .hasArrayElements (slotDefinitions )) {
3801
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
3802
+ throw raiseNode .raise (PythonBuiltinClassType .SystemError , FIELD_S_DID_NOT_RETURN_AN_ARRAY , M_SLOTS );
3803
+ }
3804
+ long nSlots = interopLib .getArraySize (slotDefinitions );
3805
+ for (long i = 0 ; i < nSlots ; i ++) {
3806
+ Object slotDefinition = interopLib .readArrayElement (slotDefinitions , i );
3807
+
3808
+ Object slotIdObj = interopLib .readMember (slotDefinition , MODULEDEF_SLOT );
3809
+ int slotId = interopLib .asInt (slotIdObj );
3810
+ switch (slotId ) {
3811
+ case SLOT_PY_MOD_CREATE :
3812
+ // handled in CreateModuleNode
3813
+ break ;
3814
+ case SLOT_PY_MOD_EXEC :
3815
+ Object execFunction = interopLib .readMember (slotDefinition , MODULEDEF_VALUE );
3816
+ Object result = interopLib .execute (execFunction , moduleToNativeNode .execute (capiContext , module ));
3817
+ int iResult = interopLib .asInt (result );
3818
+ DefaultCheckFunctionResultNode .checkFunctionResult (mName , iResult != 0 , true , language , capiContext .getContext (), raiseNode , factory ,
3819
+ EXECUTION_FAILED_WITHOUT_EXCEPTION , EXECUTION_RAISED_EXCEPTION );
3820
+ break ;
3821
+ default :
3822
+ throw raiseNode .raise (SystemError , "module %s initialized with unknown slot %i" , mName , slotId );
3823
+ }
3824
+ }
3825
+ } catch (UnsupportedMessageException | InvalidArrayIndexException | UnknownIdentifierException | UnsupportedTypeException | ArityException e ) {
3826
+ throw CompilerDirectives .shouldNotReachHere ();
3827
+ }
3828
+
3829
+ return 0 ;
3830
+ }
3831
+ }
3832
+
3745
3833
/**
3746
3834
* <pre>
3747
3835
* struct PyMethodDef {
0 commit comments