write the struct type into the type section

This commit is contained in:
Volker Berlin 2019-01-06 16:29:26 +01:00
parent efef0b03d5
commit 56fdf9018d
9 changed files with 164 additions and 64 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2017 - 2018 Volker Berlin (i-net software)
* Copyright 2017 - 2019 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.
@ -35,6 +35,7 @@ import de.inetsoftware.jwebassembly.module.FunctionName;
import de.inetsoftware.jwebassembly.module.ModuleWriter;
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.NumericOperator;
import de.inetsoftware.jwebassembly.wasm.StorageType;
import de.inetsoftware.jwebassembly.wasm.StructOperator;
@ -58,7 +59,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
private WasmOutputStream codeStream = new WasmOutputStream();
private List<FunctionType> functionTypes = new ArrayList<>();
private List<TypeEntry> functionTypes = new ArrayList<>();
private Map<String, Function> functions = new LinkedHashMap<>();
@ -226,6 +227,16 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
wasm.writeSection( SectionType.Custom, stream );
}
/**
* {@inheritDoc}
*/
@Override
protected int writeStruct( String typeName, List<NamedStorageType> fields ) throws IOException {
int typeId = functionTypes.size();
functionTypes.add( new StructType( fields ) );
return typeId;
}
/**
* {@inheritDoc}
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright 2017 - 2018 Volker Berlin (i-net software)
* Copyright 2017 - 2019 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.
@ -18,7 +18,6 @@ package de.inetsoftware.jwebassembly.binary;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import de.inetsoftware.jwebassembly.wasm.ValueType;
@ -27,7 +26,7 @@ import de.inetsoftware.jwebassembly.wasm.ValueType;
*
* @author Volker Berlin
*/
class FunctionType extends SectionEntry {
class FunctionType extends TypeEntry {
final List<ValueType> params = new ArrayList<>();
@ -37,8 +36,15 @@ class FunctionType extends SectionEntry {
* {@inheritDoc}
*/
@Override
void writeSectionEntry( WasmOutputStream stream ) throws IOException {
stream.writeValueType( ValueType.func );
ValueType getTypeForm() {
return ValueType.func;
}
/**
* {@inheritDoc}
*/
@Override
void writeSectionEntryDetails( WasmOutputStream stream ) throws IOException {
stream.writeVaruint32( this.params.size() );
for( ValueType valueType : this.params ) {
stream.writeValueType( valueType );

View File

@ -1,5 +1,5 @@
/*
* Copyright 2018 Volker Berlin (i-net software)
* Copyright 2018 - 2019 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.
@ -26,10 +26,8 @@ import de.inetsoftware.classparser.ConstantClass;
import de.inetsoftware.classparser.ConstantPool;
import de.inetsoftware.classparser.ConstantRef;
import de.inetsoftware.jwebassembly.WasmException;
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
import de.inetsoftware.jwebassembly.wasm.NumericOperator;
import de.inetsoftware.jwebassembly.wasm.StorageType;
import de.inetsoftware.jwebassembly.wasm.StructOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType;
import de.inetsoftware.jwebassembly.wasm.WasmBlockOperator;
@ -92,7 +90,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
case 0: // nop
break;
case 1: // aconst_null
addStructInstruction( StructOperator.NULL, ValueType.anyref, codePos );
addStructInstruction( StructOperator.NULL, null, codePos );
break;
case 2: // iconst_m1
case 3: // iconst_0
@ -261,6 +259,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
case anyref:
addCallInstruction( new SyntheticMember( "de/inetsoftware/jwebassembly/module/NativeHelperCode", "dup_anyref", "(Ljava.lang.Object;)Ljava.lang.Object;Ljava.lang.Object;" ), codePos );
break OP;
default:
}
//$FALL-THROUGH$
case 90: // dup_x1
@ -546,8 +545,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
//TODO case 186: // invokedynamic
case 187: // new
String name = ((ConstantClass)constantPool.get( byteCode.readUnsignedShort() )).getName();
StorageType storageType = new StructType(name);
addStructInstruction( StructOperator.NEW_DEFAULT, storageType, codePos );
addStructInstruction( StructOperator.NEW_DEFAULT, name, codePos );
break;
case 188: // newarray
int typeValue = byteCode.readByte();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2017 - 2018 Volker Berlin (i-net software)
* Copyright 2017 - 2019 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.
@ -19,6 +19,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
@ -29,10 +30,14 @@ import javax.annotation.Nullable;
import de.inetsoftware.classparser.ClassFile;
import de.inetsoftware.classparser.Code;
import de.inetsoftware.classparser.CodeInputStream;
import de.inetsoftware.classparser.FieldInfo;
import de.inetsoftware.classparser.LocalVariableTable;
import de.inetsoftware.classparser.MethodInfo;
import de.inetsoftware.jwebassembly.JWebAssembly;
import de.inetsoftware.jwebassembly.WasmException;
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.StorageType;
import de.inetsoftware.jwebassembly.wasm.ValueType;
import de.inetsoftware.jwebassembly.wasm.ValueTypeParser;
import de.inetsoftware.jwebassembly.watparser.WatParser;
@ -134,6 +139,41 @@ public class ModuleGenerator {
}
}
/**
* Set the StructType into the instruction and write the types/structs if needed.
*
* @param instruction
* the struct instruction
* @throws IOException
* if any I/O error occur
*/
private void setStructType( WasmStructInstruction instruction ) throws IOException {
String name = instruction.getTypeName();
if( name != null ) {
StructType type = types.valueOf( name );
if( type.getCode() == Integer.MIN_VALUE ) {
String className = name;
InputStream stream = libraries.getResourceAsStream( className + ".class" );
if( stream == null ) {
throw new WasmException( "Missing class: " + className, -1 );
}
ClassFile classFile = new ClassFile( stream );
ArrayList<NamedStorageType> list = new ArrayList<>();
FieldInfo[] fields = classFile.getFields();
for( FieldInfo field : fields ) {
if( field.isStatic() ) {
continue;
}
StorageType fieldtype = new ValueTypeParser( field.getType() ).next();
list.add( new NamedStorageType( fieldtype, field.getName() ) );
}
int id = writer.writeStruct( className, list );
types.useType( type, id );
}
instruction.setType( type );
}
}
/**
* Iterate over all methods of the classFile and run the handler.
*
@ -240,7 +280,8 @@ public class ModuleGenerator {
functions.functionCall( ((WasmCallInstruction)instruction).getFunctionName() );
break;
case Struct:
types.useType( ((WasmStructInstruction)instruction).getStorageType() );
setStructType( (WasmStructInstruction)instruction );
break;
default:
}
instruction.writeTo( writer );

View File

@ -1,5 +1,5 @@
/*
* Copyright 2017 - 2018 Volker Berlin (i-net software)
* Copyright 2017 - 2019 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.
@ -17,12 +17,14 @@ package de.inetsoftware.jwebassembly.module;
import java.io.Closeable;
import java.io.IOException;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import de.inetsoftware.classparser.Member;
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.NumericOperator;
import de.inetsoftware.jwebassembly.wasm.StorageType;
import de.inetsoftware.jwebassembly.wasm.StructOperator;
@ -44,6 +46,19 @@ public abstract class ModuleWriter implements Closeable {
}
/**
* Write a type/struct.
*
* @param typeName
* the name
* @param fields
* the fields
* @return type ID
* @throws IOException
* if any I/O error occur
*/
protected abstract int writeStruct( String typeName, List<NamedStorageType> fields ) throws IOException;
/**
* Prepare a imported single function in the prepare phase.
*

View File

@ -1,5 +1,5 @@
/*
Copyright 2018 Volker Berlin (i-net software)
Copyright 2018 - 2019 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.
@ -36,20 +36,13 @@ class TypeManager {
/**
* Use the type in the output.
*
* @param storageType
* @param type
* the reference to a type
* @param id
* the id in the type section of the wasm
*/
void useType( StorageType storageType ) {
if( storageType instanceof StructType ) {
StructType type = (StructType)storageType;
StructType existingType = map.get( type.name );
if( existingType == null ) {
type.code = map.size();
map.put( type.name, type );
} else {
type.code = existingType.code;
}
}
void useType( StructType type, int id ) {
type.code = id;
}
/**
@ -62,6 +55,22 @@ class TypeManager {
return map.values();
}
/**
* Get the StructType. If needed an instance is created.
*
* @param name
* the type name
* @return the struct type
*/
StructType valueOf( String name ) {
StructType type = map.get( name );
if( type == null ) {
type = new StructType();
map.put( name, type );
}
return type;
}
/**
* A reference to a type.
*
@ -69,19 +78,7 @@ class TypeManager {
*/
static class StructType implements StorageType {
private final String name;
private int code;
/**
* Create a reference to type
*
* @param name
* the Java class name
*/
StructType( String name ) {
this.name = name;
}
private int code = Integer.MIN_VALUE;
/**
* {@inheritDoc}
@ -90,13 +87,5 @@ class TypeManager {
public int getCode() {
return code;
}
/**
* Get the name of the Java type
* @return the name
*/
public String getName() {
return name;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2018 Volker Berlin (i-net software)
* Copyright 2018 - 2019 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.
@ -231,12 +231,12 @@ public abstract class WasmCodeBuilder {
*
* @param op
* the operation
* @param type
* the array type
* @param typeName
* the type name
* @param javaCodePos
* the code position/offset in the Java method
*/
protected void addStructInstruction( StructOperator op, StorageType type, int javaCodePos ) {
instructions.add( new WasmStructInstruction( op, type, javaCodePos ) );
protected void addStructInstruction( StructOperator op, String typeName, int javaCodePos ) {
instructions.add( new WasmStructInstruction( op, typeName, javaCodePos ) );
}
}

View File

@ -22,6 +22,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import de.inetsoftware.jwebassembly.WasmException;
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
import de.inetsoftware.jwebassembly.wasm.StorageType;
import de.inetsoftware.jwebassembly.wasm.StructOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType;
@ -36,31 +37,43 @@ class WasmStructInstruction extends WasmInstruction {
private final StructOperator op;
private final StorageType type;
private final String typeName;
private StorageType type;
/**
* Create an instance of numeric operation.
*
* @param op
* the struct operation
* @param type
* the type of the parameters
* @param typeName
* the type name of the parameters
* @param javaCodePos
* the code position/offset in the Java method
*/
WasmStructInstruction( @Nullable StructOperator op, @Nullable StorageType type, int javaCodePos ) {
WasmStructInstruction( @Nullable StructOperator op, @Nullable String typeName, int javaCodePos ) {
super( javaCodePos );
this.op = op;
this.type = type;
this.typeName = typeName;
}
/**
* Get the storage type of this instruction.
* Get the type name of this instruction.
*
* @return the type
*/
StorageType getStorageType() {
return type;
String getTypeName() {
return typeName;
}
/**
* Set the resolved StructType for the typeName
*
* @param type
* the type
*/
void setType( StructType type ) {
this.type = type;
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2017 - 2018 Volker Berlin (i-net software)
* Copyright 2017 - 2019 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.
@ -18,6 +18,7 @@ package de.inetsoftware.jwebassembly.text;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -28,6 +29,7 @@ import de.inetsoftware.jwebassembly.module.FunctionName;
import de.inetsoftware.jwebassembly.module.ModuleWriter;
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
import de.inetsoftware.jwebassembly.wasm.NumericOperator;
import de.inetsoftware.jwebassembly.wasm.StorageType;
import de.inetsoftware.jwebassembly.wasm.StructOperator;
@ -82,6 +84,31 @@ public class TextModuleWriter extends ModuleWriter {
output.append( ')' );
}
/**
* {@inheritDoc}
*/
@Override
protected int writeStruct( String typeName, List<NamedStorageType> fields ) throws IOException {
int oldInset = inset;
inset = 1;
newline( output );
output.append( "(type $" ).append( typeName ).append( " (struct" );
inset++;
for( NamedStorageType field : fields ) {
newline( output );
output.append( "(field" );
if( debugNames && field.name != null ) {
output.append( " $" ).append( field.name );
}
output.append( ' ' ).append( field.type.toString() ).append( ')' );
}
inset--;
newline( output );
output.append( "))" );
inset = oldInset;
return 0;
}
/**
* {@inheritDoc}
*/