Write also the fields of super classes in the struct description.

This commit is contained in:
Volker Berlin 2019-04-21 21:33:22 +02:00
parent 13fce427c3
commit 02a2e9d8ff
9 changed files with 142 additions and 44 deletions

View File

@ -1018,7 +1018,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
* {@inheritDoc}
*/
@Override
protected void writeStructOperator( StructOperator op, AnyType type, String fieldName ) throws IOException {
protected void writeStructOperator( StructOperator op, AnyType type, NamedStorageType fieldName ) throws IOException {
int opCode;
switch(op) {
case NEW:

View File

@ -59,10 +59,10 @@ class StructTypeEntry extends TypeEntry {
stream.writeVaruint32( this.fields.size() );
for( NamedStorageType field : this.fields ) {
stream.writeVarint( 1 ); // 0 - immutable; 1 - mutable
if( field.type.getCode() > 0 ) {
if( field.getType().getCode() > 0 ) {
stream.writeValueType( ValueType.ref_type );
}
stream.writeValueType( field.type );
stream.writeValueType( field.getType() );
}
}
@ -73,13 +73,11 @@ class StructTypeEntry extends TypeEntry {
* the name of the field
* @return the index
*/
int getFieldIdx( @Nonnull String fieldName ) {
for( int i = 0; i < fields.size(); i++ ) {
NamedStorageType field = fields.get( i );
if( field.name.equals( fieldName ) ) {
return i;
}
}
int getFieldIdx( @Nonnull NamedStorageType fieldName ) {
int idx = fields.indexOf( fieldName );
if( idx >= 0 ) {
return idx;
}
throw new WasmException( fieldName + " not found", -1 );
}

View File

@ -28,6 +28,7 @@ import de.inetsoftware.classparser.ConstantRef;
import de.inetsoftware.jwebassembly.WasmException;
import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.NumericOperator;
import de.inetsoftware.jwebassembly.wasm.StructOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType;
@ -567,11 +568,11 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
break;
case 180: // getfield
ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
addStructInstruction( StructOperator.GET, ref.getClassName(), ref.getName(), codePos, lineNumber );
addStructInstruction( StructOperator.GET, ref.getClassName(), new NamedStorageType( ref ), codePos, lineNumber );
break;
case 181: // putfield
ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
addStructInstruction( StructOperator.SET, ref.getClassName(), ref.getName(), codePos, lineNumber );
addStructInstruction( StructOperator.SET, ref.getClassName(), new NamedStorageType( ref ), codePos, lineNumber );
break;
case 182: // invokevirtual
case 183: // invokespecial, invoke a constructor

View File

@ -35,6 +35,7 @@ import javax.annotation.Nonnull;
import de.inetsoftware.classparser.ClassFile;
import de.inetsoftware.classparser.Code;
import de.inetsoftware.classparser.ConstantClass;
import de.inetsoftware.classparser.FieldInfo;
import de.inetsoftware.classparser.MethodInfo;
import de.inetsoftware.jwebassembly.JWebAssembly;
@ -44,7 +45,6 @@ import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.StructOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType;
import de.inetsoftware.jwebassembly.wasm.ValueTypeParser;
import de.inetsoftware.jwebassembly.watparser.WatParser;
/**
@ -225,26 +225,47 @@ public class ModuleGenerator {
*/
private void writeStructType( StructType type ) throws IOException {
String className = type.getName();
List<NamedStorageType> list = new ArrayList<>();
listStructFields( className, list );
int id = writer.writeStruct( className, list );
types.useType( type, id, list );
for( NamedStorageType namedType : list ) {
if( namedType.getType().getCode() == Integer.MAX_VALUE ) {
writeStructType( (StructType)namedType.getType() );
}
}
}
/**
* List the non static fields of the class and its superclasses.
*
* @param className
* the className
* @param list
* the container for the fields
* @throws IOException
* if any I/O error occur
*/
private void listStructFields( String className, List<NamedStorageType> list ) throws IOException {
InputStream stream = libraries.getResourceAsStream( className + ".class" );
if( stream == null ) {
throw new WasmException( "Missing class: " + className, -1 );
}
ClassFile classFile = new ClassFile( stream );
List<NamedStorageType> list = new ArrayList<>();
ConstantClass superClass = classFile.getSuperClass();
if( superClass != null ) {
String superClassName = superClass.getName();
listStructFields( superClassName, list );
}
FieldInfo[] fields = classFile.getFields();
for( FieldInfo field : fields ) {
if( field.isStatic() ) {
continue;
}
AnyType fieldtype = new ValueTypeParser( field.getType(), types ).next();
list.add( new NamedStorageType( fieldtype, field.getName() ) );
}
int id = writer.writeStruct( className, list );
types.useType( type, id, list );
for( NamedStorageType namedType : list ) {
if( namedType.type.getCode() == Integer.MAX_VALUE ) {
writeStructType( (StructType)namedType.type );
}
list.add( new NamedStorageType( className, field ) );
}
}
@ -392,8 +413,8 @@ public class ModuleGenerator {
if( instr.getOperator() == StructOperator.NEW_DEFAULT ) {
List<NamedStorageType> list = instr.getStructType().getFields();
for( NamedStorageType storageType : list ) {
if( storageType.type.getCode() < 0 ) {
ValueType type = (ValueType)storageType.type;
if( storageType.getType().getCode() < 0 ) {
ValueType type = (ValueType)storageType.getType();
switch( type ) {
case i32:
case i64:
@ -405,6 +426,9 @@ public class ModuleGenerator {
case i16:
writer.writeConst( 0, ValueType.i32 );
break;
case anyref:
writer.writeStructOperator( StructOperator.NULL, null, null );
break;
default:
throw new WasmException( "Not supported storage type: " + type, instruction.getLineNumber() );
}

View File

@ -23,10 +23,10 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import de.inetsoftware.classparser.Member;
import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.NumericOperator;
import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.StructOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType;
import de.inetsoftware.jwebassembly.wasm.VariableOperator;
@ -251,5 +251,5 @@ public abstract class ModuleWriter implements Closeable {
* @throws IOException
* if any I/O error occur
*/
protected abstract void writeStructOperator( StructOperator op, AnyType type, String fieldName ) throws IOException;
protected abstract void writeStructOperator( StructOperator op, AnyType type, NamedStorageType fieldName ) throws IOException;
}

View File

@ -27,6 +27,7 @@ import de.inetsoftware.classparser.Member;
import de.inetsoftware.jwebassembly.module.WasmInstruction.Type;
import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.NumericOperator;
import de.inetsoftware.jwebassembly.wasm.StructOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType;
@ -318,7 +319,7 @@ public abstract class WasmCodeBuilder {
* @param lineNumber
* the line number in the Java source code
*/
protected void addStructInstruction( StructOperator op, @Nullable String typeName, @Nullable String fieldName, int javaCodePos, int lineNumber ) {
protected void addStructInstruction( StructOperator op, @Nullable String typeName, @Nullable NamedStorageType fieldName, int javaCodePos, int lineNumber ) {
instructions.add( new WasmStructInstruction( op, typeName == null ? null : types.valueOf( typeName ), fieldName, javaCodePos, lineNumber ) );
}
}

View File

@ -24,6 +24,7 @@ import javax.annotation.Nullable;
import de.inetsoftware.jwebassembly.WasmException;
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.StructOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType;
@ -35,11 +36,11 @@ import de.inetsoftware.jwebassembly.wasm.ValueType;
*/
class WasmStructInstruction extends WasmInstruction {
private final StructOperator op;
private final StructOperator op;
private final StructType type;
private final StructType type;
private final String fieldName;
private final NamedStorageType fieldName;
/**
* Create an instance of numeric operation.
@ -55,7 +56,7 @@ class WasmStructInstruction extends WasmInstruction {
* @param lineNumber
* the line number in the Java source code
*/
WasmStructInstruction( @Nullable StructOperator op, @Nullable StructType type, @Nullable String fieldName, int javaCodePos, int lineNumber ) {
WasmStructInstruction( @Nullable StructOperator op, @Nullable StructType type, @Nullable NamedStorageType fieldName, int javaCodePos, int lineNumber ) {
super( javaCodePos, lineNumber );
this.op = op;
this.type = type;

View File

@ -29,10 +29,10 @@ import de.inetsoftware.jwebassembly.JWebAssembly;
import de.inetsoftware.jwebassembly.module.FunctionName;
import de.inetsoftware.jwebassembly.module.ModuleWriter;
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.NumericOperator;
import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.StructOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType;
import de.inetsoftware.jwebassembly.wasm.VariableOperator;
@ -108,11 +108,11 @@ public class TextModuleWriter extends ModuleWriter {
for( NamedStorageType field : fields ) {
newline( output );
output.append( "(field" );
if( debugNames && field.name != null ) {
output.append( " $" ).append( field.name );
if( debugNames && field.getUniqueName() != null ) {
output.append( " $" ).append( normalizeName( field.getUniqueName() ) );
}
output.append( " (mut " );
AnyType type = field.type;
AnyType type = field.getType();
if( type.getCode() < 0 ) {
output.append( type.toString() );
} else {
@ -545,7 +545,7 @@ public class TextModuleWriter extends ModuleWriter {
* {@inheritDoc}
*/
@Override
protected void writeStructOperator( StructOperator op, AnyType type, String fieldName ) throws IOException {
protected void writeStructOperator( StructOperator op, AnyType type, NamedStorageType fieldName ) throws IOException {
String operation;
switch( op ) {
case NEW:
@ -571,7 +571,7 @@ public class TextModuleWriter extends ModuleWriter {
methodOutput.append( ' ' ).append( normalizeName( type.toString() ) );
}
if( fieldName != null ) {
methodOutput.append( " $" ).append( fieldName );
methodOutput.append( " $" ).append( normalizeName( fieldName.getUniqueName() ) );
}
}
}

View File

@ -15,6 +15,9 @@
*/
package de.inetsoftware.jwebassembly.wasm;
import de.inetsoftware.classparser.ConstantRef;
import de.inetsoftware.classparser.FieldInfo;
/**
* A ValueType with a name for debug information.
*
@ -22,17 +25,87 @@ package de.inetsoftware.jwebassembly.wasm;
*/
public class NamedStorageType {
public final AnyType type;
private final AnyType type;
public final String name;
private final String name;
/**
* Create a new instance
* @param type the type
* @param name the name
*
* @param className
* the parent className of the field
* @param field
* the FieldInfo
*/
public NamedStorageType( AnyType type, String name ) {
this.type = type;
public NamedStorageType( String className, FieldInfo field ) {
this( field.getType(), className + '.' + field.getName() );
}
/**
* Create a new instance
*
* @param ref
* the reference
*/
public NamedStorageType( ConstantRef ref ) {
this( ref.getType(), ref.getClassName() + '.' + ref.getName() );
}
/**
* Create a new instance
*
* @param type
* the type
* @param name
* the name
*/
private NamedStorageType( String type, String name ) {
this.type = new ValueTypeParser( type ).next();
this.name = name;
}
/**
* Get the type.
*
* @return the type
*/
public AnyType getType() {
return type;
}
/**
* Get the global unique name of the field. See
* https://github.com/lars-t-hansen/moz-gc-experiments/blob/master/version2.md#struct-and-ref-types
*
* @return the name
*/
public String getUniqueName() {
return name;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return name.hashCode();
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals( Object obj ) {
if( this == obj ) {
return true;
}
if( obj == null ) {
return false;
}
if( getClass() != obj.getClass() ) {
return false;
}
NamedStorageType other = (NamedStorageType)obj;
return name.equals( other.name );
}
}