diff --git a/src/de/inetsoftware/jwebassembly/module/BranchManager.java b/src/de/inetsoftware/jwebassembly/module/BranchManager.java index da50c0c..ce8a2ee 100644 --- a/src/de/inetsoftware/jwebassembly/module/BranchManager.java +++ b/src/de/inetsoftware/jwebassembly/module/BranchManager.java @@ -772,7 +772,7 @@ class BranchManager { * the line number for possible error messages */ private void insertConstBeforePosition( int constant, int pos, int lineNumber ) { - instructions.add( findIdxOfCodePos( pos ), new WasmConstInstruction( constant, pos - 1, lineNumber ) ); + instructions.add( findIdxOfCodePos( pos ), new WasmConstNumberInstruction( constant, pos - 1, lineNumber ) ); } /** @@ -1319,7 +1319,7 @@ class BranchManager { String exceptionTypeName = tryCat.getType().getName(); StructType type = options.types.valueOf( exceptionTypeName ); instructions.add( idx++, new WasmLoadStoreInstruction( VariableOperator.get, ex.getSlot(), localVariables, catchPos, lineNumber ) ); - instructions.add( idx++, new WasmConstInstruction( type.getClassIndex(), catchPos, lineNumber ) ); + instructions.add( idx++, new WasmConstNumberInstruction( type.getClassIndex(), catchPos, lineNumber ) ); instructions.add( idx++, new WasmCallInstruction( instanceOf, catchPos, lineNumber, options.types, false, exceptionTypeName ) ); if( handler != tryCat.getHandler() ) { // if not multiple exception in catch block like "catch ( ArrayIndexOutOfBoundsException | IllegalArgumentException ex )" diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java index 2c50276..c2d1f1d 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java @@ -552,7 +552,7 @@ public abstract class WasmCodeBuilder { * the line number in the Java source code */ protected void addConstInstruction( Number value, ValueType valueType, int javaCodePos, int lineNumber ) { - instructions.add( new WasmConstInstruction( value, valueType, javaCodePos, lineNumber ) ); + instructions.add( new WasmConstNumberInstruction( value, valueType, javaCodePos, lineNumber ) ); } /** @@ -567,15 +567,11 @@ public abstract class WasmCodeBuilder { */ protected void addConstInstruction( Object value, int javaCodePos, int lineNumber ) { if( value.getClass() == String.class ) { - instructions.add( new WasmStringInstruction( (String)value, strings, types, javaCodePos, lineNumber ) ); + instructions.add( new WasmConstStringInstruction( (String)value, strings, types, javaCodePos, lineNumber ) ); } else if( value instanceof Number ) { - instructions.add( new WasmConstInstruction( (Number)value, javaCodePos, lineNumber ) ); + instructions.add( new WasmConstNumberInstruction( (Number)value, javaCodePos, lineNumber ) ); } else if( value instanceof ConstantClass ) { - String className = ((ConstantClass)value).getName(); - Integer id = types.valueOf( className ).getClassIndex(); - FunctionName name = types.getClassConstantFunction(); - instructions.add( new WasmConstInstruction( id, ValueType.i32, javaCodePos, lineNumber ) ); - addCallInstruction( name, false, javaCodePos, lineNumber ); + instructions.add( new WasmConstClassInstruction( (ConstantClass)value, types, javaCodePos, lineNumber ) ); } else { //TODO There can be MethodType and MethodHandle throw new WasmException( "Class constants are not supported. : " + value, lineNumber ); diff --git a/src/de/inetsoftware/jwebassembly/module/WasmConstClassInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmConstClassInstruction.java new file mode 100644 index 0000000..ae65b6f --- /dev/null +++ b/src/de/inetsoftware/jwebassembly/module/WasmConstClassInstruction.java @@ -0,0 +1,142 @@ +/* + Copyright 2022 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 java.io.IOException; + +import javax.annotation.Nonnull; + +import de.inetsoftware.classparser.ConstantClass; +import de.inetsoftware.jwebassembly.wasm.AnyType; +import de.inetsoftware.jwebassembly.wasm.ValueType; + +/** + * WasmInstruction for constant class. + * + * @author Volker Berlin + * + */ +class WasmConstClassInstruction extends WasmInstruction { + + @Nonnull + private final String className; + + private final int id; + + private final FunctionName function; + + private final AnyType valueType; + + /** + * Create an instance of a class constant instruction + * + * @param value + * the constant class value + * @param types + * the type manager + * @param javaCodePos + * the code position/offset in the Java method + * @param lineNumber + * the line number in the Java source code + */ + WasmConstClassInstruction( @Nonnull ConstantClass value, TypeManager types, int javaCodePos, int lineNumber ) { + super( javaCodePos, lineNumber ); + this.className = value.getName(); + id = types.valueOf( className ).getClassIndex(); + function = types.getClassConstantFunction(); + types.options.functions.markAsNeeded( function, false ); + valueType = types.valueOf( "java/lang/Class" ); + } + + /** + * Get the className value + * + * @return the value + */ + @Nonnull + String getValue() { + return className; + } + + /** + * {@inheritDoc} + */ + @Override + Type getType() { + return Type.Clazz; + } + + /** + * {@inheritDoc} + */ + @Override + void writeTo( @Nonnull ModuleWriter writer ) throws IOException { + writer.writeConst( id, ValueType.i32 ); + writer.writeFunctionCall( function, className ); + } + + /** + * If the string contains only ASCCI characters + * + * @param str + * the staring + * @return true, if only ASCII + */ + private static boolean isAscii( String str ) { + int length = str.length(); + for( int i = 0; i < length; i++ ) { + int c = str.charAt( i ); + if( c >= 0x20 && c < 0x7F ) { + continue; + } + return false; + } + return true; + } + + /** + * {@inheritDoc} + */ + @Override + AnyType getPushValueType() { + return valueType; + } + + /** + * {@inheritDoc} + */ + @Override + int getPopCount() { + return 0; + } + + /** + * {@inheritDoc} + */ + @Override + AnyType[] getPopValueTypes() { + return null; + } + + /** + * Only used for debugging + */ + @Override + public String toString() { + return getClass().getSimpleName() + ": " + className; + } +} diff --git a/src/de/inetsoftware/jwebassembly/module/WasmConstInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmConstNumberInstruction.java similarity index 100% rename from src/de/inetsoftware/jwebassembly/module/WasmConstInstruction.java rename to src/de/inetsoftware/jwebassembly/module/WasmConstNumberInstruction.java diff --git a/src/de/inetsoftware/jwebassembly/module/WasmStringInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmConstStringInstruction.java similarity index 100% rename from src/de/inetsoftware/jwebassembly/module/WasmStringInstruction.java rename to src/de/inetsoftware/jwebassembly/module/WasmConstStringInstruction.java diff --git a/src/de/inetsoftware/jwebassembly/module/WasmInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmInstruction.java index aaa045e..00eed42 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmInstruction.java @@ -35,7 +35,7 @@ abstract class WasmInstruction { * Type of instruction to faster differ as with instanceof. */ static enum Type { - Const, String, Convert, Local, Global, Table, Memory, Block, Numeric, Nop, Jump, Call, CallVirtual, CallInterface, Array, Struct, DupThis; + Const, String, Clazz, Convert, Local, Global, Table, Memory, Block, Numeric, Nop, Jump, Call, CallVirtual, CallInterface, Array, Struct, DupThis; } private int javaCodePos;