mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 02:44:47 +01:00
implements StructType.isSubTypeOf(x)
This commit is contained in:
parent
f4fd312d31
commit
1f167d99b9
@ -102,6 +102,8 @@ public class ModuleGenerator {
|
||||
optimizer = options.optimizer;
|
||||
javaCodeBuilder.init( options, classFileLoader );
|
||||
((WasmCodeBuilder)watParser).init( options, classFileLoader );
|
||||
types.init( classFileLoader );
|
||||
|
||||
scanLibraries( libraries );
|
||||
}
|
||||
|
||||
@ -279,7 +281,7 @@ public class ModuleGenerator {
|
||||
scanFunctions();
|
||||
functCount = functions.size(); // scan the functions can find new needed types or only new needed fields in the known types
|
||||
scanForClinit();
|
||||
types.scanTypeHierarchy( classFileLoader ); // scan the type hierarchy can find new functions
|
||||
types.scanTypeHierarchy(); // scan the type hierarchy can find new functions
|
||||
} while( functCount < functions.size() );
|
||||
|
||||
// write only the needed imports to the output
|
||||
@ -319,10 +321,10 @@ public class ModuleGenerator {
|
||||
}
|
||||
|
||||
// scan again if there are new types or new needed fields
|
||||
types.scanTypeHierarchy( classFileLoader );
|
||||
types.scanTypeHierarchy();
|
||||
|
||||
JWebAssembly.LOGGER.fine( "scan finish" );
|
||||
types.prepareFinish( writer, classFileLoader );
|
||||
types.prepareFinish( writer );
|
||||
functions.prepareFinish();
|
||||
strings.prepareFinish( writer );
|
||||
writer.prepareFinish();
|
||||
|
@ -18,6 +18,7 @@ package de.inetsoftware.jwebassembly.module;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@ -159,6 +160,8 @@ public class TypeManager {
|
||||
|
||||
private int typeTableOffset;
|
||||
|
||||
private ClassFileLoader classFileLoader;
|
||||
|
||||
/**
|
||||
* Initialize the type manager.
|
||||
*
|
||||
@ -169,6 +172,14 @@ public class TypeManager {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the type manager
|
||||
* @param classFileLoader for loading the class files
|
||||
*/
|
||||
void init( ClassFileLoader classFileLoader ) {
|
||||
this.classFileLoader = classFileLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count of used types
|
||||
*
|
||||
@ -190,12 +201,10 @@ public class TypeManager {
|
||||
/**
|
||||
* Scan the hierarchy of the types.
|
||||
*
|
||||
* @param classFileLoader
|
||||
* for loading the class files
|
||||
* @throws IOException
|
||||
* if any I/O error occur on loading or writing
|
||||
*/
|
||||
void scanTypeHierarchy( ClassFileLoader classFileLoader ) throws IOException {
|
||||
void scanTypeHierarchy() throws IOException {
|
||||
for( StructType type : structTypes.values() ) {
|
||||
type.scanTypeHierarchy( options.functions, this, classFileLoader );
|
||||
}
|
||||
@ -206,12 +215,10 @@ public class TypeManager {
|
||||
*
|
||||
* @param writer
|
||||
* the targets for the types
|
||||
* @param classFileLoader
|
||||
* for loading the class files
|
||||
* @throws IOException
|
||||
* if any I/O error occur on loading or writing
|
||||
*/
|
||||
void prepareFinish( ModuleWriter writer, ClassFileLoader classFileLoader ) throws IOException {
|
||||
void prepareFinish( ModuleWriter writer ) throws IOException {
|
||||
isFinish = true;
|
||||
for( StructType type : structTypes.values() ) {
|
||||
type.writeStructType( writer );
|
||||
@ -570,7 +577,9 @@ public class TypeManager {
|
||||
|
||||
private final String name;
|
||||
|
||||
private final StructTypeKind kind;
|
||||
private final StructTypeKind kind;
|
||||
|
||||
private final TypeManager manager;
|
||||
|
||||
private final int classIndex;
|
||||
|
||||
@ -595,7 +604,7 @@ public class TypeManager {
|
||||
* Create a reference to type
|
||||
*
|
||||
* @param name
|
||||
* the Java class name
|
||||
* the Java class name like "java/lang/String"
|
||||
* @param kind
|
||||
* the type kind
|
||||
* @param manager
|
||||
@ -604,6 +613,7 @@ public class TypeManager {
|
||||
protected StructType( @Nonnull String name, @Nonnull StructTypeKind kind, @Nonnull TypeManager manager ) {
|
||||
this.name = name;
|
||||
this.kind = kind;
|
||||
this.manager = manager;
|
||||
switch( kind ) {
|
||||
case array_native:
|
||||
this.classIndex = -1;
|
||||
@ -943,8 +953,43 @@ public class TypeManager {
|
||||
*/
|
||||
@Override
|
||||
public boolean isSubTypeOf( AnyType type ) {
|
||||
//TODO if type is StructType (class or interface)
|
||||
return type == this || type == ValueType.externref || type == ValueType.anyref || type == ValueType.eqref;
|
||||
if( type == this || type == ValueType.externref || type == ValueType.anyref || type == ValueType.eqref ) {
|
||||
return true;
|
||||
}
|
||||
if( !(type instanceof StructType) ) {
|
||||
return false;
|
||||
}
|
||||
StructType structType = (StructType)type;
|
||||
if( kind != structType.kind ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
ClassFile classFile = manager.classFileLoader.get( name );
|
||||
if( classFile != null ) {
|
||||
for( ConstantClass interClass : classFile.getInterfaces() ) {
|
||||
if( interClass.getName().equals( structType.name ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
while( classFile != null ) {
|
||||
ConstantClass superClass = classFile.getSuperClass();
|
||||
if( superClass == null ) {
|
||||
break;
|
||||
}
|
||||
String superName = superClass.getName();
|
||||
if( superName.equals( structType.name ) ) {
|
||||
return true;
|
||||
}
|
||||
classFile = manager.classFileLoader.get( superName );
|
||||
}
|
||||
}
|
||||
} catch( IOException ex ) {
|
||||
throw new UncheckedIOException( ex );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
102
test/de/inetsoftware/jwebassembly/module/StructTypeTest.java
Normal file
102
test/de/inetsoftware/jwebassembly/module/StructTypeTest.java
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2021 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.jwebassembly.module;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import de.inetsoftware.jwebassembly.JWebAssembly;
|
||||
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
|
||||
import de.inetsoftware.jwebassembly.module.TypeManager.StructTypeKind;
|
||||
|
||||
/**
|
||||
* @author Volker Berlin
|
||||
*/
|
||||
public class StructTypeTest {
|
||||
|
||||
private TypeManager manager;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
HashMap<String, String> properties = new HashMap<>();
|
||||
properties.put( JWebAssembly.WASM_USE_GC, "true" );
|
||||
WasmOptions options = new WasmOptions( properties );
|
||||
manager = options.types;
|
||||
manager.init( new ClassFileLoader( getClass().getClassLoader() ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSubTypeOf_SuperClass() throws Throwable {
|
||||
StructType typeInteger = manager.valueOf( "java/lang/Integer" );
|
||||
StructType typeNumber = manager.valueOf( "java/lang/Number" );
|
||||
StructType typeObject = manager.valueOf( "java/lang/Object" );
|
||||
|
||||
assertTrue( typeInteger.isSubTypeOf( typeInteger ) );
|
||||
assertTrue( typeInteger.isSubTypeOf( typeNumber ) );
|
||||
assertTrue( typeInteger.isSubTypeOf( typeObject ) );
|
||||
|
||||
assertFalse( typeNumber.isSubTypeOf( typeInteger ) );
|
||||
assertFalse( typeObject.isSubTypeOf( typeInteger ) );
|
||||
assertFalse( typeObject.isSubTypeOf( typeNumber ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSubTypeOf_Primitives() throws Throwable {
|
||||
StructType typeObject = manager.valueOf( "java/lang/Object" );
|
||||
StructType typeBoolean = manager.valueOf( "boolean" );
|
||||
StructType typeInt = manager.valueOf( "int" );
|
||||
|
||||
assertEquals( StructTypeKind.primitive, typeBoolean.getKind() );
|
||||
assertEquals( StructTypeKind.primitive, typeInt.getKind() );
|
||||
assertEquals( StructTypeKind.normal, typeObject.getKind() );
|
||||
|
||||
assertFalse( typeBoolean.isSubTypeOf( typeInt ) );
|
||||
assertFalse( typeInt.isSubTypeOf( typeBoolean ) );
|
||||
|
||||
assertFalse( typeBoolean.isSubTypeOf( typeObject ) );
|
||||
assertFalse( typeObject.isSubTypeOf( typeBoolean ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSubTypeOf_Interfaces() throws Throwable {
|
||||
StructType typeInteger = manager.valueOf( "java/lang/Integer" );
|
||||
StructType typeComparable = manager.valueOf( "java/lang/Comparable" );
|
||||
|
||||
assertTrue( typeInteger.isSubTypeOf( typeComparable ) );
|
||||
assertFalse( typeComparable.isSubTypeOf( typeInteger ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSubTypeOf_Arrays() throws Throwable {
|
||||
StructType typeObject = manager.valueOf( "java/lang/Object" );
|
||||
StructType typeInteger = manager.valueOf( "java/lang/Integer" );
|
||||
StructType typeObjArray = manager.arrayType( typeObject );
|
||||
StructType typeIntArray = manager.arrayType( typeInteger );
|
||||
|
||||
assertTrue( typeObjArray.isSubTypeOf( typeObject ) );
|
||||
assertFalse( typeObjArray.isSubTypeOf( typeInteger ) );
|
||||
|
||||
assertTrue( typeIntArray.isSubTypeOf( typeObjArray ) );
|
||||
assertFalse( typeObjArray.isSubTypeOf( typeIntArray ) );
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user