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)
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;
/**
* @author Volker Berlin
*/
public abstract class ConstantRef {
private final ConstantClass constClass;
private final ConstantNameAndType nameAndType;
ConstantRef( ConstantClass constClass, ConstantNameAndType nameAndType ) {
this.constClass = constClass;
this.nameAndType = nameAndType;
}
public String getName() {
return nameAndType.getName();
}
/**
* Get the type of the method. For example "(Ljava.lang.String;)I"
*/
public String getType() {
return nameAndType.getType();
}
public ConstantClass getConstantClass() {
return constClass;
}
}
/*
Copyright 2017 - 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;
/**
* A reference to an member that is described in the constant pool of a Java class.
*
* @author Volker Berlin
*/
public abstract class ConstantRef implements Member {
private final ConstantClass constClass;
private final ConstantNameAndType nameAndType;
/**
* Create a new instance.
*
* @param constClass
* the class description
* @param nameAndType
* the name and type description
*/
ConstantRef( ConstantClass constClass, ConstantNameAndType nameAndType ) {
this.constClass = constClass;
this.nameAndType = nameAndType;
}
/**
* {@inheritDoc}
*/
@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
*/
public class MethodInfo {
public class MethodInfo implements Member {
private final int accessFlags;
@ -99,10 +99,19 @@ public class MethodInfo {
/**
* @return the name
*/
@Override
public String getName() {
return name;
}
/**
* {@inheritDoc}
*/
@Override
public String getClassName() {
return getDeclaringClassFile().getThisClass().getName();
}
/**
* @return the attributes
*/
@ -125,7 +134,8 @@ public class MethodInfo {
/**
* Get the signature of the method without generic types.
*/
public String getDescription() {
@Override
public String getType() {
return description;
}

View File

@ -29,7 +29,7 @@ import java.util.Map.Entry;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import de.inetsoftware.classparser.ConstantRef;
import de.inetsoftware.classparser.Member;
import de.inetsoftware.jwebassembly.JWebAssembly;
import de.inetsoftware.jwebassembly.WasmException;
import de.inetsoftware.jwebassembly.module.FunctionName;
@ -356,7 +356,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
* {@inheritDoc}
*/
@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 );
if( var == null ) { // if not declared then create a definition in the global section
var = new Global();

View File

@ -18,8 +18,7 @@ package de.inetsoftware.jwebassembly.module;
import javax.annotation.Nonnull;
import de.inetsoftware.classparser.ConstantRef;
import de.inetsoftware.classparser.MethodInfo;
import de.inetsoftware.classparser.Member;
/**
* Described the name of WebAssembly function.
@ -40,28 +39,15 @@ public class FunctionName {
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
*/
FunctionName( @Nonnull MethodInfo method ) {
String methodName = method.getName();
String className = method.getDeclaringClassFile().getThisClass().getName();
FunctionName( @Nonnull Member methodOrField ) {
String methodName = methodOrField.getName();
String className = methodOrField.getClassName();
fullName = className + '.' + methodName;
signatureName = fullName + method.getDescription();
}
/**
* 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();
signatureName = fullName + methodOrField.getType();
}
}

View File

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

View File

@ -21,7 +21,7 @@ import java.io.IOException;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import de.inetsoftware.classparser.ConstantRef;
import de.inetsoftware.classparser.Member;
/**
* Module Writer base class.
@ -156,7 +156,7 @@ public abstract class ModuleWriter implements Closeable {
* @throws IOException
* 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 de.inetsoftware.classparser.ConstantRef;
import de.inetsoftware.classparser.Member;
/**
* WasmInstruction for a function call.
@ -30,7 +30,7 @@ import de.inetsoftware.classparser.ConstantRef;
*/
class WasmCallInstruction extends WasmInstruction {
private final ConstantRef method;
private final Member method;
private final ValueType valueType;
@ -42,11 +42,11 @@ class WasmCallInstruction extends WasmInstruction {
* @param javaCodePos
* the code position/offset in the Java method
*/
WasmCallInstruction( ConstantRef method, int javaCodePos ) {
WasmCallInstruction( Member method, int javaCodePos ) {
super( javaCodePos );
this.method = method;
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 );
}
/**
* {@inheritDoc}
*/
@ -77,8 +76,8 @@ class WasmCallInstruction extends WasmInstruction {
return 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
* @param load
* true: if load
* @param idx
* the memory/slot idx of the variable
* @param javaIdx
* the memory/slot index of the variable in Java byte code
* @param javaCodePos
* the code position/offset in the Java method
*/
@Nonnull
protected void addLoadStoreInstruction( ValueType valueType, boolean load, @Nonnegative int idx, int javaCodePos ) {
localVariables.use( valueType, idx );
instructions.add( new WasmLoadStoreInstruction( load, idx, localVariables, javaCodePos ) );
protected void addLoadStoreInstruction( ValueType valueType, boolean load, @Nonnegative int javaIdx, int javaCodePos ) {
localVariables.use( valueType, javaIdx );
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 de.inetsoftware.classparser.ConstantRef;
import de.inetsoftware.classparser.Member;
/**
* WasmInstruction for set and get global variables.
@ -30,9 +30,9 @@ import de.inetsoftware.classparser.ConstantRef;
*/
class WasmGlobalInstruction extends WasmInstruction {
private boolean load;
private boolean load;
private ConstantRef ref;
private Member ref;
/**
* Create an instance of a load/store instruction
@ -44,7 +44,7 @@ class WasmGlobalInstruction extends WasmInstruction {
* @param javaCodePos
* the code position/offset in the Java method
*/
WasmGlobalInstruction( boolean load, ConstantRef ref, int javaCodePos ) {
WasmGlobalInstruction( boolean load, Member ref, int javaCodePos ) {
super( javaCodePos );
this.load = load;
this.ref = ref;

View File

@ -22,7 +22,7 @@ import java.util.HashSet;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import de.inetsoftware.classparser.ConstantRef;
import de.inetsoftware.classparser.Member;
import de.inetsoftware.jwebassembly.JWebAssembly;
import de.inetsoftware.jwebassembly.module.FunctionName;
import de.inetsoftware.jwebassembly.module.ModuleWriter;
@ -176,7 +176,7 @@ public class TextModuleWriter extends ModuleWriter {
* {@inheritDoc}
*/
@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 ) ) {
// declare global variable if not already declared.
output.append( "\n " );