9090import com .oracle .graal .python .builtins .objects .module .PythonModule ;
9191import com .oracle .graal .python .builtins .objects .object .PythonObject ;
9292import com .oracle .graal .python .builtins .objects .str .PString ;
93+ import com .oracle .graal .python .compiler .CodeUnit ;
9394import com .oracle .graal .python .compiler .Compiler ;
9495import com .oracle .graal .python .lib .PyObjectGetAttr ;
9596import com .oracle .graal .python .lib .PyObjectLookupAttr ;
131132import com .oracle .truffle .api .memory .ByteArraySupport ;
132133import com .oracle .truffle .api .nodes .Node ;
133134import com .oracle .truffle .api .profiles .InlinedConditionProfile ;
135+ import com .oracle .truffle .api .source .Source ;
134136import com .oracle .truffle .api .strings .TruffleString ;
135137import com .oracle .truffle .api .utilities .TriState ;
136138
@@ -157,20 +159,14 @@ private static class FrozenResult {
157159
158160 private static class FrozenInfo {
159161 @ SuppressWarnings ("unused" ) final TruffleString name ;
160- final byte [] data ;
161- final int size ;
162+ final CodeUnit code ;
162163 final boolean isPackage ;
163164 final TruffleString origName ;
164165 @ SuppressWarnings ("unused" ) final boolean isAlias ;
165166
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 ) {
171168 this .name = name ;
172- this .data = data ;
173- this .size = size ;
169+ this .code = code ;
174170 this .isPackage = isPackage ;
175171 this .origName = origName ;
176172 this .isAlias = isAlias ;
@@ -548,39 +544,45 @@ static Object run(VirtualFrame frame, TruffleString name, Object dataObj,
548544 @ Cached PRaiseNode raiseNode ) {
549545 FrozenInfo info ;
550546 if (dataObj != PNone .NONE ) {
547+ byte [] bytes ;
548+ int size ;
551549 try {
552- info = new FrozenInfo (bufferLib .getInternalOrCopiedByteArray (dataObj ), bufferLib .getBufferLength (dataObj ));
550+ bytes = bufferLib .getInternalOrCopiedByteArray (dataObj );
551+ size = bufferLib .getBufferLength (dataObj );
553552 } finally {
554553 bufferLib .release (dataObj , frame , indirectCallData );
555554 }
556- if (info . size == 0 ) {
555+ if (size == 0 ) {
557556 /* Does not contain executable code. */
558557 raiseFrozenError (frame , FROZEN_INVALID , name , constructAndRaiseNode .get (inliningTarget ));
559558 }
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 ;
560573 } else {
561574 FrozenResult result = findFrozen (context , name , equalNode );
562575 FrozenStatus status = result .status ;
563576 info = result .info ;
564577 raiseFrozenError (frame , status , name , constructAndRaiseNode .get (inliningTarget ));
565- }
566578
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 );
577581 }
578-
579- return code ;
580582 }
581583 }
582584
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 " +
584586 "--\n " +
585587 "\n " +
586588 "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,
594596 " the module\' s current name)" )
595597 @ GenerateNodeFactory
596598 @ 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 )
598600 abstract static class FindFrozen extends PythonBinaryClinicBuiltinNode {
599601
600602 @ Override
@@ -625,7 +627,8 @@ static Object run(VirtualFrame frame, TruffleString name, boolean withData,
625627 PMemoryView data = null ;
626628
627629 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 ));
629632 }
630633
631634 Object [] returnValues = new Object []{
@@ -690,16 +693,14 @@ public static PythonModule importFrozenModuleObject(Python3Core core, TruffleStr
690693 }
691694 }
692695
693- PCode code = (PCode ) MarshalModuleBuiltins .Marshal .load (core .getContext (), info .data , info .size );
694-
696+ RootCallTarget callTarget = createCallTarget (core .getContext (), info );
695697 PythonModule module = globals == null ? PFactory .createPythonModule (core .getLanguage (), name ) : globals ;
696698
697699 if (info .isPackage ) {
698700 /* Set __path__ to the empty list */
699701 WriteAttributeToPythonObjectNode .getUncached ().execute (module , T___PATH__ , PFactory .createList (core .getLanguage ()));
700702 }
701703
702- RootCallTarget callTarget = code .getRootCallTarget ();
703704 CallDispatchers .SimpleIndirectInvokeNode .executeUncached (callTarget , PArguments .withGlobals (module ));
704705
705706 Object origName = info .origName == null ? PNone .NONE : info .origName ;
@@ -708,6 +709,12 @@ public static PythonModule importFrozenModuleObject(Python3Core core, TruffleStr
708709 return module ;
709710 }
710711
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+
711718 /*
712719 * CPython's version of this accepts any object and casts, but all Python-level callers use
713720 * argument clinic to convert the name first. The only exception is
@@ -727,20 +734,11 @@ private static FrozenResult findFrozen(PythonContext context, TruffleString name
727734 boolean isAlias = module .getOriginalName () == null || !equalNode .execute (name , module .getOriginalName (), TS_ENCODING );
728735 FrozenInfo info = new FrozenInfo (name ,
729736 module .getCode (),
730- module .getSize (),
731737 module .isPackage (),
732738 module .getOriginalName (),
733739 !isAlias );
734740
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
744742
745743 return new FrozenResult (FROZEN_OKAY , info );
746744 }
0 commit comments