public inbox for kawa@sourceware.org
 help / color / mirror / Atom feed
* Google Summer of Code
@ 2014-03-05  8:43 Andrea Bernardini
  2014-03-05 10:15 ` Charles Turner
  0 siblings, 1 reply; 27+ messages in thread
From: Andrea Bernardini @ 2014-03-05  8:43 UTC (permalink / raw)
  To: kawa

Hi, 
I'm a student at Politecnico di Milano [1] (Milan, Italy), at the
second year of the Engineering Of Computing Systems MSc. I'd like to
apply for the Google Summer of Code, so I'm writing here to ask some
questions about KAWA project ideas.  

I'm looking for a project that can make me learn how a real compiler
works. I have a course in the second semester regarding compiler
construction [2], and the opportunity to get course credit developing a
GSoC project.

I have only basic knowledge in formal languages, compilers and low
level architectures, and no experience in compilers development, so I
need to reason about the feasibility of the project. I noticed this
entry in your project ideas page, that you call a fairly small starter
project [3]:

Optimize switches (case)
Implement SwitchExp as a new class extending Expression, and compile it
using the existing gnu.bytecode.SwitchState. Use it to optimize
Scheme’s case form. This might be better done without a new Expression,
but instead using a special Procedure with custom “validation” and
code-generation.

Could it be a reasonable project for a student with few experience in
compilers? 
Is there an other project that could be a good starting point? 

Thanks

Andrea Bernardini

[1] http://www.polimi.it/en/english-version/
[2] http://bit.ly/1jHIKZH
[3] http://www.gnu.org/software/kawa/Ideas-and-tasks.html

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-03-05  8:43 Google Summer of Code Andrea Bernardini
@ 2014-03-05 10:15 ` Charles Turner
  2014-03-05 12:23   ` Andrea Bernardini
  0 siblings, 1 reply; 27+ messages in thread
From: Charles Turner @ 2014-03-05 10:15 UTC (permalink / raw)
  To: kawa

Hi Andrea,

On 05/03/14 08:42, Andrea Bernardini wrote:
> I have only basic knowledge in formal languages, compilers and low
> level architectures, and no experience in compilers development, so I
> need to reason about the feasibility of the project.

Depending on which project you select, compiler knowledge required 
varies. But again, the more you know, the better! The project you 
enquired about could have an element of code generation to it, and a 
basic understanding of computer architecture won't hurt in understanding 
how to use it. You can look at the methods in gnu.bytecode.CodeAttr to 
get a feel for the level abstraction we're working with in Kawa. You 
certainly don't need to know any micro-architectural details, if that's 
what you meant by "low-level", the JVM takes care of that. :-)

As far as formal languages go, perhaps the only things I can imagine you 
coming across are regular (sic) expressions and grammars, but again, 
nothing spectacular.

> Optimize switches (case)
> Implement SwitchExp as a new class extending Expression, and compile it
> using the existing gnu.bytecode.SwitchState. Use it to optimize
> Scheme’s case form. This might be better done without a new Expression,
> but instead using a special Procedure with custom “validation” and
> code-generation.
>
> Could it be a reasonable project for a student with few experience in
> compilers?

I think a motivated student could accomplish this task, even without 
experience with compliers, as long as they're interested in the topic.

> Is there an other project that could be a good starting point?

It's hard to suggest projects since we're not sure what your personal 
strengths and interests are. To be honest, all the projects would be 
good starting points for the motivated student.

My advice is to pick something that interests you, and dig around the 
code base trying to get a better understanding of what that particular 
project might involve. Don't worry if you get lost, feel free to ask 
questions, someone here will be able to help you!

Kind regards,
Charles.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-03-05 10:15 ` Charles Turner
@ 2014-03-05 12:23   ` Andrea Bernardini
  2014-03-05 20:29     ` Per Bothner
  2014-03-05 21:46     ` Helmut Eller
  0 siblings, 2 replies; 27+ messages in thread
From: Andrea Bernardini @ 2014-03-05 12:23 UTC (permalink / raw)
  To: kawa

On Wed, 05 Mar 2014 10:15:50 +0000
Charles Turner <chturne@gmail.com> wrote:

> It's hard to suggest projects since we're not sure what your personal 
> strengths and interests are. To be honest, all the projects would be 
> good starting points for the motivated student.
> 
> My advice is to pick something that interests you, and dig around the 
> code base trying to get a better understanding of what that
> particular project might involve. Don't worry if you get lost, feel
> free to ask questions, someone here will be able to help you!

Thank you, I will start looking at the code. I also found on the
website the documentation about the internals of Kawa, that should be
useful. I will ask here if I have questions.

I'm really interested in programming languages implementation, the
problem here at polimi is that we see a lot of theory, but we rarely
use it to develop real applications. 

To be more clear about my previous knowledge, these are some topics I
studied in some of my courses: 

Formal languages
regular expressions, context-free grammars, grammars of regular
languages, syntax trees, context-free languages, finite deterministic
and non-deterministic automata, pushdown automata, semantic functions
and attribute grammars.

Programming Language Concepts
Variables, Binding, Scoping, Parameter Passing, Types, Pattern
Matching, Functional programming, Logic Programming...

Architectures
Basics of RISC/MIPS architecture, pipelining, structural, control and
data hazards, branch prediction techniques (Static and dynamic branch
prediction),  Instruction level parallelism(static and dynamic
scheduling).

Compilers
Some Flex + Bison

Languages that I used to develop some project:
Java, Python, Haskell, HTML/CSS/Javascript

Languages I played with:
Scheme, C/C++, bash

Best regards

Andrea Bernardini 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-03-05 12:23   ` Andrea Bernardini
@ 2014-03-05 20:29     ` Per Bothner
  2014-03-05 21:46     ` Helmut Eller
  1 sibling, 0 replies; 27+ messages in thread
From: Per Bothner @ 2014-03-05 20:29 UTC (permalink / raw)
  To: Andrea Bernardini, kawa

On 03/05/2014 04:22 AM, Andrea Bernardini wrote:

> Thank you, I will start looking at the code. I also found on the
> website the documentation about the internals of Kawa, that should be
> useful. I will ask here if I have questions.
>
> I'm really interested in programming languages implementation, the
> problem here at polimi is that we see a lot of theory, but we rarely
> use it to develop real applications.
>
> To be more clear about my previous knowledge, these are some topics I
> studied in some of my courses:

What will happen is we will (hopefully) get few students interested in
working on Kawa, and we will get a small number of funded "slots" (maybe
only one).  At that point we will decide on the best match of students
and projects, given our limited number of slots.

Being proactive, studying the code, asking intelligent questions are likely
to increase your changes of getting funded.  Even if you're not, it's not
wasted effort, since studying and maybe contributing to a real non-trivial
code-base is a very useful experience - more valuable long-term than the
actual money.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-03-05 12:23   ` Andrea Bernardini
  2014-03-05 20:29     ` Per Bothner
@ 2014-03-05 21:46     ` Helmut Eller
  2014-03-06 23:45       ` Per Bothner
  1 sibling, 1 reply; 27+ messages in thread
From: Helmut Eller @ 2014-03-05 21:46 UTC (permalink / raw)
  To: kawa

On Wed, Mar 05 2014, Andrea Bernardini wrote:
[...]
> Thank you, I will start looking at the code. I also found on the
> website the documentation about the internals of Kawa, that should be
> useful. I will ask here if I have questions.

For the "Optimize switches" project I would also suggest to read
Clinger's paper "Rapid case dispatch in Scheme" [1].  The paper
describes the kind of optimizations that we, well I, would like to see.
The problem is how to integrate the ideas of the paper into Kawa's
existing infrastructure.

Helmut

[1] http://scheme2006.cs.uchicago.edu/07-clinger.pdf

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-03-05 21:46     ` Helmut Eller
@ 2014-03-06 23:45       ` Per Bothner
  2014-03-07  0:00         ` Jamison Hope
  0 siblings, 1 reply; 27+ messages in thread
From: Per Bothner @ 2014-03-06 23:45 UTC (permalink / raw)
  To: Helmut Eller, kawa

On 03/05/2014 01:45 PM, Helmut Eller wrote:
> On Wed, Mar 05 2014, Andrea Bernardini wrote:
> [...]
>> Thank you, I will start looking at the code. I also found on the
>> website the documentation about the internals of Kawa, that should be
>> useful. I will ask here if I have questions.
>
> For the "Optimize switches" project I would also suggest to read
> Clinger's paper "Rapid case dispatch in Scheme" [1].  The paper
> describes the kind of optimizations that we, well I, would like to see.
> The problem is how to integrate the ideas of the paper into Kawa's
> existing infrastructure.

In addition, we probably want to look at JDK7's switch-on-strings
feature.  Ideally, we'd like to special-case the switch if the expression
is java.lang.String (most likely using the same implementation as Java),
and also special-case java.lang.CharSequence (somewhat trickier).
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-03-06 23:45       ` Per Bothner
@ 2014-03-07  0:00         ` Jamison Hope
  2014-03-16  0:21           ` Andrea Bernardini
  0 siblings, 1 reply; 27+ messages in thread
From: Jamison Hope @ 2014-03-07  0:00 UTC (permalink / raw)
  To: kawa@sourceware.org list

On Mar 6, 2014, at 6:45 PM, Per Bothner <per@bothner.com> wrote:

> On 03/05/2014 01:45 PM, Helmut Eller wrote:
>> On Wed, Mar 05 2014, Andrea Bernardini wrote:
>> [...]
>>> Thank you, I will start looking at the code. I also found on the
>>> website the documentation about the internals of Kawa, that should be
>>> useful. I will ask here if I have questions.
>> 
>> For the "Optimize switches" project I would also suggest to read
>> Clinger's paper "Rapid case dispatch in Scheme" [1].  The paper
>> describes the kind of optimizations that we, well I, would like to see.
>> The problem is how to integrate the ideas of the paper into Kawa's
>> existing infrastructure.
> 
> In addition, we probably want to look at JDK7's switch-on-strings
> feature.  Ideally, we'd like to special-case the switch if the expression
> is java.lang.String (most likely using the same implementation as Java),
> and also special-case java.lang.CharSequence (somewhat trickier).

Also enums!  Basically anything that's valid for a Java switch.

--
Jamison Hope
The PTR Group
www.theptrgroup.com



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-03-07  0:00         ` Jamison Hope
@ 2014-03-16  0:21           ` Andrea Bernardini
  2014-03-17  6:26             ` Per Bothner
  0 siblings, 1 reply; 27+ messages in thread
From: Andrea Bernardini @ 2014-03-16  0:21 UTC (permalink / raw)
  To: kawa

After reading the documentation, I started to inspect the code. Looking
at the implementation of other types of expressions I began to outline
some code, so I would like to ask some questions to know if I am on the
right track. If I understand correctly the problem, we now have case
constructs implemented as Scheme macros in kawa/lib/std_syntax.scm and
we would like to implement them at a lower level (i.e. using Java
bytecode), to make optimizations.

I created a Case class in kawa.lang. It is an abstract class, so we can
generate a specialized matchKey method for each type of key (String,
Enums, etc.):

> public abstract class Case extends Syntax {
> 	
> 	public Pair[] clauses;
> 	
> 	public Object matchKey(Object key) {
> 		return matchKey(key, key.getClass().getName());
> 	}
> 	
> 	/* Check if one of the clauses is equal to the key, 
> 	 * returning the corresponding expression
> 	*/
> 	public abstract Expression matchKey(Object key, String type);
> 	
> 	@Override
> 	public Expression rewrite(Object obj, Translator tr) {//TODO}
> }

Then we need a CaseExp in gnu.expr to perform the actual compilation
using gnu.bytecode.SwitchState:

> public class CaseExp extends Expression {
> 
> 	@Override
> 	protected boolean mustCompile() {return false;}
> 
> 	@Override
> 	public void print(OutPort ps) {//TODO}
> 
> 	@Override
> 	public void compile(Compilation comp, Target target) {//TODO}
> 
> }

Does this make any sense?

What the rewrite method is supposed to do?

An other thing I didn't understand yet is where and how this two classes
should be used in the rest of the code.

Thanks,

Andrea Bernardini

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-03-16  0:21           ` Andrea Bernardini
@ 2014-03-17  6:26             ` Per Bothner
  2014-03-20 19:50               ` Andrea Bernardini
  0 siblings, 1 reply; 27+ messages in thread
From: Per Bothner @ 2014-03-17  6:26 UTC (permalink / raw)
  To: Andrea Bernardini, kawa

On 03/15/2014 05:20 PM, Andrea Bernardini wrote:
> After reading the documentation, I started to inspect the code. Looking
> at the implementation of other types of expressions I began to outline
> some code, so I would like to ask some questions to know if I am on the
> right track. If I understand correctly the problem, we now have case
> constructs implemented as Scheme macros in kawa/lib/std_syntax.scm and
> we would like to implement them at a lower level (i.e. using Java
> bytecode), to make optimizations.

Right.

> I created a Case class in kawa.lang. It is an abstract class, so we can
> generate a specialized matchKey method for each type of key (String,
> Enums, etc.):

That doesn't sound right.  How would you decide which kind of key you
have until you expand it?  In general you may not know until you do
type-inference/-propagation, which happens in the (awkwardly-named)
InlineCalls phase.

> Then we need a CaseExp in gnu.expr to perform the actual compilation
> using gnu.bytecode.SwitchState:

Right - though an alternative may be to do similar to what we do
for TypeSwitch: Represent each case branch as a LambdaExp - which then gets
inlined.  This avoids creating a new Expression type, but it is more
complicated and slightly harder to understand.  However, the TypeSwitch
approach may mesh better with the pattern-matching framework I'm working on.

Perhaps best to focus on implementing a CaseExpr class; we can look
at the TypeSwitch-like LambdaExp approach later.

> What the rewrite method is supposed to do?

It converts the S-Expression (list) case expression into a CaseExp object.

> An other thing I didn't understand yet is where and how this two classes
> should be used in the rest of the code.

You don't actually need a Case Syntax class.  You can create the CaseExp
object directly using Scheme code.  Look at how try-finally (in syntax,scm)
creates a TryExp, or how if (in prim_syntax.scm) creates an IfExp.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-03-17  6:26             ` Per Bothner
@ 2014-03-20 19:50               ` Andrea Bernardini
  2014-03-21  2:56                 ` Per Bothner
  0 siblings, 1 reply; 27+ messages in thread
From: Andrea Bernardini @ 2014-03-20 19:50 UTC (permalink / raw)
  To: kawa

Il giorno Sun, 16 Mar 2014 23:26:08 -0700
Per Bothner <per@bothner.com> ha scritto:

> > I created a Case class in kawa.lang. It is an abstract class, so we
> > can generate a specialized matchKey method for each type of key
> > (String, Enums, etc.):
> 
> That doesn't sound right.  How would you decide which kind of key you
> have until you expand it?  In general you may not know until you do
> type-inference/-propagation, which happens in the (awkwardly-named)
> InlineCalls phase.

Ok, so now I'm wondering if it is possible to use the same concepts
described in "Rapid case dispatch in Scheme" in the compile method of
CaseExp. That is, to use dispatch on the type and index/clause mapping
in Java to generate optimized bytecode.

> 
> > Then we need a CaseExp in gnu.expr to perform the actual compilation
> > using gnu.bytecode.SwitchState:
> 
> Right - though an alternative may be to do similar to what we do
> for TypeSwitch: Represent each case branch as a LambdaExp - which
> then gets inlined.  This avoids creating a new Expression type, but
> it is more complicated and slightly harder to understand.  However,
> the TypeSwitch approach may mesh better with the pattern-matching
> framework I'm working on.
> 
> Perhaps best to focus on implementing a CaseExpr class; we can look
> at the TypeSwitch-like LambdaExp approach later.

I agree.

> 
> > An other thing I didn't understand yet is where and how this two
> > classes should be used in the rest of the code.
> 
> You don't actually need a Case Syntax class.  You can create the
> CaseExp object directly using Scheme code.  Look at how try-finally
> (in syntax,scm) creates a TryExp, or how if (in prim_syntax.scm)
> creates an IfExp.

I came to this:

>public class CaseExp extends Expression {
>	
>	public CaseExp(Expression key, Expression clauses) {
>		System.out.print("Case Expression\n");
>	}
>
>	public CaseExp(Expression key, Expression clauses, 
>			Expression elseClause , Boolean isLambdaForm) {
>		System.out.print("Case Expression with else
>	clause"+...));
>	}

>(define-rewrite-syntax case
>  (lambda (x)
>    (syntax-case x (else =>)
>       ((_ case-key case-clause ... (else => case-else-lambda))
>       (make <it.polimi.kawacase.CaseExp>
>         (syntax->expression (syntax case-key))
>         (syntax->expression (syntax (case-clause ...)))
>         (syntax->expression (syntax case-else-lambda))
>         #t))
>      ((_ case-key case-clause ... (else case-else))
>       (make <it.polimi.kawacase.CaseExp>
>         (syntax->expression (syntax case-key))
>         (syntax->expression (syntax (case-clause ...)))
>         (syntax->expression (syntax case-else))
>         #f))
>      ((_ case-key case-clause ...)
>       (make <it.polimi.kawacase.CaseExp>
>         (syntax->expression (syntax case-key))
>         (syntax->expression (syntax (case-clause ...))))))))

So if i compile this sample code:

>(case 'sym
>  ((sym) (display 1))
>  ((boo) (display 2))
>  (else => (lambda (x)
>             (display 3))))

Kawa prints:

> Case Expression with else clause in lambda form

Am I on the right track? Now I have to study how to generate the
bytecode, obviously at the current state the generated code does
nothing.

Thank you very much for all your answers.

Andrea

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-03-20 19:50               ` Andrea Bernardini
@ 2014-03-21  2:56                 ` Per Bothner
  2014-03-26 10:02                   ` Andrea Bernardini
  2014-03-28 11:14                   ` Andrea Bernardini
  0 siblings, 2 replies; 27+ messages in thread
From: Per Bothner @ 2014-03-21  2:56 UTC (permalink / raw)
  To: Andrea Bernardini, kawa

On 03/20/2014 12:48 PM, Andrea Bernardini wrote:
> Il giorno Sun, 16 Mar 2014 23:26:08 -0700
> Per Bothner <per@bothner.com> ha scritto:
>
>>> I created a Case class in kawa.lang. It is an abstract class, so we
>>> can generate a specialized matchKey method for each type of key
>>> (String, Enums, etc.):
>>
>> That doesn't sound right.  How would you decide which kind of key you
>> have until you expand it?  In general you may not know until you do
>> type-inference/-propagation, which happens in the (awkwardly-named)
>> InlineCalls phase.
>
> Ok, so now I'm wondering if it is possible to use the same concepts
> described in "Rapid case dispatch in Scheme" in the compile method of
> CaseExp. That is, to use dispatch on the type and index/clause mapping
> in Java to generate optimized bytecode.

It is certainly possible, but using a type-specific Case Syntax class
doesn't seem practical.  It's better to do type-specific analysis later.
It may be possible in the Syntax class to partition the clauses depending
on the type of the literal, but I would object to that.  It isn't
extensible, since it would be hard to add new case-like forms with
evaluated expression - I would much rather that any type-based 
classification
be done *after* constant-folding and type propation - i.e. in or
after the InlineCalls phase.

I.e. Case Syntax class should not look at the types of the sub-expressions,
just the syntax, and from that assemble a CaseExp.

>>> An other thing I didn't understand yet is where and how this two
>>> classes should be used in the rest of the code.
>>
>> You don't actually need a Case Syntax class.  You can create the
>> CaseExp object directly using Scheme code.  Look at how try-finally
>> (in syntax,scm) creates a TryExp, or how if (in prim_syntax.scm)
>> creates an IfExp.
>
> I came to this:
>
>> public class CaseExp extends Expression {
>> 	
>> 	public CaseExp(Expression key, Expression clauses) {
>> 		System.out.print("Case Expression\n");
>> 	}
>>
>> 	public CaseExp(Expression key, Expression clauses,
>> 			Expression elseClause , Boolean isLambdaForm) {
>> 		System.out.print("Case Expression with else
>> 	clause"+...));
>> 	}
>
>> (define-rewrite-syntax case
>>   (lambda (x)
>>     (syntax-case x (else =>)
>>        ((_ case-key case-clause ... (else => case-else-lambda))
>>        (make <it.polimi.kawacase.CaseExp>
>>          (syntax->expression (syntax case-key))
>>          (syntax->expression (syntax (case-clause ...)))
>>          (syntax->expression (syntax case-else-lambda))
>>          #t))
>>       ((_ case-key case-clause ... (else case-else))
>>        (make <it.polimi.kawacase.CaseExp>
>>          (syntax->expression (syntax case-key))
>>          (syntax->expression (syntax (case-clause ...)))
>>          (syntax->expression (syntax case-else))
>>          #f))
>>       ((_ case-key case-clause ...)
>>        (make <it.polimi.kawacase.CaseExp>
>>          (syntax->expression (syntax case-key))
>>          (syntax->expression (syntax (case-clause ...))))))))

That's the right basic idea.  However, 'clauses' is not an expression;
it's not a set of expressions.  Perhaps best to try something similar to
how TryExpr contains a set of CatchClauses.

If CaseClause extends LetExp in the same way as CatchClause, then
you can translate '=> expression' as something like
   '(let ((dummy (match ...))) (expression dummy))'


> Am I on the right track? Now I have to study how to generate the
> bytecode, obviously at the current state the generated code does
> nothing.

You're on teh right track, but I suggest introducing a CaseClause type.

-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-03-21  2:56                 ` Per Bothner
@ 2014-03-26 10:02                   ` Andrea Bernardini
  2014-03-28 11:14                   ` Andrea Bernardini
  1 sibling, 0 replies; 27+ messages in thread
From: Andrea Bernardini @ 2014-03-26 10:02 UTC (permalink / raw)
  To: kawa

Il giorno Thu, 20 Mar 2014 19:56:31 -0700
Per Bothner <per@bothner.com> ha scritto:

> On 03/20/2014 12:48 PM, Andrea Bernardini wrote:
> > Il giorno Sun, 16 Mar 2014 23:26:08 -0700
> > Per Bothner <per@bothner.com> ha scritto:
> 
> It is certainly possible, but using a type-specific Case Syntax class
> doesn't seem practical.  

Ok. I'm not using the Case Syntax class any more.

> That's the right basic idea.  However, 'clauses' is not an expression;
> it's not a set of expressions.  Perhaps best to try something similar
> to how TryExpr contains a set of CatchClauses.

Right, that implementation was wrong, as a clause is of the form
((datum*) exp+). 
Now I'm able to create a CaseExp in the Scheme code, containing an
array of CaseClause. Each case clause contains an array of Object
(the datum*) and an Expression (the clause body). 

I also tried to implement the compile method in CaseExp, but i got this
error:

java.lang.Error: popType called with empty stack
at gnu.bytecode.CodeAttr.popType(CodeAttr.java:442)
at gnu.bytecode.SwitchState.switchValuePushed(SwitchState.java:76)
at gnu.bytecode.CodeAttr.startSwitch(CodeAttr.java:2505)

Code:

>public void compile(Compilation comp, Target target) {
>	System.out.print("Compiling CaseExp\n");
>	
>	CodeAttr code = comp.getCode();
>	key.compile(comp, target);
>	SwitchState sw = code.startSwitch();
>	
>	for (int i = 0; i < clauses.length; i++) {
>		clauses[i].compile(sw, comp,
>	target);			
>}
>	if (elseClause != null)
>		elseClause.compile(sw, comp, target);
>}

I think the problem is that the key Expression is not found on the
stack when startSwitch is called. How can I push the key on the stack?
Looking at the IfExp.compile implementation I found a similar code:

>ConditionalTarget ctarget
>      = new ConditionalTarget(trueLabel, falseLabel, language);
>test.compile(comp, ctarget);
>code.emitIfThen(); 

Do I have to create a particular Target to compile the case key?

> 
> If CaseClause extends LetExp in the same way as CatchClause, then
> you can translate '=> expression' as something like
>    '(let ((dummy (match ...))) (expression dummy))'

I choose not to use a LetExp as we have no bindings in the case clauses.

To avoid writing a lot of code here, I published the git repository:

bit.ly/1g0ajsl 

Andrea



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-03-21  2:56                 ` Per Bothner
  2014-03-26 10:02                   ` Andrea Bernardini
@ 2014-03-28 11:14                   ` Andrea Bernardini
  2014-03-30  6:43                     ` Per Bothner
  1 sibling, 1 reply; 27+ messages in thread
From: Andrea Bernardini @ 2014-03-28 11:14 UTC (permalink / raw)
  To: kawa

I solved the popType problem using a StackTarget, but I don't
understand why this code does not work:

>public void compile(Compilation comp, Target target) {
>	System.out.print("Compiling CaseExp\n");
>	
>	CodeAttr code = comp.getCode();
>	
>	StackTarget st = new StackTarget(PrimType.int_type);
>	key.compile(comp, st);
>	SwitchState sw = code.startSwitch();
>
>	sw.addDefault(code);
>	clauses[0].exp.compile(comp, new
>	StackTarget(Compilation.typeObject)); sw.finish(code);

>at gnu.bytecode.Label.setTypes(Label.java:103)
>at gnu.bytecode.CodeAttr.emitGoto(CodeAttr.java:1601)
>at gnu.bytecode.SwitchState.finish(SwitchState.java:228)

While this works:

>public void compile(Compilation comp, Target target) {
>	System.out.print("Compiling CaseExp\n");
>	
>	clauses[0].exp.compile(comp, new
>	StackTarget(Compilation.typeObject));

Another thing I don't understand is why SwitchState.finish() raise an
Exception when you compile a switch without a default clause. It should
be allowed both in Java and Scheme.

Andrea

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-03-28 11:14                   ` Andrea Bernardini
@ 2014-03-30  6:43                     ` Per Bothner
  2014-04-03  0:12                       ` Andrea Bernardini
  0 siblings, 1 reply; 27+ messages in thread
From: Per Bothner @ 2014-03-30  6:43 UTC (permalink / raw)
  To: Andrea Bernardini, kawa

On 03/28/2014 04:14 AM, Andrea Bernardini wrote:
> I solved the popType problem using a StackTarget, but I don't
> understand why this code does not work:
>
>> public void compile(Compilation comp, Target target) {
>> 	System.out.print("Compiling CaseExp\n");
>> 	
>> 	CodeAttr code = comp.getCode();
>> 	
>> 	StackTarget st = new StackTarget(PrimType.int_type);
>> 	key.compile(comp, st);
>> 	SwitchState sw = code.startSwitch();
>>
>> 	sw.addDefault(code);
>> 	clauses[0].exp.compile(comp, new
>> 	StackTarget(Compilation.typeObject)); sw.finish(code);
>
>> at gnu.bytecode.Label.setTypes(Label.java:103)
>> at gnu.bytecode.CodeAttr.emitGoto(CodeAttr.java:1601)
>> at gnu.bytecode.SwitchState.finish(SwitchState.java:228)

Could well be a bug.  The error in setTypes indicates that the stack
size in two paths are inconsistent.  That would be the "current SP"
and the SP in the label, typically set by an earlier goto to this label.

I'd uncomment the DEBUG statements at the end of Label.java, and
replace the throw new InternalError() by
  throw new InternalError("setTypes for "+this+" SP:"
+(stackTypes==null?-1:stackTypes.length)+" code.SP:"+code.SP);

Note the 'id' of the label - say NNN.  You can find out which label
this is and when it was created by adding to the Label constructor:
   if (id==NNN) new Error("creating "+this).printStackTrace();

Sometimes it's ok for stack sizes of multiple execution paths are
inconsistent, but only if the label is "unreachable" along some paths.

> Another thing I don't understand is why SwitchState.finish() raise an
> Exception when you compile a switch without a default clause. It should
> be allowed both in Java and Scheme.

There has to be a default case at the JVM level.  Java and Scheme allow
a "default default" that does nothing or (for Scheme) returns an
unspecified value - just like for (if e1 e2).  A missing default should
be compiled as if it were QuoteExp.voidExp.

Note also how the visitIfExp in InlineCalls handles type-checking - 
including
possibly complaining if "missing else where value is required".
vistCaseExp would need to do something similar.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-03-30  6:43                     ` Per Bothner
@ 2014-04-03  0:12                       ` Andrea Bernardini
  2014-04-04 19:49                         ` Per Bothner
  0 siblings, 1 reply; 27+ messages in thread
From: Andrea Bernardini @ 2014-04-03  0:12 UTC (permalink / raw)
  To: kawa

Il giorno Sat, 29 Mar 2014 23:43:24 -0700
Per Bothner <per@bothner.com> ha scritto:

> I'd uncomment the DEBUG statements at the end of Label.java, and
> replace the throw new InternalError() by
>   throw new InternalError("setTypes for "+this+" SP:"
> +(stackTypes==null?-1:stackTypes.length)+" code.SP:"+code.SP);

In fact, there is an inconsistency. It always prints:
> setTypes for Label#7-pos:31 SP:0 code.SP:1

I believe the problem is in this part of the SwitchState.finish()
method:
>if (numCases <= 1)
>{
>	code.pushType(Type.intType);
>	if (numCases == 1)
>	{
>		if (minValue == 0)
>			code.emitIfIntEqZero();
>		else
>		{
>			code.emitPushInt(minValue);
>			code.emitIfEq();
>		}
>		code.emitGoto(labels[0]);
>		code.emitElse();
>		code.emitGoto(defaultLabel);
>		code.emitFi();
>	}
>	else
>	{
>		code.emitPop(1);
>		code.emitGoto(defaultLabel);
>	}
>}
 
I tried to modify this code to solve the problem, without success for
now (I get an "unimplemented bytecode" error at the end of execution,
not in compilation), but I noticed that removing this if-block entirely
and using the more general code that follows in the method, my code
compiles and runs correctly.

> There has to be a default case at the JVM level.  Java and Scheme
> allow a "default default" that does nothing or (for Scheme) returns an
> unspecified value - just like for (if e1 e2).  A missing default
> should be compiled as if it were QuoteExp.voidExp.

Indeed, adding a default case with QuoteExp.voidExp worked.

> Note also how the visitIfExp in InlineCalls handles type-checking - 
> including
> possibly complaining if "missing else where value is required".
> vistCaseExp would need to do something similar.

Once solved the problem with StartSwitch.finish(), I will look at that.

Thanks,
Andrea

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-04-03  0:12                       ` Andrea Bernardini
@ 2014-04-04 19:49                         ` Per Bothner
  2014-04-04 21:04                           ` Andrea Bernardini
  2014-04-13 16:04                           ` Andrea Bernardini
  0 siblings, 2 replies; 27+ messages in thread
From: Per Bothner @ 2014-04-04 19:49 UTC (permalink / raw)
  To: kawa



On 04/02/2014 05:11 PM, Andrea Bernardini wrote:

> I believe the problem is in this part of the SwitchState.finish()
> method:
>> if (numCases <= 1)
>> {
>      ....
>> }

Is this numCases==0? If so I don't see where the bug is.
Perhaps you could put System.println("line N SP:"+SP) on
various lines and see if you can figure out what the problem is.

> I tried to modify this code to solve the problem, without success for
> now (I get an "unimplemented bytecode" error at the end of execution,
> not in compilation), but I noticed that removing this if-block entirely
> and using the more general code that follows in the method, my code
> compiles and runs correctly.

That suggests you're right - and Ill probably say "duh - that should
have been obvious" once we figure it out.  It's almost certainly a
1-line fix.

-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-04-04 19:49                         ` Per Bothner
@ 2014-04-04 21:04                           ` Andrea Bernardini
  2014-04-13 16:04                           ` Andrea Bernardini
  1 sibling, 0 replies; 27+ messages in thread
From: Andrea Bernardini @ 2014-04-04 21:04 UTC (permalink / raw)
  To: kawa

On Fri, 04 Apr 2014 12:49:25 -0700
Per Bothner <per@bothner.com> wrote:

> Is this numCases==0? If so I don't see where the bug is.
> Perhaps you could put System.println("line N SP:"+SP) on
> various lines and see if you can figure out what the problem is.

Also with numCases == 1

> // only an else clause
> numCases: 0 
> Before code.pushType(Type.intType);  SP:1
> After code.pushType(Type.intType);  SP:2
> Before code.emitPop(1); SP:2
> After code.emitPop(1); SP:1
> Before code.emitGoto(defaultLabel); SP:1
> Exception in thread "main" java.lang.InternalError: setTypes for
> Label#7-pos:31 SP:0 code.SP:1

> // one clause with an else clause
> numCases: 1 
> Before code.pushType(Type.intType);  SP:1
> After code.pushType(Type.intType);  SP:2
> Before code.emitIfIntEqZero(); SP:2
> After code.emitIfIntEqZero(); SP:1
> Before code.emitGoto(labels[0]); SP:1
> Exception in thread "main" java.lang.InternalError: setTypes for
> Label#7-pos:31 SP:0 code.SP:1

> // one clouse without an else clause
> numCases: 1
> Before code.pushType(Type.intType);  SP:0
> After code.pushType(Type.intType);  SP:1
> Before code.emitIfIntEqZero(); SP:1
> After code.emitIfIntEqZero(); SP:0
> Before code.emitGoto(labels[0]); SP:0
> After code.emitGoto(labels[0]); SP:0
> Before code.emitElse(); SP:0
> After code.emitElse(); SP:0
> Before code.emitGoto(defaultLabel); SP:0
> After code.emitGoto(defaultLabel); SP:0
> Before code.emitFi(); SP:0
> After code.emitFi(); SP:0
>
> No error during compilation
> Executes the right case expression correctly
> After execution: DEBUG MESSAGE: unimplemented bytecode
> java.lang.NullPointerException
>	at it.polimi.kawacase.syntax.run(syntax.scm:69)
>	at gnu.expr.ModuleBody.runAsMain(ModuleBody.java:152)
>	at it.polimi.kawacase.syntax.main(syntax.scm)

Maybe there is some problem with my code. I think the problem is the
SP:1 at the starting point of finish(). I suppose from the emitPop(1)
in the code that at that point is always expected an SP:0. There SP is 1
because the default clause expression is compiled with a StackTarget,
so the result is expected to be put on the stack.

Concerning the "unimplemented bytecode" message, I have no idea. When I
have no else clause I add a default void case:

>sw.addDefault(code);
>QuoteExp.voidExp.compile(comp, new StackTarget(PrimType.void_type));
>sw.finish(code);

Andrea 
 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-04-04 19:49                         ` Per Bothner
  2014-04-04 21:04                           ` Andrea Bernardini
@ 2014-04-13 16:04                           ` Andrea Bernardini
  2014-04-17  1:17                             ` Per Bothner
  1 sibling, 1 reply; 27+ messages in thread
From: Andrea Bernardini @ 2014-04-13 16:04 UTC (permalink / raw)
  To: kawa

[-- Attachment #1: Type: text/plain, Size: 555 bytes --]

I think I solved the problem, besides the stack size inconsistency
there was a missing return statement at the end of the switch bytecode,
and after each case. The code handling the numCases > 1 case
automatically inserts the return statements,  instead when numCases <=
1 they have to be inserted explicitly. 

I changed only few lines of code in SwitchState.java (see the
attachment). I compiled kawa with these changes and it seems to work.
Do you see some problem in this code?

Now I can start to look at the type-checking in InlineCalls.

Andrea  


[-- Attachment #2: SwitchState.diff --]
[-- Type: text/x-patch, Size: 767 bytes --]

--- Programmazione/Projects/Kawa/code/gnu/bytecode/SwitchState.java	2014-03-09 17:57:31.358834943 +0100
+++ Programmazione/Projects/Kawa/code_mod/gnu/bytecode/SwitchState.java	2014-04-13 17:05:06.886136667 +0200
@@ -183,7 +183,7 @@
   {
     if (outerTry != code.try_stack)
       throw new Error("exitSwitch cannot exit through a try");
-    code.emitGoto(after_label);
+    code.emitReturn();
   }
 
   /** Handle the end of the switch statement.
@@ -204,9 +204,13 @@
 	code.emitInvokeSpecial(con);
 	code.emitThrow();
       }
+    if (numCases <= 1)
+    	code.emitReturn();
     code.fixupChain(switch_label, after_label);
     if (numCases <= 1)
       {
+	if (code.getSP() == 1)	
+	    code.popType();
 	code.pushType(Type.intType);
 	if (numCases == 1)
 	  {

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-04-13 16:04                           ` Andrea Bernardini
@ 2014-04-17  1:17                             ` Per Bothner
  2014-04-17 23:12                               ` Andrea Bernardini
  0 siblings, 1 reply; 27+ messages in thread
From: Per Bothner @ 2014-04-17  1:17 UTC (permalink / raw)
  To: kawa

On 04/13/2014 09:03 AM, Andrea Bernardini wrote:
> I think I solved the problem, besides the stack size inconsistency
> there was a missing return statement at the end of the switch bytecode,
> and after each case.

That doesn't seem right - why should switch automatically cause a
a method return?

And in fact it doesn't work - the test suite has numerous failures.

My recommendation: Run the test-suite early and often.
This is easiest if you're developing on a Unix-like system (e.g.
GNU/Linux or MacOS) and using configure+make (rather than ant builds),
since you just do:
   make check -k >& LOG.CHECK

I stash a copy of LOG.CHECK before I make changes, and compare (with
diff) the result after my changes.

(Recently I've made a number of improvements in the Windows support,
so that 'make check -k' works much better on Windows - tested using
MSYS.  Patches welcome.)

> The code handling the numCases > 1 case
> automatically inserts the return statements,  instead when numCases <=
> 1 they have to be inserted explicitly.

Where?   I don't see anything that inserts a return statement.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-04-17  1:17                             ` Per Bothner
@ 2014-04-17 23:12                               ` Andrea Bernardini
  2014-04-18  0:31                                 ` Per Bothner
  0 siblings, 1 reply; 27+ messages in thread
From: Andrea Bernardini @ 2014-04-17 23:12 UTC (permalink / raw)
  To: kawa

On Wed, 16 Apr 2014 18:17:36 -0700
Per Bothner <per@bothner.com> wrote:

> That doesn't seem right - why should switch automatically cause a
> a method return?

If I compile a case expr wit numCases == 2, this code is generated:

>...
> 31: tableswitch low: 1 high: 5 default: 114
>  1: 64
>  2: 114
>  3: 114
>  4: 114
>  5: 89
> 64: *First case code*
>...
> 83: invokevirtual <Method gnu.mapping.Procedure.apply1
> (java.lang.Object)java.lang.Object> 
> 86: goto 124
> 89: *Second case code*
>...
>108: invokevirtual <Method gnu.mapping.Procedure.apply1
>(java.lang.Object)java.lang.Object> 
>111: goto 124
>114: *Default case code*
>...
>121: invokevirtual <Method gnu.mapping.Procedure.apply2
>(java.lang.Object,java.lang.Object)java.lang.Object> 
>124: return
>Attribute "StackMapTable", length:17, number of entries: 4
>...

If I compile a case expr wit numCases == 1, this is the result:

>...
> 31: iconst_1
> 32: if_icmpne 38
> 35: goto 41
> 38: goto 66
> 41: *First case code*
>...
> 60: invokevirtual <Method gnu.mapping.Procedure.apply1
> (java.lang.Object)java.lang.Object> 
> 63: goto 76
> 66: *Default case code*
>...
> 73: invokevirtual <Method gnu.mapping.Procedure.apply2
> (java.lang.Object,java.lang.Object)java.lang.Object>
>Attribute "StackMapTable", length:13, number of entries: 3
>...

In the numCases == 2 code, all the gotos point to a return statement,
while in the numCases == 1 the return is missing. What I wanted to
obtain was the same code with a return statement at the end. But adding
a return statement at the end with emitReturn() is not enough, because
for some reason after_label is not pointing to the correct location:

>...
> 31: iconst_1
> 32: if_icmpne 38
> 35: goto 41
> 38: goto 66
> 41: *First case code*
>...
> 60: invokevirtual <Method gnu.mapping.Procedure.apply1
> (java.lang.Object)java.lang.Object> 
> 63: goto 77
> 66: *Default case code*
>...
> 73: invokevirtual <Method gnu.mapping.Procedure.apply2
> (java.lang.Object,java.lang.Object)java.lang.Object> 
> 76: return
>Attribute "StackMapTable", length:13, number of entries: 3
>...

The problem is: where is that return generated when we have numCases ==
2, and how can we obtain the same behaviour when numCases <= 1.

> And in fact it doesn't work - the test suite has numerous failures.
> 
> My recommendation: Run the test-suite early and often.
> This is easiest if you're developing on a Unix-like system (e.g.
> GNU/Linux or MacOS) and using configure+make (rather than ant builds),
> since you just do:
>    make check -k >& LOG.CHECK
> 
> I stash a copy of LOG.CHECK before I make changes, and compare (with
> diff) the result after my changes.

Thanks, I will make use of the test suite from now on. I ususally work
on Debian GNU/Linux.

Andrea

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-04-17 23:12                               ` Andrea Bernardini
@ 2014-04-18  0:31                                 ` Per Bothner
  2014-04-18 11:08                                   ` Andrea Bernardini
  0 siblings, 1 reply; 27+ messages in thread
From: Per Bothner @ 2014-04-18  0:31 UTC (permalink / raw)
  To: kawa

[-- Attachment #1: Type: text/plain, Size: 1139 bytes --]



On 04/17/2014 04:12 PM, Andrea Bernardini wrote:
> In the numCases == 2 code, all the gotos point to a return statement,
> while in the numCases == 1 the return is missing. What I wanted to
> obtain was the same code with a return statement at the end. But adding
> a return statement at the end with emitReturn() is not enough, because
> for some reason after_label is not pointing to the correct location:

I have a hunch there could be a problem with the "fixup" machinery -
which could be a bug in my code - or that you're violating some
important assumption in the code.

The fixup logic is rather complex.  It can re-order the bytecode and
make various optimizations.  It actually makes 3 passes over the
bytecode. I suggest uncommenting disAssembleWithFixups and calling it
at the beginning of processFixups - the attached patch shows what you
need to do.  That will show you how the bytecode looks before
fixup-processing.

I assume switchValuePushed is being called by your code (probably 
indirectly via startSwitch) and that exitSwitch is called before
addDefault.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

[-- Attachment #2: debug-fixup.patch --]
[-- Type: text/x-patch, Size: 1813 bytes --]

Index: gnu/bytecode/CodeAttr.java
===================================================================
--- gnu/bytecode/CodeAttr.java	(revision 7851)
+++ gnu/bytecode/CodeAttr.java	(working copy)
@@ -2538,6 +2538,10 @@
   {
     if (fixup_count <= 0)
       return;
+    System.out.println("processFixups for "+getMethod());
+    ClassTypeWriter writer = new ClassTypeWriter(getMethod().getDeclaringClass(), System.out, 0);
+disAssembleWithFixups(writer);
+writer.flush();
 
     // For each label, set it to its maximum limit, assuming all
     // fixups causes the code the be expanded.  We need a prepass
@@ -2936,7 +2940,7 @@
     dst.printAttributes(this);
   }
 
-  /* DEBUGGING:
+    ///* DEBUGGING:
   public void disAssembleWithFixups (ClassTypeWriter dst)
   {
     if (fixup_count <= 0)
@@ -3017,7 +3021,7 @@
 	i++;
       }
   }
-  */
+  //*/
 
   public void disAssemble (ClassTypeWriter dst, int start, int limit)
   {
Index: gnu/bytecode/Label.java
===================================================================
--- gnu/bytecode/Label.java	(revision 7851)
+++ gnu/bytecode/Label.java	(working copy)
@@ -241,9 +241,9 @@
     code.setReachable(true);
   }
 
-  /* DEBUG
+    ///* DEBUG
   int id = ++counter;
   static int counter;
   public String toString() { return "Label#"+id+"-pos:"+position; }
-  */
+    //*/
 }
Index: gnu/bytecode/SwitchState.java
===================================================================
--- gnu/bytecode/SwitchState.java	(revision 7851)
+++ gnu/bytecode/SwitchState.java	(working copy)
@@ -63,7 +63,7 @@
     cases_label = new Label(code);
     after_label = new Label(code);
     outerTry = code.try_stack;
-
+    System.err.println("new Switch switch_label:"+switch_label+" cases_label:"+cases_label+" after_label:"+after_label);
     numCases = 0;
   }
 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-04-18  0:31                                 ` Per Bothner
@ 2014-04-18 11:08                                   ` Andrea Bernardini
  2014-04-19  0:23                                     ` Per Bothner
  0 siblings, 1 reply; 27+ messages in thread
From: Andrea Bernardini @ 2014-04-18 11:08 UTC (permalink / raw)
  To: kawa

On Thu, 17 Apr 2014 17:31:05 -0700
Per Bothner <per@bothner.com> wrote:

> I assume switchValuePushed is being called by your code (probably 
> indirectly via startSwitch) and that exitSwitch is called before
> addDefault.

Yes, these assumption are respected.

I applied the patch to revision 7851, but when I try to build kawa
source tree, it fails:

>fixup#69 @378 DEFINE Lainternal error while compiling srfi1.scm
>java.lang.ArrayIndexOutOfBoundsException: 1927
>	at gnu.bytecode.CodeAttr.readUnsignedShort(CodeAttr.java:3300)
>	at gnu.bytecode.CodeAttr.readInt(CodeAttr.java:3305)
>	at gnu.bytecode.CodeAttr.disAssemble(CodeAttr.java:3204)
>	at
>	gnu.bytecode.CodeAttr.disAssembleWithFixups(CodeAttr.java:2961)
>	at gnu.bytecode.CodeAttr.processFixups(CodeAttr.java:2543) at
>	gnu.bytecode.CodeAttr.assignConstants(CodeAttr.java:2856) at
>	gnu.bytecode.Attribute.assignConstants(Attribute.java:104) at
>	gnu.bytecode.Method.assignConstants(Method.java:344) at
>	gnu.bytecode.ClassType.doFixups(ClassType.java:1106) at
>	gnu.bytecode.ClassType.writeToStream(ClassType.java:1166) at
>	gnu.bytecode.ClassType.writeToFile(ClassType.java:1209) at
>	gnu.expr.Compilation.outputClass(Compilation.java:977) at
>	gnu.expr.Compilation.process(Compilation.java:1983) at
>	gnu.expr.ModuleInfo.loadByStages(ModuleInfo.java:305) at
>	kawa.repl.compileFiles(repl.java:816) at
>	kawa.repl.processArgs(repl.java:439) at
>	kawa.repl.main(repl.java:863)

Andrea


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-04-18 11:08                                   ` Andrea Bernardini
@ 2014-04-19  0:23                                     ` Per Bothner
  2014-04-22 22:37                                       ` Andrea Bernardini
  0 siblings, 1 reply; 27+ messages in thread
From: Per Bothner @ 2014-04-19  0:23 UTC (permalink / raw)
  To: kawa

[-- Attachment #1: Type: text/plain, Size: 666 bytes --]

On 04/18/2014 04:07 AM, Andrea Bernardini wrote:
> I applied the patch to revision 7851, but when I try to build kawa
> source tree, it fails:
>
>> fixup#69 @378 DEFINE Lainternal error while compiling srfi1.scm
>> java.lang.ArrayIndexOutOfBoundsException: 1927
>> 	at gnu.bytecode.CodeAttr.readUnsignedShort(CodeAttr.java:3300)
>> 	at gnu.bytecode.CodeAttr.readInt(CodeAttr.java:3305)
>> 	at gnu.bytecode.CodeAttr.disAssemble(CodeAttr.java:3204)
>> 	at
>> 	gnu.bytecode.CodeAttr.disAssembleWithFixups(CodeAttr.java:2961)

Oops.

Try reverting the previous patch, svn update, and then the attached
patch.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

[-- Attachment #2: debug-fixup.patch2 --]
[-- Type: text/plain, Size: 2041 bytes --]

Index: gnu/bytecode/CodeAttr.java
===================================================================
--- gnu/bytecode/CodeAttr.java	(revision 7853)
+++ gnu/bytecode/CodeAttr.java	(working copy)
@@ -2547,7 +2547,7 @@
         int instruction_tail = fixup_count;
         fixupAdd(CodeAttr.FIXUP_MOVE, 0, null);
 
-        /* DEBUGGING:
+        ///* DEBUGGING:
         System.err.println("processFixups for "+getMethod());
         ClassTypeWriter writer =
             new ClassTypeWriter(getMethod().getDeclaringClass(), System.err, 0);
@@ -2554,7 +2554,7 @@
         writer.println("processFixups for "+getMethod());
         disAssembleWithFixups(writer);
         writer.flush();
-        */
+        //*/
 
   loop1:
    for (int i = 0;  ;  )
@@ -2944,7 +2944,7 @@
     dst.printAttributes(this);
   }
 
-    /* DEBUGGING:
+    ///* DEBUGGING:
     public void disAssembleWithFixups(ClassTypeWriter dst) {
         if (fixup_count <= 0) {
             disAssemble(dst, 0, PC);
@@ -3027,7 +3027,7 @@
         }
         disAssemble(dst, prev_pc, PC);
     }
-    */
+    //*/
 
   public void disAssemble (ClassTypeWriter dst, int start, int limit)
   {
Index: gnu/bytecode/Label.java
===================================================================
--- gnu/bytecode/Label.java	(revision 7851)
+++ gnu/bytecode/Label.java	(working copy)
@@ -241,9 +241,9 @@
     code.setReachable(true);
   }
 
-  /* DEBUG
+    ///* DEBUG
   int id = ++counter;
   static int counter;
   public String toString() { return "Label#"+id+"-pos:"+position; }
-  */
+    //*/
 }
Index: gnu/bytecode/SwitchState.java
===================================================================
--- gnu/bytecode/SwitchState.java	(revision 7854)
+++ gnu/bytecode/SwitchState.java	(working copy)
@@ -63,7 +63,7 @@
     cases_label = new Label(code);
     after_label = new Label(code);
     outerTry = code.try_stack;
-
+    System.err.println("new Switch switch_label:"+switch_label+" cases_label:"+cases_label+" after_label:"+after_label);
     numCases = 0;
   }
 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-04-19  0:23                                     ` Per Bothner
@ 2014-04-22 22:37                                       ` Andrea Bernardini
  2014-04-23  5:12                                         ` Per Bothner
  0 siblings, 1 reply; 27+ messages in thread
From: Andrea Bernardini @ 2014-04-22 22:37 UTC (permalink / raw)
  To: kawa

Running the code with disAssembleWithFixups, I noticed that the
final return statement is missing also before the code reordering.

This is the code generated when we have two cases:

# numCases == 2
> [...]
>fixup#66 @0 MOVE Label#6-pos:146
>fixup#67 @113 DEFINE Label#4-pos:113
>fixup#68 @113 SWITCH
>fixup#69 @114 CASE Label#9-pos:81
>fixup#70 @126 CASE Label#7-pos:31
>fixup#71 @130 CASE Label#9-pos:81
>fixup#72 @134 CASE Label#9-pos:81
>fixup#73 @138 CASE Label#9-pos:81
>fixup#74 @142 CASE Label#8-pos:56
>113: tableswitch low: 1 high: 5 default: 113
>  1: 113
>  2: 113
>  3: 113
>  4: 113
>  5: 113
>fixup#75 @0 MOVE Label#5-pos:31
>fixup#76 @146 DEFINE Label#6-pos:146
>146: return
>fixup#77 @147 DEFINE Label#10-pos:147
>fixup#78 @147 DEFINE Label#11-pos:147
>fixup#79 @0 MOVE null

Instead when we have only one case the code before the reordering is
the following:

# numCases == 1
> [...]
>fixup#54 @0 MOVE Label#6-pos:98
>fixup#55 @88 DEFINE Label#4-pos:88
> 88: iconst_1
>fixup#56 @89 TRANSFER Label#9-pos:95
> 89: if_icmpne 89
>fixup#57 @92 GOTO Label#7-pos:31
> 92: goto 92
>fixup#58 @95 DEFINE Label#9-pos:95
>fixup#59 @95 GOTO Label#8-pos:56
> 95: goto 95
>fixup#60 @0 MOVE Label#5-pos:31
>fixup#61 @98 DEFINE Label#6-pos:98
>fixup#62 @98 DEFINE Label#10-pos:98
>fixup#63 @98 DEFINE Label#11-pos:98
>fixup#64 @0 MOVE null

I tried to put some println inside code.emitReturn and code.put1.
It comes out that emitReturn is never called when the numCases == 1
code is generated.

-- 
Andrea Bernardini
Engineering  Of  Computing Systems student
Politecnico di Milano, Italy

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer of Code
  2014-04-22 22:37                                       ` Andrea Bernardini
@ 2014-04-23  5:12                                         ` Per Bothner
  0 siblings, 0 replies; 27+ messages in thread
From: Per Bothner @ 2014-04-23  5:12 UTC (permalink / raw)
  To: kawa



On 04/22/2014 03:37 PM, Andrea Bernardini wrote:
> Running the code with disAssembleWithFixups, I noticed that the
> final return statement is missing also before the code reordering.
>
 > ...
 >
> I tried to put some println inside code.emitReturn and code.put1.
> It comes out that emitReturn is never called when the numCases == 1
> code is generated.

What I usually in such cases is I put a:
   new Error("emitReturn called").printStackTrace();
inside emitReturn. Then I look at the stack trace (for numCases == 2)
to understand who calls emitReturn and why.  (It shouldn't have
anything to do (directly) with SwitchState.)

Then you try to figure out why emitReturn is not being called in the
numCases == 1 case.  I.e. you try to figure out why the two cases are
acting differently. Either using a debugger or adding print statements

However, I have a hunch: The problem is most likely that
   comp.method.reachableHere()
is false when compileEnd is called.

Clearly reachableHere() *should* be false after the (numcases==1)
code in SwitchState.finish.  Logically, it should also be false
after a lookupswitch or tableswitch instruction.  Perhaps things
accidentally work because we don't do code.setUnreachable() when
we really ought to.

I.e. a possible work-around would be to add a code.setReachable(true)
at the end of the numCases=1 logic.  However I would like to understand
why that would be needed, and perhaps make a cleaner fix.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Google Summer Of Code
  2011-03-29 16:40 Google Summer Of Code Simon
@ 2011-03-30  7:28 ` Per Bothner
  0 siblings, 0 replies; 27+ messages in thread
From: Per Bothner @ 2011-03-30  7:28 UTC (permalink / raw)
  To: Simon; +Cc: kawa

On 03/29/2011 09:40 AM, Simon wrote:
> Hi there,
> I am a second year computer science student at the University of St.
> Andrews. I am hoping to do a project for the Google Summer of Code. I am
> very interested in working on a part of the GNU project, and Kawa seems
> like an interesting technology to work on.

I think so - and hope you will enjoy working on Kawa!

> The project ideas at
> http://www.gnu.org/software/kawa/Ideas-and-tasks.html give little
> indication of how much work would be involved, and there are quite a
> number of them, so I was wondering if you could recommend which sections
> have the highest priority and possibly a combination of tasks which you
> feel would be achievable for the duration of the project.

A reasonable request.  I will attempt to flesh the projects out ASAP
with both importance and perceived difficulty.
Of course how difficult a project is is very individual and depends
on your background.

For example, "Full continuations" is highly desirable for some applications
- and if nothing else as a "check-off item" for Kawa to qualify as "full
Scheme".  I think it can be done in a Summer, though will involve some 
studying
of the research, especially if you're not very familiar with continuations
or continuation-passing-style.  Familiarity with Haskell and functional
programming should help, though.

Parameterized types is also high desirable, but it is best to have
some familiarity with type inference and type checking theory.

Some of the projects, such as the Common Lisp support, are open-ended:
You dig in, and you get done as much as you have time for.

> I have skills in Java, Python, C, Haskell, HTML, JavaScript and some in
> CLISP. I am happy to learn Scheme if you feel it is necessary for the
> project.

For most of the project it will help to have some Scheme familiarity, but
most you won't need very much.

Anyway, I'll try to add more information in the next few days.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Google Summer Of Code
@ 2011-03-29 16:40 Simon
  2011-03-30  7:28 ` Per Bothner
  0 siblings, 1 reply; 27+ messages in thread
From: Simon @ 2011-03-29 16:40 UTC (permalink / raw)
  To: kawa

Hi there,
I am a second year computer science student at the University of St.
Andrews. I am hoping to do a project for the Google Summer of Code. I am
very interested in working on a part of the GNU project, and Kawa seems
like an interesting technology to work on.

The project ideas at
http://www.gnu.org/software/kawa/Ideas-and-tasks.html give little
indication of how much work would be involved, and there are quite a
number of them, so I was wondering if you could recommend which sections
have the highest priority and possibly a combination of tasks which you
feel would be achievable for the duration of the project.

I have skills in Java, Python, C, Haskell, HTML, JavaScript and some in
CLISP. I am happy to learn Scheme if you feel it is necessary for the
project.

I look forward to hearing from you
Kind regards,
Simon Brand

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2014-04-23  5:12 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-05  8:43 Google Summer of Code Andrea Bernardini
2014-03-05 10:15 ` Charles Turner
2014-03-05 12:23   ` Andrea Bernardini
2014-03-05 20:29     ` Per Bothner
2014-03-05 21:46     ` Helmut Eller
2014-03-06 23:45       ` Per Bothner
2014-03-07  0:00         ` Jamison Hope
2014-03-16  0:21           ` Andrea Bernardini
2014-03-17  6:26             ` Per Bothner
2014-03-20 19:50               ` Andrea Bernardini
2014-03-21  2:56                 ` Per Bothner
2014-03-26 10:02                   ` Andrea Bernardini
2014-03-28 11:14                   ` Andrea Bernardini
2014-03-30  6:43                     ` Per Bothner
2014-04-03  0:12                       ` Andrea Bernardini
2014-04-04 19:49                         ` Per Bothner
2014-04-04 21:04                           ` Andrea Bernardini
2014-04-13 16:04                           ` Andrea Bernardini
2014-04-17  1:17                             ` Per Bothner
2014-04-17 23:12                               ` Andrea Bernardini
2014-04-18  0:31                                 ` Per Bothner
2014-04-18 11:08                                   ` Andrea Bernardini
2014-04-19  0:23                                     ` Per Bothner
2014-04-22 22:37                                       ` Andrea Bernardini
2014-04-23  5:12                                         ` Per Bothner
  -- strict thread matches above, loose matches on Subject: below --
2011-03-29 16:40 Google Summer Of Code Simon
2011-03-30  7:28 ` Per Bothner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).