@@ -475,7 +475,7 @@ public int read(byte[] b, int off, int len) {
475475 int depth = 0 ;
476476 long cacheKey ;
477477 TruffleFile bytecodeFile ;
478- TruffleFile sourceFile ;
478+ SourceReference sourceReference ;
479479 // Offset of the buffer in parent buffer in nested deserializations
480480 int baseOffset ;
481481
@@ -507,23 +507,22 @@ public int read(byte[] b, int off, int len) {
507507 }
508508
509509 Marshal (PythonLanguage language , byte [] in , int length , long cacheKey ) {
510- this (language , SerializationUtils .createByteBufferDataInput (ByteBuffer .wrap (in , 0 , length )), null , null , 0 );
510+ this (language , SerializationUtils .createByteBufferDataInput (ByteBuffer .wrap (in , 0 , length )), null , 0 );
511511 this .cacheKey = cacheKey ;
512512 }
513513
514514 Marshal (PythonLanguage language , byte [] in , int length , long cacheKey , TruffleFile bytecodeFile , int baseOffset ) {
515- this (language , SerializationUtils .createByteBufferDataInput (ByteBuffer .wrap (in , 0 , length )), null , bytecodeFile , baseOffset );
515+ this (language , SerializationUtils .createByteBufferDataInput (ByteBuffer .wrap (in , 0 , length )), bytecodeFile , baseOffset );
516516 this .cacheKey = cacheKey ;
517517 }
518518
519519 Marshal (PythonLanguage language , Object in ) {
520- this (language , new DataInputStream (new FileLikeInputStream (in )), null , null , 0 );
520+ this (language , new DataInputStream (new FileLikeInputStream (in )), null , 0 );
521521 }
522522
523- Marshal (PythonLanguage language , DataInput in , Source source , TruffleFile bytecodeFile , int baseOffset ) {
523+ Marshal (PythonLanguage language , DataInput in , TruffleFile bytecodeFile , int baseOffset ) {
524524 this .language = language ;
525525 this .in = in ;
526- this .source = source ;
527526 this .refList = new ArrayList <>();
528527 this .version = -1 ;
529528 this .outData = null ;
@@ -949,7 +948,7 @@ private void writeComplexObject(Object v, int flag) {
949948 }
950949 } else if (v instanceof Source s ) {
951950 writeByte (TYPE_DSL_SOURCE | flag );
952- setSource (s );
951+ writeSource (s );
953952 } else {
954953 PythonBufferAcquireLibrary acquireLib = PythonBufferAcquireLibrary .getFactory ().getUncached (v );
955954 if (acquireLib .hasBuffer (v )) {
@@ -1166,7 +1165,7 @@ private Object readObject(int type, AddRefAndReturn addRef) throws NumberFormatE
11661165 case TYPE_GRAALPYTHON_DSL_CODE_UNIT :
11671166 return addRef .run (readBytecodeDSLCodeUnit ());
11681167 case TYPE_DSL_SOURCE :
1169- return getSource ( );
1168+ return addRef . run ( readSource () );
11701169 case TYPE_DSL_EMPTY_KEYWORDS :
11711170 return PKeyword .EMPTY_KEYWORDS ;
11721171 case TYPE_ARRAY :
@@ -1182,6 +1181,18 @@ private void writeString(TruffleString v) {
11821181 writeBytes (ba .getArray (), ba .getOffset (), ba .getLength ());
11831182 }
11841183
1184+ private void writeSource (Source source ) {
1185+ writeString (TruffleString .fromJavaStringUncached (source .getName (), TS_ENCODING ));
1186+ }
1187+
1188+ private Source readSource () {
1189+ String name = readString (false ).toJavaStringUncached ();
1190+ if (sourceReference == null ) {
1191+ sourceReference = new SourceReference (name );
1192+ }
1193+ return sourceReference .getSource (language );
1194+ }
1195+
11851196 private TruffleString readString (boolean intern ) {
11861197 int sz = readInt ();
11871198 if (sz == 0 ) {
@@ -1338,24 +1349,6 @@ private Object[] readObjectArray() {
13381349 return a ;
13391350 }
13401351
1341- private void setSource (Source s ) {
1342- if (source == null ) {
1343- source = s ;
1344- } else if (source != s ) {
1345- throw CompilerDirectives .shouldNotReachHere ("attempted to serialize with multiple Source objects" );
1346- }
1347- }
1348-
1349- private Source getSource () {
1350- if (source != null ) {
1351- return source ;
1352- } else {
1353- // This should never happen when deserializing a bytecode DSL code unit, but could
1354- // happen if the user tries to deserialize arbitrary bytes.
1355- throw new MarshalError (ValueError , ErrorMessages .BAD_MARSHAL_DATA );
1356- }
1357- }
1358-
13591352 private CodeUnit readCodeUnit () {
13601353 int codeUnitType = readByte ();
13611354 return switch (codeUnitType ) {
@@ -1450,7 +1443,7 @@ private BytecodeDSLCodeUnit readBytecodeDSLCodeUnit() {
14501443 int yieldFromGeneratorIndex = readInt ();
14511444 int instrumentationDataIndex = readInt ();
14521445
1453- BytecodeSupplier provider = new BytecodeSupplier (serialized , bytecodeFile , bytecodeOffset , bytecodeSize , cacheKey );
1446+ BytecodeSupplier provider = new BytecodeSupplier (serialized , bytecodeFile , sourceReference , bytecodeOffset , bytecodeSize , cacheKey );
14541447 return new BytecodeDSLCodeUnit (name , qualname , argCount , kwOnlyArgCount , positionalOnlyArgCount , flags , names , varnames , cellvars , freevars , cell2arg , constants ,
14551448 startLine , startColumn , endLine , endColumn , classcellIndex , selfIndex , yieldFromGeneratorIndex , instrumentationDataIndex , provider );
14561449 }
@@ -1545,8 +1538,8 @@ private PCode readCode() {
15451538 String jName = code .qualname .toJavaStringUncached ();
15461539 Source source = Source .newBuilder (PythonLanguage .ID , "" , jName ).content (Source .CONTENT_NONE ).build ();
15471540 PythonLanguage language = this .language ;
1548- if (sourceFile != null ) {
1549- language .registerOriginalFile (source , sourceFile );
1541+ if (sourceReference != null && sourceReference . sourceFile != null ) {
1542+ language .registerOriginalFile (source , sourceReference . sourceFile );
15501543 }
15511544 return language .callTargetFromBytecode (source , code );
15521545 };
@@ -1587,36 +1580,65 @@ public static CodeUnit deserializeCodeUnit(Node node, PythonLanguage language, b
15871580 }
15881581 }
15891582
1583+ private static final class SourceReference {
1584+ private String name ;
1585+ private final TruffleFile sourceFile ;
1586+ private Source source ;
1587+
1588+ SourceReference (String name ) {
1589+ this .name = name ;
1590+ this .sourceFile = null ;
1591+ }
1592+
1593+ SourceReference (TruffleFile sourceFile ) {
1594+ this .sourceFile = sourceFile ;
1595+ }
1596+
1597+ synchronized Source getSource (PythonLanguage language ) {
1598+ if (source == null ) {
1599+ String sourceName = sourceFile != null ? sourceFile .getPath () : name ;
1600+ source = Source .newBuilder (PythonLanguage .ID , "" , sourceName ).content (Source .CONTENT_NONE ).build ();
1601+ if (sourceFile != null ) {
1602+ language .registerOriginalFile (source , sourceFile );
1603+ }
1604+ }
1605+ return source ;
1606+ }
1607+ }
1608+
15901609 public static class BytecodeSupplier extends BytecodeDSLCodeUnit .BytecodeSupplier {
15911610 private byte [] serialized ;
15921611 // Original file for reparsing
15931612 private final TruffleFile bytecodeFile ;
1613+ private final SourceReference sourceReference ;
15941614 // Offset within the bytecode file, points directly at the start of serialized bytecode
15951615 private final int bytecodeOffset ;
15961616 private final int bytecodeSize ;
15971617 private final long cacheKey ;
15981618
1599- public BytecodeSupplier (byte [] serialized , TruffleFile bytecodeFile , int bytecodeOffset , int bytecodeSize , long cacheKey ) {
1619+ public BytecodeSupplier (byte [] serialized , TruffleFile bytecodeFile , SourceReference sourceReference , int bytecodeOffset , int bytecodeSize , long cacheKey ) {
16001620 this .serialized = serialized ;
16011621 this .bytecodeFile = bytecodeFile ;
1622+ this .sourceReference = sourceReference ;
16021623 this .bytecodeOffset = bytecodeOffset ;
16031624 this .bytecodeSize = bytecodeSize ;
16041625 this .cacheKey = cacheKey ;
16051626 }
16061627
16071628 @ Override
1608- public PBytecodeDSLRootNode createRootNode (PythonLanguage language , Source source ) {
1629+ public PBytecodeDSLRootNode createRootNode (PythonLanguage language ) {
16091630 BytecodeRootNodes <PBytecodeDSLRootNode > deserialized ;
16101631 try {
1611- deserialized = PBytecodeDSLRootNodeGen .deserialize (language , BytecodeConfig .WITH_SOURCE ,
1632+ deserialized = PBytecodeDSLRootNodeGen .deserialize (language , BytecodeConfig .DEFAULT ,
16121633 () -> SerializationUtils .createByteBufferDataInput (ByteBuffer .wrap (getBytecode ())),
16131634 /*
16141635 * NB: Since a DSL node may reparse multiple times, we cannot reuse
16151636 * a common Marshal object across calls (each call may take a
16161637 * different buffer).
16171638 */
16181639 (deserializerContext , buffer ) -> {
1619- Marshal marshal = new Marshal (language , buffer , source , bytecodeFile , bytecodeOffset );
1640+ Marshal marshal = new Marshal (language , buffer , bytecodeFile , bytecodeOffset );
1641+ marshal .sourceReference = sourceReference ;
16201642 marshal .cacheKey = cacheKey ;
16211643 return marshal .readObject ();
16221644 });
@@ -1699,7 +1721,7 @@ public ReparseError(String message) {
16991721 @ TruffleBoundary
17001722 public static Object fromBytecodeFile (PythonLanguage language , TruffleFile bytecodeFile , TruffleFile sourceFile , byte [] bytes , int offset , int length , long cacheKey ) throws IOException {
17011723 MarshalModuleBuiltins .Marshal marshal = new MarshalModuleBuiltins .Marshal (language , bytes , length + offset , cacheKey , bytecodeFile , 0 );
1702- marshal .sourceFile = sourceFile ;
1724+ marshal .sourceReference = sourceFile == null ? null : new SourceReference ( sourceFile ) ;
17031725 marshal .in .skipBytes (offset );
17041726 return marshal .readObject ();
17051727 }
0 commit comments