mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
Add support for invoke static method calls
This commit is contained in:
parent
c548779c76
commit
4836024e4e
@ -25,6 +25,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import de.inetsoftware.classparser.MethodInfo;
|
||||||
import de.inetsoftware.jwebassembly.WasmException;
|
import de.inetsoftware.jwebassembly.WasmException;
|
||||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||||
import de.inetsoftware.jwebassembly.module.NumericOperator;
|
import de.inetsoftware.jwebassembly.module.NumericOperator;
|
||||||
@ -176,19 +177,30 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
protected void prepareMethod( MethodInfo method ) throws WasmException {
|
||||||
protected void writeExport( String methodName, String exportName ) throws IOException {
|
String methodName = method.getName();
|
||||||
exports.put( exportName, methodName );
|
String className = method.getDeclaringClassFile().getThisClass().getName();
|
||||||
|
String fullName = className + '.' + methodName;
|
||||||
|
String signatureName = fullName + method.getDescription();
|
||||||
|
Function function = new Function();
|
||||||
|
function.id = functions.size();
|
||||||
|
functions.put( signatureName, function );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void writeMethodStart( String name ) throws IOException {
|
protected void writeExport( String signatureName, String methodName, String exportName ) throws IOException {
|
||||||
function = new Function();
|
exports.put( exportName, signatureName );
|
||||||
function.id = functions.size();
|
}
|
||||||
functions.put( name, function );
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void writeMethodStart( String signatureName, String name ) throws IOException {
|
||||||
|
function = functions.get( signatureName );
|
||||||
functionType = new FunctionType();
|
functionType = new FunctionType();
|
||||||
codeStream.reset();
|
codeStream.reset();
|
||||||
}
|
}
|
||||||
@ -458,4 +470,17 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
protected void writeReturn() throws IOException {
|
protected void writeReturn() throws IOException {
|
||||||
codeStream.write( RETURN );
|
codeStream.write( RETURN );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void writeFunctionCall( String name ) throws IOException {
|
||||||
|
codeStream.write( CALL );
|
||||||
|
Function func = functions.get( name );
|
||||||
|
if( func == null ) {
|
||||||
|
throw new WasmException( "Call to unknown function: " + name, null, -1 );
|
||||||
|
}
|
||||||
|
codeStream.writeVaruint32( func.id );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,8 @@ interface InstructionOpcodes {
|
|||||||
|
|
||||||
static final int RETURN = 0x0F;
|
static final int RETURN = 0x0F;
|
||||||
|
|
||||||
|
static final int CALL = 0x10;
|
||||||
|
|
||||||
// === Variable access ===========
|
// === Variable access ===========
|
||||||
|
|
||||||
static final int GET_LOCAL = 0x20;
|
static final int GET_LOCAL = 0x20;
|
||||||
|
@ -105,8 +105,8 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
* @throws WasmException
|
* @throws WasmException
|
||||||
* if some Java code can't converted
|
* if some Java code can't converted
|
||||||
*/
|
*/
|
||||||
private void prepareMethod( MethodInfo method ) throws WasmException {
|
protected void prepareMethod( MethodInfo method ) throws WasmException {
|
||||||
|
// Nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -121,9 +121,12 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
try {
|
try {
|
||||||
Code code = method.getCode();
|
Code code = method.getCode();
|
||||||
if( code != null ) { // abstract methods and interface methods does not have code
|
if( code != null ) { // abstract methods and interface methods does not have code
|
||||||
String methodName = method.getName(); // TODO naming conversion rule
|
String methodName = method.getName();
|
||||||
writeExport( methodName, method );
|
String className = method.getDeclaringClassFile().getThisClass().getName();
|
||||||
writeMethodStart( methodName );
|
String fullName = className + '.' + methodName;
|
||||||
|
String signatureName = fullName + method.getDescription();
|
||||||
|
writeExport( signatureName, fullName, method );
|
||||||
|
writeMethodStart( signatureName, fullName );
|
||||||
writeMethodSignature( method );
|
writeMethodSignature( method );
|
||||||
locals.clear();
|
locals.clear();
|
||||||
localTable = code.getLocalVariableTable();
|
localTable = code.getLocalVariableTable();
|
||||||
@ -156,48 +159,55 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
/**
|
/**
|
||||||
* Look for a Export annotation and if there write an export directive.
|
* Look for a Export annotation and if there write an export directive.
|
||||||
*
|
*
|
||||||
|
* @param signatureName
|
||||||
|
* the full name with signature
|
||||||
* @param methodName
|
* @param methodName
|
||||||
* the normalized method name
|
* the normalized method name
|
||||||
* @param method
|
* @param method
|
||||||
* the moethod
|
* the moethod
|
||||||
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if any IOException occur
|
* if any IOException occur
|
||||||
*/
|
*/
|
||||||
private void writeExport( String methodName, MethodInfo method ) throws IOException {
|
private void writeExport( String signatureName, String methodName, MethodInfo method ) throws IOException {
|
||||||
Annotations annotations = method.getRuntimeInvisibleAnnotations();
|
Annotations annotations = method.getRuntimeInvisibleAnnotations();
|
||||||
if( annotations != null ) {
|
if( annotations != null ) {
|
||||||
Map<String,Object> export = annotations.get( "org.webassembly.annotation.Export" );
|
Map<String,Object> export = annotations.get( "org.webassembly.annotation.Export" );
|
||||||
if( export != null ) {
|
if( export != null ) {
|
||||||
String exportName = (String)export.get( "name" );
|
String exportName = (String)export.get( "name" );
|
||||||
if( exportName == null ) {
|
if( exportName == null ) {
|
||||||
exportName = methodName;
|
exportName = method.getName(); // TODO naming conversion rule if no name was set
|
||||||
}
|
}
|
||||||
writeExport( methodName, exportName );
|
writeExport( signatureName, methodName, exportName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write an export directive
|
* Write an export directive
|
||||||
*
|
* @param signatureName
|
||||||
|
* the full name with signature
|
||||||
* @param methodName
|
* @param methodName
|
||||||
* the method name
|
* the method name
|
||||||
* @param exportName
|
* @param exportName
|
||||||
* the export name, if null then the same like the method name
|
* the export name, if null then the same like the method name
|
||||||
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if any I/O error occur
|
* if any I/O error occur
|
||||||
*/
|
*/
|
||||||
protected abstract void writeExport( String methodName, String exportName ) throws IOException;
|
protected abstract void writeExport( String signatureName, String methodName, String exportName ) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the method header.
|
* Write the method header.
|
||||||
*
|
* @param signatureName
|
||||||
|
* the full name with signature
|
||||||
* @param name
|
* @param name
|
||||||
* the method name
|
* the method name
|
||||||
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if any I/O error occur
|
* if any I/O error occur
|
||||||
*/
|
*/
|
||||||
protected abstract void writeMethodStart( String name ) throws IOException;
|
protected abstract void writeMethodStart( String signatureName, String name ) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the parameter and return signatures
|
* Write the parameter and return signatures
|
||||||
@ -490,6 +500,11 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
case 177: // return void
|
case 177: // return void
|
||||||
writeReturn();
|
writeReturn();
|
||||||
break;
|
break;
|
||||||
|
case 184: // invokestatic
|
||||||
|
idx = byteCode.readUnsignedShort();
|
||||||
|
ConstantRef method = (ConstantRef)constantPool.get( idx );
|
||||||
|
writeFunctionCall( method.getConstantClass().getName() + '.' + method.getName() + method.getType() );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new WasmException( "Unimplemented byte code operation: " + op, sourceFile, lineNumber );
|
throw new WasmException( "Unimplemented byte code operation: " + op, sourceFile, lineNumber );
|
||||||
}
|
}
|
||||||
@ -617,7 +632,9 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a add operator
|
* Write a add operator
|
||||||
* @param numOp TODO
|
*
|
||||||
|
* @param numOp
|
||||||
|
* the numeric operation
|
||||||
* @param valueType
|
* @param valueType
|
||||||
* the type of the parameters
|
* the type of the parameters
|
||||||
*
|
*
|
||||||
@ -643,4 +660,14 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
* if any I/O error occur
|
* if any I/O error occur
|
||||||
*/
|
*/
|
||||||
protected abstract void writeReturn() throws IOException;
|
protected abstract void writeReturn() throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a call to a function.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* the full qualified method name
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
|
*/
|
||||||
|
protected abstract void writeFunctionCall( String name ) throws IOException;
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ public class TextModuleWriter extends ModuleWriter {
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void writeExport( String methodName, String exportName ) throws IOException {
|
protected void writeExport( String signatureName, String methodName, String exportName ) throws IOException {
|
||||||
newline( output );
|
newline( output );
|
||||||
output.append( "(export \"" ).append( exportName ).append( "\" (func $" ).append( methodName ).append( "))" );
|
output.append( "(export \"" ).append( exportName ).append( "\" (func $" ).append( methodName ).append( "))" );
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ public class TextModuleWriter extends ModuleWriter {
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void writeMethodStart( String name ) throws IOException {
|
protected void writeMethodStart( String signatureName, String name ) throws IOException {
|
||||||
newline( output );
|
newline( output );
|
||||||
output.append( "(func $" );
|
output.append( "(func $" );
|
||||||
output.append( name );
|
output.append( name );
|
||||||
@ -211,4 +211,14 @@ public class TextModuleWriter extends ModuleWriter {
|
|||||||
output.append( ' ' );
|
output.append( ' ' );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void writeFunctionCall( String name ) throws IOException {
|
||||||
|
newline( methodOutput );
|
||||||
|
name = name.substring( 0, name.indexOf( '(' ) );
|
||||||
|
methodOutput.append( "call $" ).append( name );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,31 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017 Volker Berlin (i-net software)
|
* Copyright 2017 Volker Berlin (i-net software)
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package de.inetsoftware.jwebassembly.samples;
|
package de.inetsoftware.jwebassembly.samples;
|
||||||
|
|
||||||
/**
|
import org.webassembly.annotation.Export;
|
||||||
*
|
|
||||||
* @author Volker Berlin
|
/**
|
||||||
*
|
*
|
||||||
*/
|
* @author Volker Berlin
|
||||||
public class FunctionParameters {
|
*
|
||||||
|
*/
|
||||||
void singleInt( int a ) {
|
public class FunctionParameters {
|
||||||
|
|
||||||
}
|
@Export(name="abc")
|
||||||
}
|
static void singleInt( int a ) {
|
||||||
|
int b = a + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
(module
|
(module
|
||||||
(func $singleInt (param i32)
|
(export "abc" (func $de/inetsoftware/jwebassembly/samples/FunctionParameters.singleInt))
|
||||||
|
(func $de/inetsoftware/jwebassembly/samples/FunctionParameters.singleInt (param i32) (local i32)
|
||||||
|
get_local 0
|
||||||
|
i32.const 1
|
||||||
|
i32.add
|
||||||
|
set_local 1
|
||||||
return
|
return
|
||||||
)
|
)
|
||||||
)
|
)
|
Loading…
x
Reference in New Issue
Block a user