Add the Member interface to generalize the API usage

This commit is contained in:
Volker Berlin 2018-11-10 10:46:36 +01:00
parent 4fd7d44263
commit 101b759acb
11 changed files with 175 additions and 95 deletions

View File

@ -1,47 +1,70 @@
/* /*
Copyright 2017 Volker Berlin (i-net software) Copyright 2017 - 2018 Volker Berlin (i-net software)
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package de.inetsoftware.classparser; package de.inetsoftware.classparser;
/** /**
* @author Volker Berlin * A reference to an member that is described in the constant pool of a Java class.
*/ *
public abstract class ConstantRef { * @author Volker Berlin
*/
private final ConstantClass constClass; public abstract class ConstantRef implements Member {
private final ConstantNameAndType nameAndType; private final ConstantClass constClass;
ConstantRef( ConstantClass constClass, ConstantNameAndType nameAndType ) { private final ConstantNameAndType nameAndType;
this.constClass = constClass;
this.nameAndType = nameAndType; /**
} * Create a new instance.
*
public String getName() { * @param constClass
return nameAndType.getName(); * the class description
} * @param nameAndType
* the name and type description
/** */
* Get the type of the method. For example "(Ljava.lang.String;)I" ConstantRef( ConstantClass constClass, ConstantNameAndType nameAndType ) {
*/ this.constClass = constClass;
public String getType() { this.nameAndType = nameAndType;
return nameAndType.getType(); }
}
/**
public ConstantClass getConstantClass() { * {@inheritDoc}
return constClass; */
} @Override
} public String getName() {
return nameAndType.getName();
}
/**
* {@inheritDoc}
*/
@Override
public String getClassName() {
return getConstantClass().getName();
}
/**
* Get the type of the method. For example "(Ljava.lang.String;)I"
*/
@Override
public String getType() {
return nameAndType.getType();
}
public ConstantClass getConstantClass() {
return constClass;
}
}

View File

@ -0,0 +1,47 @@
/*
Copyright 2018 Volker Berlin (i-net software)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package de.inetsoftware.classparser;
/**
* Described a field, method, function, etc.
*
* @author Volker Berlin
*
*/
public interface Member {
/**
* The simple name without package
*
* @return the name
*/
String getName();
/**
* The class name of the declaring class.
*
* @return the class name
*/
String getClassName();
/**
* Get the type of the method or field. For example "(Ljava.lang.String;)I"
*
* @return the type
*/
String getType();
}

View File

@ -27,7 +27,7 @@ import de.inetsoftware.classparser.Attributes.AttributeInfo;
/** /**
* @author Volker Berlin * @author Volker Berlin
*/ */
public class MethodInfo { public class MethodInfo implements Member {
private final int accessFlags; private final int accessFlags;
@ -99,10 +99,19 @@ public class MethodInfo {
/** /**
* @return the name * @return the name
*/ */
@Override
public String getName() { public String getName() {
return name; return name;
} }
/**
* {@inheritDoc}
*/
@Override
public String getClassName() {
return getDeclaringClassFile().getThisClass().getName();
}
/** /**
* @return the attributes * @return the attributes
*/ */
@ -125,7 +134,8 @@ public class MethodInfo {
/** /**
* Get the signature of the method without generic types. * Get the signature of the method without generic types.
*/ */
public String getDescription() { @Override
public String getType() {
return description; return description;
} }

View File

@ -29,7 +29,7 @@ import java.util.Map.Entry;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import de.inetsoftware.classparser.ConstantRef; import de.inetsoftware.classparser.Member;
import de.inetsoftware.jwebassembly.JWebAssembly; import de.inetsoftware.jwebassembly.JWebAssembly;
import de.inetsoftware.jwebassembly.WasmException; import de.inetsoftware.jwebassembly.WasmException;
import de.inetsoftware.jwebassembly.module.FunctionName; import de.inetsoftware.jwebassembly.module.FunctionName;
@ -356,7 +356,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
protected void writeGlobalAccess( boolean load, FunctionName name, ConstantRef ref ) throws IOException { protected void writeGlobalAccess( boolean load, FunctionName name, Member ref ) throws IOException {
Global var = globals.get( name.fullName ); Global var = globals.get( name.fullName );
if( var == null ) { // if not declared then create a definition in the global section if( var == null ) { // if not declared then create a definition in the global section
var = new Global(); var = new Global();

View File

@ -18,8 +18,7 @@ package de.inetsoftware.jwebassembly.module;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import de.inetsoftware.classparser.ConstantRef; import de.inetsoftware.classparser.Member;
import de.inetsoftware.classparser.MethodInfo;
/** /**
* Described the name of WebAssembly function. * Described the name of WebAssembly function.
@ -40,28 +39,15 @@ public class FunctionName {
public final String signatureName; public final String signatureName;
/** /**
* Create a new instance from the given parsed Java method. * Create a new instance from the given reference in the ConstantPool or parsed method.
* *
* @param method * @param methodOrField
* the Java method * the Java method
*/ */
FunctionName( @Nonnull MethodInfo method ) { FunctionName( @Nonnull Member methodOrField ) {
String methodName = method.getName(); String methodName = methodOrField.getName();
String className = method.getDeclaringClassFile().getThisClass().getName(); String className = methodOrField.getClassName();
fullName = className + '.' + methodName; fullName = className + '.' + methodName;
signatureName = fullName + method.getDescription(); signatureName = fullName + methodOrField.getType();
}
/**
* Create a new instance from the given reference in the ConstantPool.
*
* @param method
* the Java method
*/
FunctionName( @Nonnull ConstantRef method ) {
String methodName = method.getName();
String className = method.getConstantClass().getName();
fullName = className + '.' + methodName;
signatureName = fullName + method.getType();
} }
} }

View File

@ -96,7 +96,7 @@ public class ModuleGenerator {
MethodInfo[] methods = classFile.getMethods(); MethodInfo[] methods = classFile.getMethods();
for( MethodInfo method : methods ) { for( MethodInfo method : methods ) {
Code code = method.getCode(); Code code = method.getCode();
if( method.getName().equals( "<init>" ) && method.getDescription().equals( "()V" ) if( method.getName().equals( "<init>" ) && method.getType().equals( "()V" )
&& code.isSuperInitReturn( classFile.getSuperClass() ) ) { && code.isSuperInitReturn( classFile.getSuperClass() ) ) {
continue; //default constructor continue; //default constructor
} }
@ -149,7 +149,7 @@ public class ModuleGenerator {
writeExport( name, method ); writeExport( name, method );
writer.writeMethodStart( name ); writer.writeMethodStart( name );
codeBuilder.buildCode( code, !method.getDescription().endsWith( ")V" ) ); codeBuilder.buildCode( code, !method.getType().endsWith( ")V" ) );
writeMethodSignature( method, code.getLocalVariableTable(), codeBuilder ); writeMethodSignature( method, code.getLocalVariableTable(), codeBuilder );
for( WasmInstruction instruction : codeBuilder.getInstructions() ) { for( WasmInstruction instruction : codeBuilder.getInstructions() ) {
@ -200,7 +200,7 @@ public class ModuleGenerator {
* if some Java code can't converted * if some Java code can't converted
*/ */
private void writeMethodSignature( MethodInfo method, @Nullable LocalVariableTable variables, WasmCodeBuilder codeBuilder ) throws IOException, WasmException { private void writeMethodSignature( MethodInfo method, @Nullable LocalVariableTable variables, WasmCodeBuilder codeBuilder ) throws IOException, WasmException {
String signature = method.getDescription(); String signature = method.getType();
String kind = "param"; String kind = "param";
int paramCount = 0; int paramCount = 0;
ValueType type = null; ValueType type = null;

View File

@ -21,7 +21,7 @@ import java.io.IOException;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import de.inetsoftware.classparser.ConstantRef; import de.inetsoftware.classparser.Member;
/** /**
* Module Writer base class. * Module Writer base class.
@ -156,7 +156,7 @@ public abstract class ModuleWriter implements Closeable {
* @throws IOException * @throws IOException
* if any I/O error occur * if any I/O error occur
*/ */
protected abstract void writeGlobalAccess( boolean load, FunctionName name, ConstantRef ref ) throws IOException; protected abstract void writeGlobalAccess( boolean load, FunctionName name, Member ref ) throws IOException;
/** /**

View File

@ -20,7 +20,7 @@ import java.io.IOException;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import de.inetsoftware.classparser.ConstantRef; import de.inetsoftware.classparser.Member;
/** /**
* WasmInstruction for a function call. * WasmInstruction for a function call.
@ -30,7 +30,7 @@ import de.inetsoftware.classparser.ConstantRef;
*/ */
class WasmCallInstruction extends WasmInstruction { class WasmCallInstruction extends WasmInstruction {
private final ConstantRef method; private final Member method;
private final ValueType valueType; private final ValueType valueType;
@ -42,11 +42,11 @@ class WasmCallInstruction extends WasmInstruction {
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
*/ */
WasmCallInstruction( ConstantRef method, int javaCodePos ) { WasmCallInstruction( Member method, int javaCodePos ) {
super( javaCodePos ); super( javaCodePos );
this.method = method; this.method = method;
String signature = method.getType(); String signature = method.getType();
this.valueType = ValueType.getValueType( signature, signature.indexOf( ')' ) + 1 ); this.valueType = ValueType.getValueType( signature, signature.indexOf( ')' ) + 1 );
} }
/** /**
@ -56,7 +56,6 @@ class WasmCallInstruction extends WasmInstruction {
writer.writeFunctionCall( new FunctionName( method ).signatureName ); writer.writeFunctionCall( new FunctionName( method ).signatureName );
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -77,8 +76,8 @@ class WasmCallInstruction extends WasmInstruction {
return paramCount; return paramCount;
} }
paramCount++; paramCount++;
ValueType.getValueType( signature, i ); ValueType.getValueType( signature, i );
} }
throw new Error(); throw new Error();
} }
} }

View File

@ -77,15 +77,30 @@ public abstract class WasmCodeBuilder {
* the value type * the value type
* @param load * @param load
* true: if load * true: if load
* @param idx * @param javaIdx
* the memory/slot idx of the variable * the memory/slot index of the variable in Java byte code
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
*/ */
@Nonnull @Nonnull
protected void addLoadStoreInstruction( ValueType valueType, boolean load, @Nonnegative int idx, int javaCodePos ) { protected void addLoadStoreInstruction( ValueType valueType, boolean load, @Nonnegative int javaIdx, int javaCodePos ) {
localVariables.use( valueType, idx ); localVariables.use( valueType, javaIdx );
instructions.add( new WasmLoadStoreInstruction( load, idx, localVariables, javaCodePos ) ); instructions.add( new WasmLoadStoreInstruction( load, javaIdx, localVariables, javaCodePos ) );
}
/**
* Create a WasmLoadStoreInstruction get_local/set_local.
*
* @param load
* true: if load
* @param wasmIdx
* the index of the variable
* @param javaCodePos
* the code position/offset in the Java method
*/
@Nonnull
protected void addLoadStoreInstruction( boolean load, @Nonnegative int wasmIdx, int javaCodePos ) {
instructions.add( new WasmLoadStoreInstruction( load, wasmIdx, null, javaCodePos ) );
} }
/** /**

View File

@ -20,7 +20,7 @@ import java.io.IOException;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import de.inetsoftware.classparser.ConstantRef; import de.inetsoftware.classparser.Member;
/** /**
* WasmInstruction for set and get global variables. * WasmInstruction for set and get global variables.
@ -30,9 +30,9 @@ import de.inetsoftware.classparser.ConstantRef;
*/ */
class WasmGlobalInstruction extends WasmInstruction { class WasmGlobalInstruction extends WasmInstruction {
private boolean load; private boolean load;
private ConstantRef ref; private Member ref;
/** /**
* Create an instance of a load/store instruction * Create an instance of a load/store instruction
@ -44,7 +44,7 @@ class WasmGlobalInstruction extends WasmInstruction {
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
*/ */
WasmGlobalInstruction( boolean load, ConstantRef ref, int javaCodePos ) { WasmGlobalInstruction( boolean load, Member ref, int javaCodePos ) {
super( javaCodePos ); super( javaCodePos );
this.load = load; this.load = load;
this.ref = ref; this.ref = ref;

View File

@ -22,7 +22,7 @@ import java.util.HashSet;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import de.inetsoftware.classparser.ConstantRef; import de.inetsoftware.classparser.Member;
import de.inetsoftware.jwebassembly.JWebAssembly; import de.inetsoftware.jwebassembly.JWebAssembly;
import de.inetsoftware.jwebassembly.module.FunctionName; import de.inetsoftware.jwebassembly.module.FunctionName;
import de.inetsoftware.jwebassembly.module.ModuleWriter; import de.inetsoftware.jwebassembly.module.ModuleWriter;
@ -176,7 +176,7 @@ public class TextModuleWriter extends ModuleWriter {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
protected void writeGlobalAccess( boolean load, FunctionName name, ConstantRef ref ) throws IOException { protected void writeGlobalAccess( boolean load, FunctionName name, Member ref ) throws IOException {
if( !globals.contains( name.fullName ) ) { if( !globals.contains( name.fullName ) ) {
// declare global variable if not already declared. // declare global variable if not already declared.
output.append( "\n " ); output.append( "\n " );