001 /* 002 * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered 003 * by the modified BSD License. You should have received a copy of the 004 * modified BSD license with this compiler. 005 * 006 * Copyright (c) 2005-2008, Torbjorn Ekman 007 * All rights reserved. 008 */ 009 010 aspect LocalNum { 011 inh lazy int VariableDeclaration.localNum(); 012 inh lazy int Stmt.localNum(); 013 inh lazy int ParameterDeclaration.localNum(); 014 015 eq Program.getChild(int index).localNum() = 0; 016 017 syn lazy int MethodDecl.offsetBeforeParameters() = isStatic() ? 0 : 1; 018 019 syn lazy int MethodDecl.offsetAfterParameters() { 020 if(getNumParameter() == 0) 021 return offsetBeforeParameters(); 022 return getParameter(getNumParameter()-1).localNum() + 023 getParameter(getNumParameter()-1).type().variableSize(); 024 } 025 026 eq MethodDecl.getParameter(int index).localNum() { 027 if(index == 0) 028 return offsetBeforeParameters(); 029 return getParameter(index-1).localNum() + getParameter(index-1).type().variableSize(); 030 } 031 032 eq InstanceInitializer.getBlock().localNum() { 033 int localNum = 1; 034 for(Iterator iter = hostType().constructors().iterator(); iter.hasNext(); ) { 035 ConstructorDecl c = (ConstructorDecl)iter.next(); 036 int num = c.getNumParameter() == 0 ? c.localNumOfFirstParameter() : 037 c.getParameter(c.getNumParameter()-1).localNum() + c.getParameter(c.getNumParameter()-1).type().variableSize(); 038 if(num > localNum) 039 localNum = num; 040 } 041 return localNum; 042 } 043 044 inh lazy int ReturnStmt.resultSaveLocalNum(); 045 eq MethodDecl.getBlock().resultSaveLocalNum() = offsetAfterParameters(); 046 eq Program.getChild().resultSaveLocalNum() { 047 throw new Error("Unsupported operation resultSaveLocalNum"); 048 } 049 050 syn lazy int MethodDecl.resultOffset() = type().isVoid() ? 0 : type().variableSize(); 051 052 eq MethodDecl.getBlock().localNum() = offsetAfterParameters() + 053 resultOffset(); 054 055 syn lazy int ConstructorDecl.localNumOfFirstParameter() { 056 int i = 1; 057 if(hostType().needsEnclosing()) 058 i++; 059 if(hostType().needsSuperEnclosing()) 060 i++; 061 return i; 062 } 063 064 syn lazy int ConstructorDecl.offsetFirstEnclosingVariable() { 065 int localIndex = localNumOfFirstParameter(); 066 Collection vars = hostType().enclosingVariables(); 067 if(vars.isEmpty()) 068 return localIndex; 069 String name = "val$" + ((Variable)vars.iterator().next()).name(); 070 for(int i = 0; !getParameter(i).name().equals(name); i++) 071 localIndex += getParameter(i).type().variableSize(); 072 return localIndex; 073 } 074 075 syn int ConstructorDecl.localIndexOfEnclosingVariable(Variable v) { 076 int localIndex = offsetFirstEnclosingVariable(); 077 Iterator iter = hostType().enclosingVariables().iterator(); 078 Variable varDecl = (Variable)iter.next(); 079 while(varDecl != v && iter.hasNext()) { 080 localIndex += varDecl.type().variableSize(); 081 varDecl = (Variable)iter.next(); 082 } 083 return localIndex; 084 } 085 086 eq ConstructorDecl.getParameter(int index).localNum() = index == 0 ? 087 localNumOfFirstParameter() : 088 getParameter(index-1).localNum() + getParameter(index-1).type().variableSize(); 089 090 eq ConstructorDecl.getBlock().localNum() = getNumParameter() == 0 ? 091 localNumOfFirstParameter() : 092 getParameter(getNumParameter()-1).localNum() + getParameter(getNumParameter()-1).type().variableSize(); 093 094 eq ForStmt.getStmt().localNum() { 095 if(getNumInitStmt() == 0) 096 return localNum(); 097 if(getInitStmt(getNumInitStmt()-1) instanceof VariableDeclaration) 098 return getInitStmt(getNumInitStmt()-1).localNum() + ((VariableDeclaration)getInitStmt(getNumInitStmt()-1)).type().variableSize(); 099 return getInitStmt(getNumInitStmt()-1).localNum(); 100 } 101 102 eq ForStmt.getInitStmt(int index).localNum() { 103 if(index == 0) 104 return localNum(); 105 if(getInitStmt(index-1) instanceof VariableDeclaration) 106 return getInitStmt(index-1).localNum() + ((VariableDeclaration)getInitStmt(index-1)).type().variableSize(); 107 return getInitStmt(index-1).localNum(); 108 } 109 110 eq Block.getStmt(int index).localNum() { 111 if(index == 0) 112 return localNum(); 113 if(getStmt(index-1) instanceof VariableDeclaration) 114 return getStmt(index-1).localNum() + ((VariableDeclaration)getStmt(index-1)).type().variableSize(); 115 return getStmt(index-1).localNum(); 116 } 117 118 eq TryStmt.getFinally().localNum() = localNum() + 2; 119 120 eq BasicCatch.getBlock().localNum() = getParameter().localNum() + getParameter().type().variableSize(); 121 122 eq SynchronizedStmt.getBlock().localNum() = localNum() + 3; 123 124 syn int TypeDecl.variableSize() = 0; 125 eq ReferenceType.variableSize() = 1; 126 eq PrimitiveType.variableSize() = 1; 127 eq LongType.variableSize() = 2; 128 eq DoubleType.variableSize() = 2; 129 eq NullType.variableSize() = 1; 130 } 131