90
90
import com .oracle .graal .python .builtins .objects .module .PythonModule ;
91
91
import com .oracle .graal .python .builtins .objects .object .PythonObject ;
92
92
import com .oracle .graal .python .builtins .objects .str .PString ;
93
+ import com .oracle .graal .python .compiler .CodeUnit ;
93
94
import com .oracle .graal .python .compiler .Compiler ;
94
95
import com .oracle .graal .python .lib .PyObjectGetAttr ;
95
96
import com .oracle .graal .python .lib .PyObjectLookupAttr ;
131
132
import com .oracle .truffle .api .memory .ByteArraySupport ;
132
133
import com .oracle .truffle .api .nodes .Node ;
133
134
import com .oracle .truffle .api .profiles .InlinedConditionProfile ;
135
+ import com .oracle .truffle .api .source .Source ;
134
136
import com .oracle .truffle .api .strings .TruffleString ;
135
137
import com .oracle .truffle .api .utilities .TriState ;
136
138
@@ -157,20 +159,14 @@ private static class FrozenResult {
157
159
158
160
private static class FrozenInfo {
159
161
@ SuppressWarnings ("unused" ) final TruffleString name ;
160
- final byte [] data ;
161
- final int size ;
162
+ final CodeUnit code ;
162
163
final boolean isPackage ;
163
164
final TruffleString origName ;
164
165
@ SuppressWarnings ("unused" ) final boolean isAlias ;
165
166
166
- FrozenInfo (byte [] data , int size ) {
167
- this (null , data , size , false , null , false );
168
- }
169
-
170
- FrozenInfo (TruffleString name , byte [] data , int size , boolean isPackage , TruffleString origName , boolean isAlias ) {
167
+ FrozenInfo (TruffleString name , CodeUnit code , boolean isPackage , TruffleString origName , boolean isAlias ) {
171
168
this .name = name ;
172
- this .data = data ;
173
- this .size = size ;
169
+ this .code = code ;
174
170
this .isPackage = isPackage ;
175
171
this .origName = origName ;
176
172
this .isAlias = isAlias ;
@@ -548,39 +544,45 @@ static Object run(VirtualFrame frame, TruffleString name, Object dataObj,
548
544
@ Cached PRaiseNode raiseNode ) {
549
545
FrozenInfo info ;
550
546
if (dataObj != PNone .NONE ) {
547
+ byte [] bytes ;
548
+ int size ;
551
549
try {
552
- info = new FrozenInfo (bufferLib .getInternalOrCopiedByteArray (dataObj ), bufferLib .getBufferLength (dataObj ));
550
+ bytes = bufferLib .getInternalOrCopiedByteArray (dataObj );
551
+ size = bufferLib .getBufferLength (dataObj );
553
552
} finally {
554
553
bufferLib .release (dataObj , frame , indirectCallData );
555
554
}
556
- if (info . size == 0 ) {
555
+ if (size == 0 ) {
557
556
/* Does not contain executable code. */
558
557
raiseFrozenError (frame , FROZEN_INVALID , name , constructAndRaiseNode .get (inliningTarget ));
559
558
}
559
+
560
+ Object code = null ;
561
+
562
+ try {
563
+ code = MarshalModuleBuiltins .Marshal .load (context , bytes , size );
564
+ } catch (MarshalError | NumberFormatException e ) {
565
+ raiseFrozenError (frame , FROZEN_INVALID , name , constructAndRaiseNode .get (inliningTarget ));
566
+ }
567
+
568
+ if (!isCodeObjectProfile .profile (inliningTarget , code instanceof PCode )) {
569
+ throw raiseNode .raise (inliningTarget , TypeError , ErrorMessages .NOT_A_CODE_OBJECT , name );
570
+ }
571
+
572
+ return code ;
560
573
} else {
561
574
FrozenResult result = findFrozen (context , name , equalNode );
562
575
FrozenStatus status = result .status ;
563
576
info = result .info ;
564
577
raiseFrozenError (frame , status , name , constructAndRaiseNode .get (inliningTarget ));
565
- }
566
578
567
- Object code = null ;
568
-
569
- try {
570
- code = MarshalModuleBuiltins .Marshal .load (context , info .data , info .size );
571
- } catch (MarshalError | NumberFormatException e ) {
572
- raiseFrozenError (frame , FROZEN_INVALID , name , constructAndRaiseNode .get (inliningTarget ));
573
- }
574
-
575
- if (!isCodeObjectProfile .profile (inliningTarget , code instanceof PCode )) {
576
- throw raiseNode .raise (inliningTarget , TypeError , ErrorMessages .NOT_A_CODE_OBJECT , name );
579
+ RootCallTarget callTarget = createCallTarget (context , info );
580
+ return PFactory .createCode (context .getLanguage (), callTarget );
577
581
}
578
-
579
- return code ;
580
582
}
581
583
}
582
584
583
- @ Builtin (name = "find_frozen" , parameterNames = {"name" , "withData " }, minNumOfPositionalArgs = 1 , doc = "find_frozen($module, name, /, *, withdata=False)\n " +
585
+ @ Builtin (name = "find_frozen" , parameterNames = {"name" , "withdata " }, minNumOfPositionalArgs = 1 , doc = "find_frozen($module, name, /, *, withdata=False)\n " +
584
586
"--\n " +
585
587
"\n " +
586
588
"Return info about the corresponding frozen module (if there is one) or None.\n " +
@@ -594,7 +596,7 @@ static Object run(VirtualFrame frame, TruffleString name, Object dataObj,
594
596
" the module\' s current name)" )
595
597
@ GenerateNodeFactory
596
598
@ ArgumentClinic (name = "name" , conversion = ArgumentClinic .ClinicConversion .TString )
597
- @ ArgumentClinic (name = "withData " , conversion = ArgumentClinic .ClinicConversion .Boolean , defaultValue = "false" , useDefaultForNone = true )
599
+ @ ArgumentClinic (name = "withdata " , conversion = ArgumentClinic .ClinicConversion .Boolean , defaultValue = "false" , useDefaultForNone = true )
598
600
abstract static class FindFrozen extends PythonBinaryClinicBuiltinNode {
599
601
600
602
@ Override
@@ -625,7 +627,8 @@ static Object run(VirtualFrame frame, TruffleString name, boolean withData,
625
627
PMemoryView data = null ;
626
628
627
629
if (withData ) {
628
- data = memoryViewNode .execute (frame , PFactory .createBytes (context .getLanguage (inliningTarget ), info .data ));
630
+ byte [] bytes = MarshalModuleBuiltins .serializeCodeUnit (inliningTarget , context , info .code );
631
+ data = memoryViewNode .execute (frame , PFactory .createBytes (context .getLanguage (inliningTarget ), bytes ));
629
632
}
630
633
631
634
Object [] returnValues = new Object []{
@@ -690,16 +693,14 @@ public static PythonModule importFrozenModuleObject(Python3Core core, TruffleStr
690
693
}
691
694
}
692
695
693
- PCode code = (PCode ) MarshalModuleBuiltins .Marshal .load (core .getContext (), info .data , info .size );
694
-
696
+ RootCallTarget callTarget = createCallTarget (core .getContext (), info );
695
697
PythonModule module = globals == null ? PFactory .createPythonModule (core .getLanguage (), name ) : globals ;
696
698
697
699
if (info .isPackage ) {
698
700
/* Set __path__ to the empty list */
699
701
WriteAttributeToPythonObjectNode .getUncached ().execute (module , T___PATH__ , PFactory .createList (core .getLanguage ()));
700
702
}
701
703
702
- RootCallTarget callTarget = code .getRootCallTarget ();
703
704
CallDispatchers .SimpleIndirectInvokeNode .executeUncached (callTarget , PArguments .withGlobals (module ));
704
705
705
706
Object origName = info .origName == null ? PNone .NONE : info .origName ;
@@ -708,6 +709,12 @@ public static PythonModule importFrozenModuleObject(Python3Core core, TruffleStr
708
709
return module ;
709
710
}
710
711
712
+ private static RootCallTarget createCallTarget (PythonContext context , FrozenInfo info ) {
713
+ String name = PythonLanguage .FROZEN_FILENAME_PREFIX + info .name + PythonLanguage .FROZEN_FILENAME_SUFFIX ;
714
+ Source source = Source .newBuilder ("python" , "" , name ).content (Source .CONTENT_NONE ).build ();
715
+ return context .getLanguage ().callTargetFromBytecode (context , source , info .code );
716
+ }
717
+
711
718
/*
712
719
* CPython's version of this accepts any object and casts, but all Python-level callers use
713
720
* argument clinic to convert the name first. The only exception is
@@ -727,20 +734,11 @@ private static FrozenResult findFrozen(PythonContext context, TruffleString name
727
734
boolean isAlias = module .getOriginalName () == null || !equalNode .execute (name , module .getOriginalName (), TS_ENCODING );
728
735
FrozenInfo info = new FrozenInfo (name ,
729
736
module .getCode (),
730
- module .getSize (),
731
737
module .isPackage (),
732
738
module .getOriginalName (),
733
739
!isAlias );
734
740
735
- if (module .getCode () == null ) {
736
- /* It is frozen but marked as un-importable. */
737
- return new FrozenResult (FROZEN_EXCLUDED , info );
738
- }
739
-
740
- if (module .getCode ()[0 ] == '\0' || module .getSize () == 0 ) {
741
- /* Does not contain executable code. */
742
- return new FrozenResult (FROZEN_INVALID , info );
743
- }
741
+ // CPython checks for invalid/empty modules here, but we don't generate those
744
742
745
743
return new FrozenResult (FROZEN_OKAY , info );
746
744
}
0 commit comments