mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 10:44:47 +01:00
write the struct type into the type section
This commit is contained in:
parent
efef0b03d5
commit
56fdf9018d
@ -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}
|
||||
*/
|
||||
|
@ -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 );
|
||||
|
@ -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();
|
||||
|
@ -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 );
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 ) );
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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}
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user