@@ -4786,6 +4786,7 @@ public final int constantsID(){
4786
4786
4787
4787
private DynamicClassLoader loader ;
4788
4788
private byte [] bytecode ;
4789
+ Map <String , byte []> constFieldBytecode ;
4789
4790
4790
4791
public ObjExpr (Object tag ){
4791
4792
this .tag = tag ;
@@ -4824,7 +4825,7 @@ void compile(String superName, String[] interfaceNames, boolean oneTimeUse) thro
4824
4825
ClassVisitor cv = cw ;
4825
4826
// ClassVisitor cv = new TraceClassVisitor(new CheckClassAdapter(cw), new PrintWriter(System.out));
4826
4827
//ClassVisitor cv = new TraceClassVisitor(cw, new PrintWriter(System.out));
4827
- cv .visit (V1_8 , ACC_PUBLIC + ACC_SUPER + ACC_FINAL , internalName , null ,superName ,interfaceNames );
4828
+ cv .visit (V17 , ACC_PUBLIC + ACC_SUPER + ACC_FINAL , internalName , null ,superName ,interfaceNames );
4828
4829
// superName != null ? superName :
4829
4830
// (isVariadic() ? "clojure/lang/RestFn" : "clojure/lang/AFunction"), null);
4830
4831
String source = (String ) SOURCE .deref ();
@@ -5096,14 +5097,7 @@ void compile(String superName, String[] interfaceNames, boolean oneTimeUse) thro
5096
5097
emitStatics (cv );
5097
5098
emitMethods (cv );
5098
5099
5099
- //static fields for constants
5100
- for (int i = 0 ; i < constants .count (); i ++)
5101
- {
5102
- if (usedConstants .contains (i ))
5103
- cv .visitField (ACC_PUBLIC + ACC_FINAL
5104
- + ACC_STATIC , constantName (i ), constantType (i ).getDescriptor (),
5105
- null , null );
5106
- }
5100
+ emitConstantFields (cv );
5107
5101
5108
5102
//static fields for lookup sites
5109
5103
for (int i = 0 ; i < keywordCallsites .count (); i ++)
@@ -5124,11 +5118,6 @@ void compile(String superName, String[] interfaceNames, boolean oneTimeUse) thro
5124
5118
clinitgen .visitCode ();
5125
5119
clinitgen .visitLineNumber (line , clinitgen .mark ());
5126
5120
5127
- if (constants .count () > 0 )
5128
- {
5129
- emitConstants (clinitgen );
5130
- }
5131
-
5132
5121
if (keywordCallsites .count () > 0 )
5133
5122
emitKeywordCallsites (clinitgen );
5134
5123
@@ -5183,8 +5172,16 @@ void compile(String superName, String[] interfaceNames, boolean oneTimeUse) thro
5183
5172
cv .visitEnd ();
5184
5173
5185
5174
bytecode = cw .toByteArray ();
5186
- if (RT .booleanCast (COMPILE_FILES .deref ()))
5175
+ if (RT .booleanCast (COMPILE_FILES .deref ())) {
5187
5176
writeClassFile (internalName , bytecode );
5177
+ if (constFieldBytecode != null ) {
5178
+ for (Map .Entry <String , byte []> entry : constFieldBytecode .entrySet ()) {
5179
+ String constName = entry .getKey ();
5180
+ byte [] constBytecode = entry .getValue ();
5181
+ writeClassFile (constName , constBytecode );
5182
+ }
5183
+ }
5184
+ }
5188
5185
// else
5189
5186
// getCompiledClass();
5190
5187
}
@@ -5438,6 +5435,62 @@ else if(value instanceof Pattern)
5438
5435
}
5439
5436
}
5440
5437
5438
+ void emitConstantFields (ClassVisitor cv ) throws IOException {
5439
+ if (constants .count () > 0 ) {
5440
+ Map <String , byte []> tempFieldBytecode = new HashMap <>();
5441
+ final int INITS_PER = 100 ;
5442
+ int numInits = constants .count () / INITS_PER ;
5443
+ if (constants .count () % INITS_PER != 0 )
5444
+ ++numInits ;
5445
+
5446
+ for (int n = 0 ; n < numInits ; n ++) {
5447
+ int containerStart = n * INITS_PER ;
5448
+ Type inner_type = constantContainer (containerStart );
5449
+
5450
+ cv .visitInnerClass (inner_type .getInternalName (),
5451
+ objtype .getInternalName (),
5452
+ constantContainerName (containerStart ),
5453
+ ACC_STATIC + ACC_FINAL );
5454
+
5455
+ ClassWriter inner_cw = classWriter ();
5456
+ ClassVisitor inner_cv = inner_cw ;
5457
+ inner_cv .visit (V17 , ACC_PUBLIC + ACC_SUPER , inner_type .getInternalName (), null , "java/lang/Object" , null );
5458
+
5459
+ //static fields for constants
5460
+ for (int i = n * INITS_PER ; i < constants .count () && i < (n + 1 ) * INITS_PER ; i ++) {
5461
+ if (usedConstants .contains (i ))
5462
+ inner_cv .visitField (ACC_PUBLIC + ACC_FINAL + ACC_STATIC , constantName (i ), constantType (i ).getDescriptor (),
5463
+ null , null );
5464
+ }
5465
+
5466
+ GeneratorAdapter clinitgen = new GeneratorAdapter (ACC_PUBLIC + ACC_STATIC ,
5467
+ Method .getMethod ("void <clinit> ()" ),
5468
+ null ,
5469
+ null ,
5470
+ inner_cv );
5471
+
5472
+ clinitgen .visitCode ();
5473
+ try {
5474
+ Var .pushThreadBindings (RT .map (RT .PRINT_DUP , RT .T ));
5475
+
5476
+ for (int i = n * INITS_PER ; i < constants .count () && i < (n + 1 ) * INITS_PER ; i ++) {
5477
+ if (usedConstants .contains (i )) {
5478
+ emitValue (constants .nth (i ), clinitgen );
5479
+ clinitgen .checkCast (constantType (i ));
5480
+ clinitgen .putStatic (constantContainer (i ), constantName (i ), constantType (i ));
5481
+ }
5482
+ }
5483
+ } finally {
5484
+ Var .popThreadBindings ();
5485
+ }
5486
+ clinitgen .returnValue ();
5487
+ clinitgen .endMethod ();
5488
+ inner_cv .visitEnd ();
5489
+ tempFieldBytecode .put (inner_type .getInternalName (), inner_cw .toByteArray ());
5490
+ }
5491
+ constFieldBytecode = tempFieldBytecode ;
5492
+ }
5493
+ }
5441
5494
5442
5495
void emitConstants (GeneratorAdapter clinitgen ){
5443
5496
try
@@ -5500,6 +5553,10 @@ synchronized Class getCompiledClass(){
5500
5553
// else
5501
5554
{
5502
5555
loader = (DynamicClassLoader ) LOADER .deref ();
5556
+ if (constFieldBytecode != null )
5557
+ constFieldBytecode .forEach ((constName , constBytecode ) -> {
5558
+ loader .defineClass (constName .replace ("/" , "." ), constBytecode , src );
5559
+ });
5503
5560
compiledClass = loader .defineClass (name , bytecode , src );
5504
5561
}
5505
5562
return compiledClass ;
@@ -5650,7 +5707,7 @@ private void emitLocal(GeneratorAdapter gen, LocalBinding lb, boolean clear){
5650
5707
{
5651
5708
// System.out.println("use: " + rep);
5652
5709
}
5653
- }
5710
+ }
5654
5711
}
5655
5712
else
5656
5713
{
@@ -5722,9 +5779,18 @@ public void emitKeyword(GeneratorAdapter gen, Keyword k){
5722
5779
5723
5780
public void emitConstant (GeneratorAdapter gen , int id ){
5724
5781
usedConstants = (IPersistentSet ) usedConstants .cons (id );
5725
- gen .getStatic (objtype , constantName (id ), constantType (id ));
5782
+ gen .getStatic (constantContainer (id ), constantName (id ), constantType (id ));
5783
+ }
5784
+
5785
+ public static final int INITS_PER = 100 ;
5786
+
5787
+ public Type constantContainer (int id ) {
5788
+ return Type .getObjectType (objtype .getInternalName () + "$" + constantContainerName (id ));
5726
5789
}
5727
5790
5791
+ public String constantContainerName (int id ) {
5792
+ return "ID_" + (id / INITS_PER );
5793
+ }
5728
5794
5729
5795
String constantName (int id ){
5730
5796
return CONST_PREFIX + id ;
@@ -8308,7 +8374,7 @@ CONSTANT_IDS, new IdentityHashMap(),
8308
8374
objx .objtype = Type .getObjectType (objx .internalName );
8309
8375
ClassWriter cw = classWriter ();
8310
8376
ClassVisitor cv = cw ;
8311
- cv .visit (V1_8 , ACC_PUBLIC + ACC_SUPER , objx .internalName , null , "java/lang/Object" , null );
8377
+ cv .visit (V17 , ACC_PUBLIC + ACC_SUPER , objx .internalName , null , "java/lang/Object" , null );
8312
8378
8313
8379
//static load method
8314
8380
GeneratorAdapter gen = new GeneratorAdapter (ACC_PUBLIC + ACC_STATIC ,
@@ -8332,48 +8398,7 @@ CONSTANT_IDS, new IdentityHashMap(),
8332
8398
gen .returnValue ();
8333
8399
gen .endMethod ();
8334
8400
8335
- //static fields for constants
8336
- for (int i = 0 ; i < objx .constants .count (); i ++)
8337
- {
8338
- if (objx .usedConstants .contains (i ))
8339
- cv .visitField (ACC_PUBLIC + ACC_FINAL + ACC_STATIC , objx .constantName (i ), objx .constantType (i ).getDescriptor (),
8340
- null , null );
8341
- }
8342
-
8343
- final int INITS_PER = 100 ;
8344
- int numInits = objx .constants .count () / INITS_PER ;
8345
- if (objx .constants .count () % INITS_PER != 0 )
8346
- ++numInits ;
8347
-
8348
- for (int n = 0 ;n <numInits ;n ++)
8349
- {
8350
- GeneratorAdapter clinitgen = new GeneratorAdapter (ACC_PUBLIC + ACC_STATIC ,
8351
- Method .getMethod ("void __init" + n + "()" ),
8352
- null ,
8353
- null ,
8354
- cv );
8355
- clinitgen .visitCode ();
8356
- try
8357
- {
8358
- Var .pushThreadBindings (RT .map (RT .PRINT_DUP , RT .T ));
8359
-
8360
- for (int i = n *INITS_PER ; i < objx .constants .count () && i < (n +1 )*INITS_PER ; i ++)
8361
- {
8362
- if (objx .usedConstants .contains (i ))
8363
- {
8364
- objx .emitValue (objx .constants .nth (i ), clinitgen );
8365
- clinitgen .checkCast (objx .constantType (i ));
8366
- clinitgen .putStatic (objx .objtype , objx .constantName (i ), objx .constantType (i ));
8367
- }
8368
- }
8369
- }
8370
- finally
8371
- {
8372
- Var .popThreadBindings ();
8373
- }
8374
- clinitgen .returnValue ();
8375
- clinitgen .endMethod ();
8376
- }
8401
+ objx .emitConstantFields (cv );
8377
8402
8378
8403
//static init for constants, keywords and vars
8379
8404
GeneratorAdapter clinitgen = new GeneratorAdapter (ACC_PUBLIC + ACC_STATIC ,
@@ -8391,8 +8416,6 @@ CONSTANT_IDS, new IdentityHashMap(),
8391
8416
// {
8392
8417
// objx.emitConstants(clinitgen);
8393
8418
// }
8394
- for (int n = 0 ;n <numInits ;n ++)
8395
- clinitgen .invokeStatic (objx .objtype , Method .getMethod ("void __init" + n + "()" ));
8396
8419
8397
8420
clinitgen .push (objx .internalName .replace ('/' ,'.' ));
8398
8421
clinitgen .invokeStatic (RT_TYPE , Method .getMethod ("Class classForName(String)" ));
@@ -8418,7 +8441,12 @@ CONSTANT_IDS, new IdentityHashMap(),
8418
8441
//end of class
8419
8442
cv .visitEnd ();
8420
8443
8421
- writeClassFile (objx .internalName , cw .toByteArray ());
8444
+ for (Map .Entry <String , byte []> entry : objx .constFieldBytecode .entrySet ()) {
8445
+ String constName = entry .getKey ();
8446
+ byte [] constBytecode = entry .getValue ();
8447
+ writeClassFile (constName , constBytecode );
8448
+ }
8449
+ writeClassFile (objx .internalName , cw .toByteArray ());
8422
8450
}
8423
8451
catch (LispReader .ReaderException e )
8424
8452
{
@@ -8628,7 +8656,7 @@ VAR_CALLSITES, emptyVarCallSites(),
8628
8656
static Class compileStub (String superName , NewInstanceExpr ret , String [] interfaceNames , Object frm ){
8629
8657
ClassWriter cw = classWriter ();
8630
8658
ClassVisitor cv = cw ;
8631
- cv .visit (V1_8 , ACC_PUBLIC + ACC_SUPER , COMPILE_STUB_PREFIX + "/" + ret .internalName ,
8659
+ cv .visit (V17 , ACC_PUBLIC + ACC_SUPER , COMPILE_STUB_PREFIX + "/" + ret .internalName ,
8632
8660
null ,superName ,interfaceNames );
8633
8661
8634
8662
//instance fields for closed-overs
0 commit comments