1
1
// Copyright (c) Corporation for National Research Initiatives
2
2
package org .python .compiler ;
3
3
4
- import static org .python .util .CodegenUtils .ci ;
5
- import static org .python .util .CodegenUtils .p ;
6
- import static org .python .util .CodegenUtils .sig ;
7
-
8
- import java .io .IOException ;
9
- import java .io .OutputStream ;
10
- import java .util .ArrayList ;
11
- import java .util .Enumeration ;
12
- import java .util .Hashtable ;
13
- import java .util .List ;
14
-
15
4
import org .objectweb .asm .Label ;
16
5
import org .objectweb .asm .Opcodes ;
17
6
import org .objectweb .asm .Type ;
18
7
import org .python .antlr .ParseException ;
19
8
import org .python .antlr .PythonTree ;
9
+ import org .python .antlr .ast .Bytes ;
20
10
import org .python .antlr .ast .Num ;
21
11
import org .python .antlr .ast .Str ;
22
12
import org .python .antlr .ast .Suite ;
41
31
import org .python .core .PyUnicode ;
42
32
import org .python .core .ThreadState ;
43
33
34
+ import java .io .IOException ;
35
+ import java .io .OutputStream ;
36
+ import java .util .ArrayList ;
37
+ import java .util .Enumeration ;
38
+ import java .util .Hashtable ;
39
+ import java .util .List ;
40
+
41
+ import static org .python .util .CodegenUtils .*;
42
+
44
43
class PyIntegerConstant extends Constant implements ClassConstants , Opcodes {
45
44
46
45
final int value ;
@@ -250,7 +249,9 @@ class PyCodeConstant extends Constant implements ClassConstants, Opcodes {
250
249
final String co_name ;
251
250
final int argcount ;
252
251
final int kwonlyargcount ;
252
+ final List <String > varnames ;
253
253
final List <String > names ;
254
+ final List <PythonTree > constants ;
254
255
final int id ;
255
256
final int co_firstlineno ;
256
257
final boolean arglist , keywordlist ;
@@ -304,11 +305,13 @@ class PyCodeConstant extends Constant implements ClassConstants, Opcodes {
304
305
305
306
// !classdef only
306
307
if (!classBody ) {
307
- names = toNameAr (scope .names , false );
308
+ varnames = toNameAr (scope .names , false );
308
309
} else {
309
- names = null ;
310
+ varnames = null ;
310
311
}
311
312
313
+ constants = scope .constants ;
314
+ names = toNameAr (scope .globalNames , true );
312
315
cellvars = toNameAr (scope .cellvars , true );
313
316
freevars = toNameAr (scope .freevars , true );
314
317
jy_npurecell = scope .jy_npurecell ;
@@ -371,15 +374,15 @@ void put(Code c) throws IOException {
371
374
module .classfile .addField (name , ci (PyCode .class ), access );
372
375
c .iconst (argcount );
373
376
374
- // Make all names
375
- int nameArray ;
376
- if (names != null ) {
377
- nameArray = CodeCompiler .makeStrings (c , names );
377
+ // Make all var names
378
+ int varNameArr ;
379
+ if (varnames != null ) {
380
+ varNameArr = CodeCompiler .makeStrings (c , varnames );
378
381
} else { // classdef
379
- nameArray = CodeCompiler .makeStrings (c , null );
382
+ varNameArr = CodeCompiler .makeStrings (c , null );
380
383
}
381
- c .aload (nameArray );
382
- c .freeLocal (nameArray );
384
+ c .aload (varNameArr );
385
+ c .freeLocal (varNameArr );
383
386
c .aload (1 );
384
387
c .ldc (co_name );
385
388
c .iconst (co_firstlineno );
@@ -406,6 +409,19 @@ void put(Code c) throws IOException {
406
409
c .aconst_null ();
407
410
}
408
411
412
+ if (names != null ) {
413
+ int strArray = CodeCompiler .makeStrings (c , names );
414
+ c .aload (strArray );
415
+ c .freeLocal (strArray );
416
+ } else {
417
+ c .aconst_null ();
418
+ }
419
+ if (constants != null ) {
420
+ int constArr = module .makeConstArray (c , constants );
421
+ c .aload (constArr );
422
+ c .freeLocal (constArr );
423
+ }
424
+
409
425
c .iconst (jy_npurecell );
410
426
c .iconst (kwonlyargcount );
411
427
c .iconst (moreflags );
@@ -415,7 +431,8 @@ void put(Code c) throws IOException {
415
431
"newCode" ,
416
432
sig (PyCode .class , Integer .TYPE , String [].class , String .class , String .class ,
417
433
Integer .TYPE , Boolean .TYPE , Boolean .TYPE , PyFunctionTable .class ,
418
- Integer .TYPE , String [].class , String [].class , Integer .TYPE , Integer .TYPE , Integer .TYPE ));
434
+ Integer .TYPE , String [].class , String [].class , String [].class , PyObject [].class ,
435
+ Integer .TYPE , Integer .TYPE , Integer .TYPE ));
419
436
c .putstatic (module .classfile .name , name , ci (PyCode .class ));
420
437
}
421
438
}
@@ -479,6 +496,26 @@ private Constant findConstant(Constant c) {
479
496
return ret ;
480
497
}
481
498
499
+ Constant constant (PythonTree node ) {
500
+ if (node instanceof Num ) {
501
+ PyObject n = (PyObject ) ((Num ) node ).getInternalN ();
502
+ if (n instanceof PyLong ) {
503
+ return longConstant (n .__str__ ().toString ());
504
+ } else if (n instanceof PyFloat ) {
505
+ return floatConstant (((PyFloat ) n ).getValue ());
506
+ } else if (n instanceof PyComplex ) {
507
+ return complexConstant (((PyComplex )n ).imag );
508
+ }
509
+ } else if (node instanceof Str ) {
510
+ PyUnicode s = (PyUnicode )((Str ) node ).getInternalS ();
511
+ return unicodeConstant (s .asString ());
512
+ } else if (node instanceof Bytes ) {
513
+ String s = ((Bytes ) node ).getInternalS ();
514
+ return stringConstant (s );
515
+ }
516
+ throw new RuntimeException ("unexpected constant: " + node .toString ());
517
+ }
518
+
482
519
Constant integerConstant (int value ) {
483
520
return findConstant (new PyIntegerConstant (value ));
484
521
}
@@ -660,6 +697,37 @@ public void error(String msg, boolean err, PythonTree node) throws Exception {
660
697
throw new ParseException (msg , node );
661
698
}
662
699
700
+ public int makeConstArray (Code code , java .util .List <? extends PythonTree > nodes ) throws IOException {
701
+ final int n ;
702
+
703
+ if (nodes == null ) {
704
+ n = 0 ;
705
+ } else {
706
+ n = nodes .size ();
707
+ }
708
+
709
+ int array = code .getLocal (ci (PyObject [].class ));
710
+ if (n == 0 ) {
711
+ code .getstatic (p (Py .class ), "EmptyObjects" , ci (PyObject [].class ));
712
+ code .astore (array );
713
+ } else {
714
+ code .iconst (n );
715
+ code .anewarray (p (PyObject .class ));
716
+ code .astore (array );
717
+
718
+ for (int i = 0 ; i < n ; i ++) {
719
+ constant (nodes .get (i )).get (code );
720
+ code .aload (array );
721
+ code .swap ();
722
+ code .iconst (i );
723
+ code .swap ();
724
+ code .aastore ();
725
+ }
726
+ }
727
+ return array ;
728
+ }
729
+
730
+
663
731
public static void compile (mod node , OutputStream ostream , String name , String filename ,
664
732
boolean linenumbers , boolean printResults , CompilerFlags cflags ) throws Exception {
665
733
compile (node , ostream , name , filename , linenumbers , printResults , cflags ,
0 commit comments