001    /*
002     * JastAddJ is covered by the modified BSD License. You should have received a copy of the
003     * modified BSD license with this compiler.
004     * 
005     * Copyright (c) 2011, Jesper Öqvist <jesper.oqvist@cs.lth.se>
006     * All rights reserved.
007     */
008    
009    aspect MultiCatch {
010    
011        /**
012         * The Multi-Catch clause has two or more exception table entries
013         * which all point to the same exception handler.
014         */
015        public void MultiCatch.exceptionTableEntries(CodeGeneration gen, TryStmt tryStmt) {
016                for (int i = 0; i < getParameter().getNumTypeAccess(); ++i) {
017                        TypeDecl type = getParameter().getTypeAccess(i).type();
018    
019                        gen.addException(
020                                gen.addressOf(tryStmt.label_begin()),
021                                gen.addressOf(tryStmt.label_block_end()),
022                                gen.addressOf(label()),
023                                gen.constantPool().addClass(type.constantPoolName())
024                                );
025                }
026        }
027    
028        /**
029         * Code gen.
030         */
031        public void MultiCatch.createBCode(CodeGeneration gen) {
032                gen.addLabel(label());
033                // add 1 to stack depth
034                gen.changeStackDepth(1);
035                getParameter().type().emitStoreLocal(gen, localNum());
036                getBlock().createBCode(gen);
037        }
038    
039        /**
040         * Local number used to store the exception parameter.
041         */
042        inh lazy int CatchParameterDeclaration.localNum();
043        inh lazy int MultiCatch.localNum();
044    
045        eq MultiCatch.getBlock().localNum() =
046                localNum() + getParameter().type().variableSize();
047        eq MultiCatch.getParameter().localNum() = localNum();
048    
049        refine GenericsCodegen
050        public void VarAccess.createAssignLoadDest(CodeGeneration gen) {
051                Variable v = decl();
052                if (v instanceof CatchParameterDeclaration) {
053                        if (v.isInstanceVariable())
054                                gen.emitDup();
055                        CatchParameterDeclaration decl = (CatchParameterDeclaration)v;
056                        decl.type().emitLoadLocal(gen, decl.localNum());
057                } else {
058                        refined(gen);
059                }
060        }
061    
062        refine GenericsCodegen
063        public void VarAccess.createBCode(CodeGeneration gen) {
064                Variable v = decl();
065                if (v instanceof CatchParameterDeclaration) {
066                        CatchParameterDeclaration decl = (CatchParameterDeclaration)v;
067                        if (decl.hostType() == hostType())
068                                decl.type().emitLoadLocal(gen, decl.localNum());
069                        else
070                                emitLoadLocalInNestedClass(gen, decl);
071                } else {
072                        refined(gen);
073                }
074        }
075    
076        eq BasicTWR.getBlock().lookupVariable(String name) =
077                localLookup(name);
078        syn lazy SimpleSet BasicTWR.localLookup(String name) {
079                VariableDeclaration v = localVariableDeclaration(name);
080                if (v != null) return v;
081                return lookupVariable(name);
082        }
083        syn lazy VariableDeclaration BasicTWR.localVariableDeclaration(String name) =
084                getResource().declaresVariable(name) ? getResource() : null;
085    
086        BasicTWR implements VariableScope;
087        inh lazy SimpleSet BasicTWR.lookupVariable(String name);
088    }