Nice/src/bossa/syntax niceclass.nice,1.23,1.24 enum.nice,1.17,1.18 defaultconstructor.nice,1.5,1.6
Daniel Bonniot <[email protected]>
| Newsgroups | gmane.comp.lang.nice.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/nice/Nice/src/bossa/syntax
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27179/src/bossa/syntax
Modified Files:
niceclass.nice enum.nice defaultconstructor.nice
Log Message:
Make sure that constructors with defaults omitted are compiled first so they
get unmangled names, in case they clash with ones with all values.
Cleaned up DefaultConstructor by creating a class CompiledConstructor to
handle the details of bytecode generation.
Index: defaultconstructor.nice
===================================================================
RCS file: /cvsroot/nice/Nice/src/bossa/syntax/defaultconstructor.nice,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** defaultconstructor.nice 13 Jan 2005 14:06:15 -0000 1.5
--- defaultconstructor.nice 1 Mar 2005 17:36:36 -0000 1.6
***************
*** 30,46 ****
?MethodDeclaration parent;
! /** Call the constructor, with all the arguments. */
! private ?gnu.expr.Expression initialize = null;
! /** Call the constructor, with all the arguments, with an implicit this argument. */
! private ?gnu.expr.Expression initializeFromConstructor = null;
! /** Call the constructor, with only non-default arguments. */
! private ?gnu.expr.Expression initializeOmitDefaults = null;
! /** Instantiate the class, calling the constructor with all the arguments. */
! private ?gnu.expr.Expression instantiate = null;
getInitializationCode(implicitThis)
{
this.getCode();
! return notNull(initializeFromConstructor);
}
--- 30,40 ----
?MethodDeclaration parent;
! private CompiledConstructor compiledFull = cast(null);
! private ?CompiledConstructor compiledMini = null;
getInitializationCode(implicitThis)
{
this.getCode();
! return notNull(compiledFull.initialization);
}
***************
*** 49,124 ****
this.getCode();
return
! // lambdaOmitDefaults is null if the two versions are identical
! omitDefaults && initializeOmitDefaults != null
! ? notNull(initializeOmitDefaults) : notNull(initialize);
}
! computeCode()
{
! if (classe.getDefinition().inInterfaceFile())
! throw new Error("Constructors are loaded from the compiled package");
! this.createBytecode(true);
! this.createBytecode(false);
! return notNull(instantiate);
}
! /**
! @param omitDefaults if true, do not take the value of fields with
! default values as parameters, but use that default instead.
! */
! private void createBytecode(boolean omitDefaults)
{
! gnu.bytecode.ClassType thisType = cast(this.javaReturnType());
! let thisDecl = new gnu.expr.Declaration("this");
! thisDecl.setType(thisType);
! let thisExp = new gnu.expr.ThisExp(thisDecl);
!
! let fullArgs = notNull(parameters).getMonoSymbols();
! let fullArgTypes = this.javaArgTypes();
!
! List<MonoSymbol> args = new LinkedList();
! List<gnu.bytecode.Type> argTypes = new LinkedList();
!
! for (int i = 0; i < notNull(parameters).size; i++)
! {
! if (omitDefaults && notNull(parameters).hasDefaultValue(i))
! continue;
!
! args.add(fullArgs[i]);
! argTypes.add(fullArgTypes[i]);
! }
!
! // Do not create a second constructor omiting defaults if there is
! // no default to omit!
! if (omitDefaults && args.size() == fullArgs.length)
! return;
! let argTypesArray = argTypes.toArray();
! let argsArray = args.toArray();
! let lambda = generateConstructor
! (thisDecl, argTypesArray, argsArray);
! lambda.setSuperCall(this.callSuper(thisExp, fullArgs, omitDefaults));
! nice.tools.code.Gen.setMethodBody(lambda, this.body(thisExp, fullArgs, omitDefaults));
! classe.getClassExp().addMethod(lambda);
! if (! omitDefaults)
! {
! initialize = new gnu.expr.QuoteExp(new gnu.expr.InitializeProc(lambda));
! initializeFromConstructor = new gnu.expr.QuoteExp(new gnu.expr.InitializeProc(lambda, true));
! instantiate = new gnu.expr.QuoteExp(new gnu.expr.InstantiateProc(lambda));
! // Add attributes useful for the nice compiler. These are not needed
! // for the version omitting defaults, since that one is only there for
! // Java users' sake.
! lambda.addBytecodeAttribute(notNull(parameters).asBytecodeAttribute());
! lambda.addBytecodeAttribute(new gnu.bytecode.MiscAttr("default"));
! }
! else
! {
! initializeOmitDefaults = new gnu.expr.QuoteExp(new gnu.expr.InitializeProc(lambda));
! }
}
--- 43,86 ----
this.getCode();
return
! // compiledMini is null if the two versions are identical
! omitDefaults && compiledMini != null
! ? notNull(compiledMini).invoke : compiledFull.invoke;
}
! void createFirstPass()
{
! // We want to create bytecode methods in two passes to guarantee a
! // consistent behaviour in case versions with and without defaults omitted
! // clash.
! // Create the full version first. At the moment class methods are created
! // in reverse order, so they don't get the priority for unmangled names.
! compiledFull = new CompiledConstructor(constructor: this);
! compiledFull.createMethod(false);
}
! computeCode()
{
! if (classe.getDefinition().inInterfaceFile())
! throw new Error("Constructors are loaded from the compiled package");
! compiledMini = new CompiledConstructor(constructor: this).createMethod(true);
! // Add attributes useful for the nice compiler. These are not needed
! // for the version omitting defaults, since that one is only there for
! // Java users' sake.
! compiledFull.lambda.addBytecodeAttribute(notNull(parameters).asBytecodeAttribute());
! compiledFull.lambda.addBytecodeAttribute(new gnu.bytecode.MiscAttr("default"));
! return notNull(compiledFull.instantiate);
! }
! compile()
! {
! this.getCode();
! if (compiledMini != null)
! notNull(compiledMini).compileBody(true);
! compiledFull.compileBody(false);
}
***************
*** 180,181 ****
--- 142,226 ----
(new gnu.expr.InitializeProc(
notNull(gnu.bytecode.Type.pointer_type).getDeclaredMethod("<init>", 0)));
+
+ /**
+ A wrapper for a bytecode version of this constructor.
+
+ One instance of this class is used to hold the version with all parameters,
+ another one holds the version where fields with default values are omitted.
+ */
+ private class CompiledConstructor
+ {
+ DefaultConstructor constructor;
+
+ /** Call the constructor. */
+ private gnu.expr.Expression invoke = cast(null);
+
+ /** Call the constructor with an implicit this argument. */
+ private ?gnu.expr.Expression initialization = null;
+
+ /** Instantiate the class then call the constructor. */
+ private ?gnu.expr.Expression instantiate = null;
+
+ // Things that need to be remembered from the method constructor
+ // to the compilation of the body.
+
+ gnu.expr.ConstructorExp lambda = cast(null);
+
+ private MonoSymbol[] fullArgs = cast(null);
+
+ /**
+ @param omitDefaults if true, do not take the value of fields with
+ default values as parameters, but use that default instead.
+ */
+ private ?CompiledConstructor createMethod(boolean omitDefaults)
+ {
+ gnu.bytecode.ClassType thisType = cast(constructor.javaReturnType());
+ let thisDecl = new gnu.expr.Declaration("this");
+ thisDecl.setType(thisType);
+
+ let parameters = constructor.parameters;
+
+ fullArgs = notNull(parameters).getMonoSymbols();
+ let fullArgTypes = constructor.javaArgTypes();
+
+ List<MonoSymbol> args = new LinkedList();
+ List<gnu.bytecode.Type> argTypes = new LinkedList();
+
+ for (int i = 0; i < notNull(parameters).size; i++)
+ {
+ if (omitDefaults && notNull(parameters).hasDefaultValue(i))
+ continue;
+
+ args.add(fullArgs[i]);
+ argTypes.add(fullArgTypes[i]);
+ }
+
+ // Do not create a second constructor omiting defaults if there is
+ // no default to omit!
+ if (omitDefaults && args.size() == fullArgs.length)
+ return null;
+
+ lambda = generateConstructor(thisDecl, argTypes.toArray(), args.toArray());
+ constructor.classe.getClassExp().addMethod(lambda);
+
+ invoke = new gnu.expr.QuoteExp(new gnu.expr.InitializeProc(lambda));
+
+ if (! omitDefaults)
+ {
+ initialization = new gnu.expr.QuoteExp(new gnu.expr.InitializeProc(lambda, true));
+ instantiate = new gnu.expr.QuoteExp(new gnu.expr.InstantiateProc(lambda));
+ }
+
+ return this;
+ }
+
+ private void compileBody(boolean omitDefaults)
+ {
+ let thisExp = new gnu.expr.ThisExp(lambda.getThisDecl());
+
+ lambda.setSuperCall(constructor.callSuper(thisExp, fullArgs, omitDefaults));
+
+ nice.tools.code.Gen.setMethodBody
+ (lambda, constructor.body(thisExp, fullArgs, omitDefaults));
+ }
+ }
Index: niceclass.nice
===================================================================
RCS file: /cvsroot/nice/Nice/src/bossa/syntax/niceclass.nice,v
retrieving revision 1.23
retrieving revision 1.24
diff -C2 -d -r1.23 -r1.24
*** niceclass.nice 28 Feb 2005 14:00:58 -0000 1.23
--- niceclass.nice 1 Mar 2005 17:36:36 -0000 1.24
***************
*** 47,51 ****
/** List of symbols for calling constructors of this class. */
private List<MethodSymbol> constructors = new ArrayList();
! private Constructor[?] constructorMethod = null;
// Used to resolve fields, and constructor constraint.
--- 47,51 ----
/** List of symbols for calling constructors of this class. */
private List<MethodSymbol> constructors = new ArrayList();
! private DefaultConstructor[?] constructorMethod = null;
// Used to resolve fields, and constructor constraint.
***************
*** 559,563 ****
cst = mlsub.typing.Constraint.True;
! constructorMethod = cast(new Constructor[allConstructorParams.size()]);
for (int i = 0; i < allConstructorParams.size(); i++)
{
--- 559,563 ----
cst = mlsub.typing.Constraint.True;
! constructorMethod = cast(new DefaultConstructor[allConstructorParams.size()]);
for (int i = 0; i < allConstructorParams.size(); i++)
{
***************
*** 597,600 ****
--- 597,608 ----
for (field : fields)
field.createField();
+
+ // Creating constructor methods needs to be done even if we don't recompile
+ // since classes are always regenerated.
+ // We want to do it in two passes to guarantee a consistent behaviour
+ // in case versions with and without defaults omitted clash.
+ if (constructorMethod != null)
+ for (cm : notNull(constructorMethod))
+ cm.createFirstPass();
}
***************
*** 614,618 ****
if (constructorMethod != null)
for (cm : notNull(constructorMethod))
! cm.getCode();
// Take into account external interface implementations, which
--- 622,626 ----
if (constructorMethod != null)
for (cm : notNull(constructorMethod))
! cm.compile();
// Take into account external interface implementations, which
Index: enum.nice
===================================================================
RCS file: /cvsroot/nice/Nice/src/bossa/syntax/enum.nice,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -d -r1.17 -r1.18
*** enum.nice 16 Jan 2005 21:51:15 -0000 1.17
--- enum.nice 1 Mar 2005 17:36:36 -0000 1.18
***************
*** 55,58 ****
--- 55,60 ----
for (symbol : symbols)
symbol.compileValue();
+
+ classDef.compile();
}
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click