This is the mail archive of the
kawa@sources.redhat.com
mailing list for the Kawa project.
Re: define-simple-class and Java constructors
- From: Vladimir Tsichevski <wowa at jet dot msk dot su>
- To: Per Bothner <per at bothner dot com>
- Cc: kawa at sources dot redhat dot com
- Date: Mon, 19 May 2003 12:52:35 +0400
- Subject: Re: define-simple-class and Java constructors
- References: <3E746437.1010901@online.ru> <3EC6C9E0.5040500@bothner.com>
Per Bothner wrote:
Vladimir Tsichevski wrote:
I've added to kawa (see attachement) a new built-in primitive syntax
`primitive-super-method', so, for example,
the following scheme declaration:
Sorry for sitting on this so long. I took a look at this.
Though I would rather have a higher-level invoke-style interface,
I'm willing to check in your patch (with a few changes).
However, you didn't send a patch, but new versions of the files.
Now I'm sending the diff against the todays CVS
Worse, they are re-indented and in places re-formatted.
I managed to tune my Emacs to use same two-character indent as in kawa
sources. So the patch
list only significant differences
This
makes applying the patch more difficult than I care for.
A few more words about the content of the patch. Not only it adds the
call-super functionality, it fixes also
the following:
- using jikes requires the JRE runtime jars explicitly specified:
Make-rules, configure.in, testsuite/Makefile.am
- unable to derive one kawa module from another (the apply0 module proc
made non-final): gnu/expr/Compilation.java
Regards,
Vladimir
Index: Make-rules
===================================================================
RCS file: /cvs/kawa/kawa/Make-rules,v
retrieving revision 1.15
diff -r1.15 Make-rules
4,5c4,5
< JAVACFLAGS =
< CLASSPATH_ENV = CLASSPATH=$(JAVAROOT)@pathsep@$(srcdir)@filesep@$(JAVAROOT)@pathsep@$$CLASSPATH
---
> JAVACFLAGS = -source 1.4
> CLASSPATH_ENV = CLASSPATH=$(JAVAROOT)@pathsep@$(srcdir)@filesep@$(JAVAROOT)@pathsep@$$CLASSPATH:@JAVART@
Index: configure.in
===================================================================
RCS file: /cvs/kawa/kawa/configure.in,v
retrieving revision 1.100
diff -r1.100 configure.in
22a23,28
> AC_ARG_WITH(jikes,
> [ --with-jikes Compile Kawa using jikes (IBM Compiler for Java)])
>
> AC_ARG_WITH(javart,
> [ --with-java-runtime Java runtime libraries (required for jikes)])
>
38c44
< [ --with-sax2 Assume AWT is available])
---
> [ --with-sax2 Assume SAX is available])
59a66,91
>
> if test "${with_jikes}" = yes ; then
> JAVAC=jikes
> if test -n "$with-java-runtime" ; then
> JAVART=$with_java_runtime
> else
> JAVART=$JAVA_HOME/jre/lib/rt.jar
> fi
> if ! test -f "$JAVART" ; then
> AC_MSG_ERROR([
> ***
> Use --with-java-runtime option to specify path to standard Java
> library. This must be explicitly specified in order to compile kawa
> with jikes compiler. For example:
>
> ./configure --with-jikes --with-java-runtime=/usr/java/jre/lib/rt.jar
> ***
> ])
> fi
>
> AC_PATH_PROG(jikes, jikes)
> if test -n "$jikes"; then
> JAVAC=$jikes
> fi
> fi
> AC_SUBST(JAVART)
Index: gnu/expr/Compilation.java
===================================================================
RCS file: /cvs/kawa/kawa/gnu/expr/Compilation.java,v
retrieving revision 1.85
diff -r1.85 Compilation.java
179c179
< ("apply0", apply0args, typeObject, Access.PUBLIC|Access.FINAL);
---
> ("apply0", apply0args, typeObject, Access.PUBLIC /*|Access.FINAL */);
1422c1422
< Access.PUBLIC|Access.FINAL);
---
> Access.PUBLIC /* |Access.FINAL */);
Index: gnu/expr/LambdaExp.java
===================================================================
RCS file: /cvs/kawa/kawa/gnu/expr/LambdaExp.java,v
retrieving revision 1.75
diff -r1.75 LambdaExp.java
431a432
>
Index: gnu/expr/PrimProcedure.java
===================================================================
RCS file: /cvs/kawa/kawa/gnu/expr/PrimProcedure.java,v
retrieving revision 1.35
diff -r1.35 PrimProcedure.java
22,24c22
<
< public final int opcode() { return op_code; }
<
---
>
27c25
<
---
>
129,130c127
< boolean is_constructor = op_code == 183;
<
---
>
139c136
< if (is_constructor)
---
> if (isConstructor())
144,145c141,142
< Object[] rargs = (Object[]) ctx.value2;
< if (is_constructor)
---
> Object[] rargs = (Object[]) ctx.value2;
> if (isConstructor())
159,188c156
<
< public PrimProcedure(java.lang.reflect.Method method,
< Class thisClass, Class[] parameterClasses,
< Interpreter interpreter)
< {
< Type[] parameterTypes = new Type[parameterClasses.length];
< Type[] implParameterTypes = new Type[parameterClasses.length];
< for (int i = parameterClasses.length; --i >= 0; )
< {
< Type ptype = interpreter.getTypeFor(parameterClasses[i]);
< parameterTypes[i] = ptype;
< implParameterTypes[i] = ptype.getImplementationType();
< }
< Type returnType = interpreter.getTypeFor(method.getReturnType());
< Type implReturnType = returnType.getImplementationType();
< ClassType thisType = (ClassType) interpreter.getTypeFor(thisClass);
< Method meth = thisType.addMethod(method.getName(), method.getModifiers(),
< implParameterTypes, implReturnType);
< init(meth);
< argTypes = parameterTypes;
< retType = op_code == 183 ? meth.getDeclaringClass() : returnType;
< }
<
< public PrimProcedure(java.lang.reflect.Method method,
< Interpreter interpreter)
< {
< this(method, method.getDeclaringClass(),
< method.getParameterTypes(), interpreter);
< }
<
---
>
191c159,174
< init(method);
---
> this.method = method;
> this.argTypes = method.getParameterTypes();
> this.retType = method.getReturnType();
> int flags = method.getModifiers();
> if ((flags & Access.STATIC) != 0)
> this.op_code = 184; // invokestatic
> else
> {
> ClassType mclass = method.getDeclaringClass();
> if ((mclass.getModifiers() & Access.INTERFACE) != 0)
> this.op_code = 185; // invokeinterface
> else if (isConstructor())
> this.op_code = 183; // invokespecial
> else
> this.op_code = 182; // invokevirtual
> }
196,197c179,180
< init(method);
<
---
> this(method);
>
219c202,203
< retType = op_code == 183 ? method.getDeclaringClass() :
---
> retType = isConstructor() ?
> method.getDeclaringClass() :
222,255c206,210
<
< private void init(Method method)
< {
< this.method = method;
< this.argTypes = method.getParameterTypes();
< this.retType = method.getReturnType();
< int flags = method.getModifiers();
< if ((flags & Access.STATIC) != 0)
< this.op_code = 184; // invokestatic
< else
< {
< ClassType mclass = method.getDeclaringClass();
< if ((mclass.getModifiers() & Access.INTERFACE) != 0)
< this.op_code = 185; // invokeinterface
< else if ("<init>".equals(method.getName()))
< this.op_code = 183; // invokespecial
< else
< this.op_code = 182; // invokevirtual
< }
< }
<
< public PrimProcedure(Method method, LambdaExp source)
< {
< this(method);
< this.source = source;
< }
<
< public PrimProcedure(int opcode, Type retType, Type[] argTypes)
< {
< this.op_code = opcode;
< this.retType = retType;
< this.argTypes= argTypes;
< }
<
---
>
> /**
> * Convenience procedure used in AddOp.java to create binary
> * operations
> */
262c217
< return new PrimProcedure(opcode, type, args);
---
> return new PrimProcedure(opcode, null, type, args);
264,265c219,220
<
< public PrimProcedure(int op_code, ClassType classtype, String name,
---
>
> public PrimProcedure(int op_code, Method method,
269,270c224
< method = classtype.addMethod (name, op_code == 184 ? Access.STATIC : 0,
< argTypes, retType);
---
> this.method = method;
274,279c228,230
<
< /** Use to compile new followed by constructor. */
< public PrimProcedure(ClassType classtype, Type[] argTypes)
< {
< this(183, classtype, "<init>", Type.void_type, argTypes);
< this.retType = classtype;
---
>
> private final boolean isConstructor() {
> return method != null && "<init>".equals(method.getName());
284c235
< return method == null || method.getStaticFlag() || op_code == 183;
---
> return method == null || method.getStaticFlag() || isConstructor();
366,372c317,322
<
< if (opcode() == 183) // invokespecial == primitive-constructor
< {
< code.emitNew(mclass);
< code.emitDup(mclass);
< }
<
---
>
> if (isConstructor()) { // invokespecial == primitive-constructor
> code.emitNew(mclass);
> code.emitDup(mclass);
> }
>
388c338
< code.emitPrimop (opcode(), args.length, retType);
---
> code.emitPrimop (op_code, args.length, retType);
390c340
< code.emitInvokeMethod(method, opcode());
---
> code.emitInvokeMethod(method, op_code);
Index: kawa/standard/Scheme.java
===================================================================
RCS file: /cvs/kawa/kawa/kawa/standard/Scheme.java,v
retrieving revision 1.135
diff -r1.135 Scheme.java
432c432
< new kawa.standard.prim_method(182));
---
> kawa.standard.prim_method.createVirtual());
434c434
< new kawa.standard.prim_method(184));
---
> kawa.standard.prim_method.createStatic());
436c436
< new kawa.standard.prim_method(185));
---
> kawa.standard.prim_method.createInterface());
438,439c438,440
< new kawa.standard.prim_method(183));
< define_syntax("primitive-op1", new kawa.standard.prim_method());
---
> kawa.standard.prim_method.createConstructor());
> define_syntax("primitive-super-method",
> kawa.standard.prim_method.createSuper());
Index: kawa/standard/prim_method.java
===================================================================
RCS file: /cvs/kawa/kawa/kawa/standard/prim_method.java,v
retrieving revision 1.17
diff -r1.17 prim_method.java
14a15
> // 183: (primitive-super-method "class" "method" "rettype" ("argtype" ...))
18,28c19,20
< static private Pattern pattern2 = new ListPat (2);
< static private Pattern pattern3 = new ListPat (3);
< static private Pattern pattern4 = new ListPat (4);
<
< int op_code;
<
< int opcode () { return op_code; }
<
< public prim_method (int opcode)
< {
< op_code = opcode;
---
> public static prim_method createVirtual(){
> return new prim_method(182);
30,32c22,26
<
< public prim_method ()
< {
---
>
> public static prim_method createConstructor(){
> prim_method result = new prim_method(183);
> result.isConstructor = true;
> return result;
34c28,40
<
---
>
> public static prim_method createStatic(){
> return new prim_method(184);
> }
>
> public static prim_method createInterface(){
> return new prim_method(185);
> }
>
> public static prim_method createSuper(){
> return new prim_method(183);
> }
>
54,59c60,64
< if (! (op_code == 0 ? pattern3.match(obj, match, 1)
< : op_code == 183 ? pattern2.match(obj, match, 2) // constructor
< : pattern4.match(obj, match, 0))) // virtual or static
< return tr.syntaxError ("wrong number of arguments to "+getName()
< +"(opcode:"+op_code+")");
<
---
> if (! (isConstructor ? pattern2.match(obj, match, 2) // constructor
> : pattern4.match(obj, match, 0))) // virtual or super or static
> return tr.syntaxError ("wrong number of arguments to " + getName()
> +"(opcode:" + opcode + ")");
>
74c79,91
< if (op_code == 0)
---
> ClassType cl = null;
> Type ctype;
> int carg;
> if (isConstructor) {
> carg = 2;
> ctype = rtype;
> }
> else {
> carg = 0;
> ctype = exp2Type(match[0], tr);
> }
>
> try
76,77c93,94
< int opcode = ((Number)(match[1])).intValue();
< proc = new PrimProcedure(opcode, rtype, args);
---
> cl = (ClassType) ctype;
> cl.getReflectClass();
79c96
< else
---
> catch (Exception ex)
81,123c98,106
< ClassType cl = null;
< Type ctype;
< int carg;
< if (op_code == 183)
< {
< carg = 2;
< ctype = rtype;
< }
< else
< {
< carg = 0;
< ctype = exp2Type(match[0], tr);
< }
< try
< {
< cl = (ClassType) ctype;
< cl.getReflectClass();
< }
< catch (Exception ex)
< {
< char code;
< if (cl == null)
< code = 'e';
< else
< {
< code = 'w';
< ((ClassType) cl).setExisting(false);
< }
< tr.error(code, "unknown class: " + match[carg]);
< }
< if (op_code == 183) // primitive-constructor
< {
< proc = new PrimProcedure(cl, args);
< }
< else
< {
< Pair p;
< if (match[1] instanceof Pair
< && (p = (Pair) match[1]).car == "quote")
< match[1] = ((Pair) p.cdr).car;
< proc = new PrimProcedure(op_code, cl,
< match[1].toString(), rtype, args);
< }
---
> char code;
> if (cl == null)
> code = 'e';
> else
> {
> code = 'w';
> ((ClassType) cl).setExisting(false);
> }
> tr.error(code, "unknown class: " + match[carg]);
124a108,128
> if (isConstructor)
> proc = new PrimProcedure(183,
> cl.addMethod ("<init>", 0, args, Type.void_type),
> cl,
> args
> );
> else {
> Pair p;
> if (match[1] instanceof Pair
> && (p = (Pair) match[1]).car == "quote")
> match[1] = ((Pair) p.cdr).car;
> proc = new PrimProcedure
> (opcode,
> cl.addMethod
> (match[1].toString(),
> opcode == 184 ? Access.STATIC : 0,
> args,
> rtype),
> rtype,
> args);
> }
125a130,143
> }
>
> // Private
>
> static private Pattern pattern2 = new ListPat (2);
> static private Pattern pattern3 = new ListPat (3);
> static private Pattern pattern4 = new ListPat (4);
>
>
> private int opcode;
> private boolean isConstructor = false;
>
> private prim_method (int opcode) {
> this.opcode = opcode;
Index: testsuite/Makefile.am
===================================================================
RCS file: /cvs/kawa/kawa/testsuite/Makefile.am,v
retrieving revision 1.42
diff -r1.42 Makefile.am
90c90
< CLASSPATH=..:. $(JAVAC) -g $(srcdir)/SimpleB.java -d .
---
> CLASSPATH=..:.:@JAVART@ $(JAVAC) -g $(srcdir)/SimpleB.java -d .
135c135
< CLASSPATH=..:. $(JAVAC) -g $(srcdir)/MySAXApp.java -d .
---
> CLASSPATH=..:.:@JAVART@ $(JAVAC) -g $(srcdir)/MySAXApp.java -d .
145c145
< CLASSPATH=..:. $(JAVAC) -g -d . $?
---
> CLASSPATH=..:.:@JAVART@ $(JAVAC) -g -d . $?