mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 02:44:47 +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 de.inetsoftware.classparser.MethodInfo;
|
||||
import de.inetsoftware.jwebassembly.WasmException;
|
||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||
import de.inetsoftware.jwebassembly.module.NumericOperator;
|
||||
@ -176,19 +177,30 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void writeExport( String methodName, String exportName ) throws IOException {
|
||||
exports.put( exportName, methodName );
|
||||
protected void prepareMethod( MethodInfo method ) throws WasmException {
|
||||
String methodName = method.getName();
|
||||
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}
|
||||
*/
|
||||
@Override
|
||||
protected void writeMethodStart( String name ) throws IOException {
|
||||
function = new Function();
|
||||
function.id = functions.size();
|
||||
functions.put( name, function );
|
||||
protected void writeExport( String signatureName, String methodName, String exportName ) throws IOException {
|
||||
exports.put( exportName, signatureName );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void writeMethodStart( String signatureName, String name ) throws IOException {
|
||||
function = functions.get( signatureName );
|
||||
functionType = new FunctionType();
|
||||
codeStream.reset();
|
||||
}
|
||||
@ -458,4 +470,17 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
||||
protected void writeReturn() throws IOException {
|
||||
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 CALL = 0x10;
|
||||
|
||||
// === Variable access ===========
|
||||
|
||||
static final int GET_LOCAL = 0x20;
|
||||
|
@ -105,8 +105,8 @@ public abstract class ModuleWriter implements Closeable {
|
||||
* @throws WasmException
|
||||
* 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 {
|
||||
Code code = method.getCode();
|
||||
if( code != null ) { // abstract methods and interface methods does not have code
|
||||
String methodName = method.getName(); // TODO naming conversion rule
|
||||
writeExport( methodName, method );
|
||||
writeMethodStart( methodName );
|
||||
String methodName = method.getName();
|
||||
String className = method.getDeclaringClassFile().getThisClass().getName();
|
||||
String fullName = className + '.' + methodName;
|
||||
String signatureName = fullName + method.getDescription();
|
||||
writeExport( signatureName, fullName, method );
|
||||
writeMethodStart( signatureName, fullName );
|
||||
writeMethodSignature( method );
|
||||
locals.clear();
|
||||
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.
|
||||
*
|
||||
* @param signatureName
|
||||
* the full name with signature
|
||||
* @param methodName
|
||||
* the normalized method name
|
||||
* @param method
|
||||
* the moethod
|
||||
*
|
||||
* @throws IOException
|
||||
* 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();
|
||||
if( annotations != null ) {
|
||||
Map<String,Object> export = annotations.get( "org.webassembly.annotation.Export" );
|
||||
if( export != null ) {
|
||||
String exportName = (String)export.get( "name" );
|
||||
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
|
||||
*
|
||||
* @param signatureName
|
||||
* the full name with signature
|
||||
* @param methodName
|
||||
* the method name
|
||||
* @param exportName
|
||||
* the export name, if null then the same like the method name
|
||||
*
|
||||
* @throws IOException
|
||||
* 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.
|
||||
*
|
||||
* @param signatureName
|
||||
* the full name with signature
|
||||
* @param name
|
||||
* the method name
|
||||
*
|
||||
* @throws IOException
|
||||
* 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
|
||||
@ -490,6 +500,11 @@ public abstract class ModuleWriter implements Closeable {
|
||||
case 177: // return void
|
||||
writeReturn();
|
||||
break;
|
||||
case 184: // invokestatic
|
||||
idx = byteCode.readUnsignedShort();
|
||||
ConstantRef method = (ConstantRef)constantPool.get( idx );
|
||||
writeFunctionCall( method.getConstantClass().getName() + '.' + method.getName() + method.getType() );
|
||||
break;
|
||||
default:
|
||||
throw new WasmException( "Unimplemented byte code operation: " + op, sourceFile, lineNumber );
|
||||
}
|
||||
@ -617,7 +632,9 @@ public abstract class ModuleWriter implements Closeable {
|
||||
|
||||
/**
|
||||
* Write a add operator
|
||||
* @param numOp TODO
|
||||
*
|
||||
* @param numOp
|
||||
* the numeric operation
|
||||
* @param valueType
|
||||
* the type of the parameters
|
||||
*
|
||||
@ -643,4 +660,14 @@ public abstract class ModuleWriter implements Closeable {
|
||||
* if any I/O error occur
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
@Override
|
||||
protected void writeExport( String methodName, String exportName ) throws IOException {
|
||||
protected void writeExport( String signatureName, String methodName, String exportName ) throws IOException {
|
||||
newline( output );
|
||||
output.append( "(export \"" ).append( exportName ).append( "\" (func $" ).append( methodName ).append( "))" );
|
||||
}
|
||||
@ -76,7 +76,7 @@ public class TextModuleWriter extends ModuleWriter {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void writeMethodStart( String name ) throws IOException {
|
||||
protected void writeMethodStart( String signatureName, String name ) throws IOException {
|
||||
newline( output );
|
||||
output.append( "(func $" );
|
||||
output.append( name );
|
||||
@ -211,4 +211,14 @@ public class TextModuleWriter extends ModuleWriter {
|
||||
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)
|
||||
*
|
||||
* 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.samples;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Volker Berlin
|
||||
*
|
||||
*/
|
||||
public class FunctionParameters {
|
||||
|
||||
void singleInt( int a ) {
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2017 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.samples;
|
||||
|
||||
import org.webassembly.annotation.Export;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Volker Berlin
|
||||
*
|
||||
*/
|
||||
public class FunctionParameters {
|
||||
|
||||
@Export(name="abc")
|
||||
static void singleInt( int a ) {
|
||||
int b = a + 1;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
(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
|
||||
)
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user