Add a separate String instruction

This commit is contained in:
Volker Berlin 2022-09-18 13:04:08 +02:00
parent 4cc13dd99f
commit c62615b425
No known key found for this signature in database
GPG Key ID: 988423EF815BE4CB
5 changed files with 149 additions and 36 deletions

View File

@ -316,11 +316,6 @@ public class TypeManager {
} else {
checkStructTypesState( name );
type = new StructType( name, StructTypeKind.normal, this );
if( "java/lang/String".equals( name ) ) {
// looks like strings are used, that register helper functions
options.strings.getStringConstantFunction();
}
}
structTypes.put( name, type );

View File

@ -567,14 +567,7 @@ public abstract class WasmCodeBuilder {
*/
protected void addConstInstruction( Object value, int javaCodePos, int lineNumber ) {
if( value.getClass() == String.class ) {
Integer id = strings.get( value );
FunctionName name = strings.getStringConstantFunction();
instructions.add( new WasmConstInstruction( id, ValueType.i32, javaCodePos, lineNumber ) );
String comment = (String)value;
if( !isAscii( comment ) ) {
comment = null;
}
instructions.add( new WasmCallInstruction( name, javaCodePos, lineNumber, types, false, comment ) );
instructions.add( new WasmStringInstruction( (String)value, strings, types, javaCodePos, lineNumber ) );
} else if( value instanceof Number ) {
instructions.add( new WasmConstInstruction( (Number)value, javaCodePos, lineNumber ) );
} else if( value instanceof ConstantClass ) {
@ -584,30 +577,11 @@ public abstract class WasmCodeBuilder {
instructions.add( new WasmConstInstruction( id, ValueType.i32, javaCodePos, lineNumber ) );
addCallInstruction( name, false, javaCodePos, lineNumber );
} else {
//TODO There can be ConstantClass, MethodType and MethodHandle
//TODO There can be MethodType and MethodHandle
throw new WasmException( "Class constants are not supported. : " + value, lineNumber );
}
}
/**
* 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;
}
/**
* Add a numeric operation instruction
*

View File

@ -103,13 +103,15 @@ class WasmConstInstruction extends WasmInstruction {
/**
* {@inheritDoc}
*/
public void writeTo( @Nonnull ModuleWriter writer ) throws IOException {
@Override
void writeTo( @Nonnull ModuleWriter writer ) throws IOException {
writer.writeConst( value, valueType );
}
/**
* {@inheritDoc}
*/
@Override
AnyType getPushValueType() {
return valueType;
}

View File

@ -1,5 +1,5 @@
/*
Copyright 2018 - 2021 Volker Berlin (i-net software)
Copyright 2018 - 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.
@ -35,7 +35,7 @@ abstract class WasmInstruction {
* Type of instruction to faster differ as with instanceof.
*/
static enum Type {
Const, Convert, Local, Global, Table, Memory, Block, Numeric, Nop, Jump, Call, CallVirtual, CallInterface, Array, Struct, DupThis;
Const, String, Convert, Local, Global, Table, Memory, Block, Numeric, Nop, Jump, Call, CallVirtual, CallInterface, Array, Struct, DupThis;
}
private int javaCodePos;

View File

@ -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.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.ValueType;
/**
* WasmInstruction for constant Strings.
*
* @author Volker Berlin
*
*/
class WasmStringInstruction extends WasmInstruction {
@Nonnull
private final String value;
private final Integer id;
private final FunctionName function;
private final AnyType valueType;
/**
* Create an instance of a string constant instruction
*
* @param value
* the constant string value
* @param strings
* the string manager
* @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
*/
WasmStringInstruction( @Nonnull String value, StringManager strings, TypeManager types, int javaCodePos, int lineNumber ) {
super( javaCodePos, lineNumber );
this.value = value;
id = strings.get( value );
function = strings.getStringConstantFunction();
valueType = types.valueOf( "java/lang/String" );
}
/**
* Get the string value
* @return the value
*/
@Nonnull
String getValue() {
return value;
}
/**
* {@inheritDoc}
*/
@Override
Type getType() {
return Type.String;
}
/**
* {@inheritDoc}
*/
@Override
void writeTo( @Nonnull ModuleWriter writer ) throws IOException {
writer.writeConst( id, ValueType.i32 );
String comment = isAscii( value ) ? value : null;
writer.writeFunctionCall( function, comment );
}
/**
* 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() + ": " + value;
}
}