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} * {@inheritDoc}
*/ */
@Override @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; int opCode;
switch(op) { switch(op) {
case NEW: case NEW:

View File

@ -59,10 +59,10 @@ class StructTypeEntry extends TypeEntry {
stream.writeVaruint32( this.fields.size() ); stream.writeVaruint32( this.fields.size() );
for( NamedStorageType field : this.fields ) { for( NamedStorageType field : this.fields ) {
stream.writeVarint( 1 ); // 0 - immutable; 1 - mutable stream.writeVarint( 1 ); // 0 - immutable; 1 - mutable
if( field.type.getCode() > 0 ) { if( field.getType().getCode() > 0 ) {
stream.writeValueType( ValueType.ref_type ); 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 * the name of the field
* @return the index * @return the index
*/ */
int getFieldIdx( @Nonnull String fieldName ) { int getFieldIdx( @Nonnull NamedStorageType fieldName ) {
for( int i = 0; i < fields.size(); i++ ) { int idx = fields.indexOf( fieldName );
NamedStorageType field = fields.get( i ); if( idx >= 0 ) {
if( field.name.equals( fieldName ) ) { return idx;
return i; }
}
}
throw new WasmException( fieldName + " not found", -1 ); 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.WasmException;
import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.ArrayOperator; import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.NumericOperator; import de.inetsoftware.jwebassembly.wasm.NumericOperator;
import de.inetsoftware.jwebassembly.wasm.StructOperator; import de.inetsoftware.jwebassembly.wasm.StructOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType; import de.inetsoftware.jwebassembly.wasm.ValueType;
@ -567,11 +568,11 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
break; break;
case 180: // getfield case 180: // getfield
ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() ); 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; break;
case 181: // putfield case 181: // putfield
ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() ); 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; break;
case 182: // invokevirtual case 182: // invokevirtual
case 183: // invokespecial, invoke a constructor 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.ClassFile;
import de.inetsoftware.classparser.Code; import de.inetsoftware.classparser.Code;
import de.inetsoftware.classparser.ConstantClass;
import de.inetsoftware.classparser.FieldInfo; import de.inetsoftware.classparser.FieldInfo;
import de.inetsoftware.classparser.MethodInfo; import de.inetsoftware.classparser.MethodInfo;
import de.inetsoftware.jwebassembly.JWebAssembly; 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.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.StructOperator; import de.inetsoftware.jwebassembly.wasm.StructOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType; import de.inetsoftware.jwebassembly.wasm.ValueType;
import de.inetsoftware.jwebassembly.wasm.ValueTypeParser;
import de.inetsoftware.jwebassembly.watparser.WatParser; import de.inetsoftware.jwebassembly.watparser.WatParser;
/** /**
@ -225,26 +225,47 @@ public class ModuleGenerator {
*/ */
private void writeStructType( StructType type ) throws IOException { private void writeStructType( StructType type ) throws IOException {
String className = type.getName(); 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" ); InputStream stream = libraries.getResourceAsStream( className + ".class" );
if( stream == null ) { if( stream == null ) {
throw new WasmException( "Missing class: " + className, -1 ); throw new WasmException( "Missing class: " + className, -1 );
} }
ClassFile classFile = new ClassFile( stream ); 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(); FieldInfo[] fields = classFile.getFields();
for( FieldInfo field : fields ) { for( FieldInfo field : fields ) {
if( field.isStatic() ) { if( field.isStatic() ) {
continue; continue;
} }
AnyType fieldtype = new ValueTypeParser( field.getType(), types ).next(); list.add( new NamedStorageType( className, field ) );
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 );
}
} }
} }
@ -392,8 +413,8 @@ public class ModuleGenerator {
if( instr.getOperator() == StructOperator.NEW_DEFAULT ) { if( instr.getOperator() == StructOperator.NEW_DEFAULT ) {
List<NamedStorageType> list = instr.getStructType().getFields(); List<NamedStorageType> list = instr.getStructType().getFields();
for( NamedStorageType storageType : list ) { for( NamedStorageType storageType : list ) {
if( storageType.type.getCode() < 0 ) { if( storageType.getType().getCode() < 0 ) {
ValueType type = (ValueType)storageType.type; ValueType type = (ValueType)storageType.getType();
switch( type ) { switch( type ) {
case i32: case i32:
case i64: case i64:
@ -405,6 +426,9 @@ public class ModuleGenerator {
case i16: case i16:
writer.writeConst( 0, ValueType.i32 ); writer.writeConst( 0, ValueType.i32 );
break; break;
case anyref:
writer.writeStructOperator( StructOperator.NULL, null, null );
break;
default: default:
throw new WasmException( "Not supported storage type: " + type, instruction.getLineNumber() ); 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 javax.annotation.Nullable;
import de.inetsoftware.classparser.Member; import de.inetsoftware.classparser.Member;
import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.ArrayOperator; import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType; import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.NumericOperator; import de.inetsoftware.jwebassembly.wasm.NumericOperator;
import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.StructOperator; import de.inetsoftware.jwebassembly.wasm.StructOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType; import de.inetsoftware.jwebassembly.wasm.ValueType;
import de.inetsoftware.jwebassembly.wasm.VariableOperator; import de.inetsoftware.jwebassembly.wasm.VariableOperator;
@ -251,5 +251,5 @@ 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 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.module.WasmInstruction.Type;
import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.ArrayOperator; import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.NumericOperator; import de.inetsoftware.jwebassembly.wasm.NumericOperator;
import de.inetsoftware.jwebassembly.wasm.StructOperator; import de.inetsoftware.jwebassembly.wasm.StructOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType; import de.inetsoftware.jwebassembly.wasm.ValueType;
@ -318,7 +319,7 @@ public abstract class WasmCodeBuilder {
* @param lineNumber * @param lineNumber
* the line number in the Java source code * 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 ) ); 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.WasmException;
import de.inetsoftware.jwebassembly.module.TypeManager.StructType; import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.StructOperator; import de.inetsoftware.jwebassembly.wasm.StructOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType; import de.inetsoftware.jwebassembly.wasm.ValueType;
@ -35,11 +36,11 @@ import de.inetsoftware.jwebassembly.wasm.ValueType;
*/ */
class WasmStructInstruction extends WasmInstruction { 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. * Create an instance of numeric operation.
@ -55,7 +56,7 @@ class WasmStructInstruction extends WasmInstruction {
* @param lineNumber * @param lineNumber
* the line number in the Java source code * 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 ); super( javaCodePos, lineNumber );
this.op = op; this.op = op;
this.type = type; 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.FunctionName;
import de.inetsoftware.jwebassembly.module.ModuleWriter; import de.inetsoftware.jwebassembly.module.ModuleWriter;
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion; import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.ArrayOperator; import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType; import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.NumericOperator; import de.inetsoftware.jwebassembly.wasm.NumericOperator;
import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.StructOperator; import de.inetsoftware.jwebassembly.wasm.StructOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType; import de.inetsoftware.jwebassembly.wasm.ValueType;
import de.inetsoftware.jwebassembly.wasm.VariableOperator; import de.inetsoftware.jwebassembly.wasm.VariableOperator;
@ -108,11 +108,11 @@ public class TextModuleWriter extends ModuleWriter {
for( NamedStorageType field : fields ) { for( NamedStorageType field : fields ) {
newline( output ); newline( output );
output.append( "(field" ); output.append( "(field" );
if( debugNames && field.name != null ) { if( debugNames && field.getUniqueName() != null ) {
output.append( " $" ).append( field.name ); output.append( " $" ).append( normalizeName( field.getUniqueName() ) );
} }
output.append( " (mut " ); output.append( " (mut " );
AnyType type = field.type; AnyType type = field.getType();
if( type.getCode() < 0 ) { if( type.getCode() < 0 ) {
output.append( type.toString() ); output.append( type.toString() );
} else { } else {
@ -545,7 +545,7 @@ public class TextModuleWriter extends ModuleWriter {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @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; String operation;
switch( op ) { switch( op ) {
case NEW: case NEW:
@ -571,7 +571,7 @@ public class TextModuleWriter extends ModuleWriter {
methodOutput.append( ' ' ).append( normalizeName( type.toString() ) ); methodOutput.append( ' ' ).append( normalizeName( type.toString() ) );
} }
if( fieldName != null ) { if( fieldName != null ) {
methodOutput.append( " $" ).append( fieldName ); methodOutput.append( " $" ).append( normalizeName( fieldName.getUniqueName() ) );
} }
} }
} }

View File

@ -15,6 +15,9 @@
*/ */
package de.inetsoftware.jwebassembly.wasm; package de.inetsoftware.jwebassembly.wasm;
import de.inetsoftware.classparser.ConstantRef;
import de.inetsoftware.classparser.FieldInfo;
/** /**
* A ValueType with a name for debug information. * A ValueType with a name for debug information.
* *
@ -22,17 +25,87 @@ package de.inetsoftware.jwebassembly.wasm;
*/ */
public class NamedStorageType { public class NamedStorageType {
public final AnyType type; private final AnyType type;
public final String name; private final String name;
/** /**
* Create a new instance * 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 ) { public NamedStorageType( String className, FieldInfo field ) {
this.type = type; 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; 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 );
}
} }