mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 15:37:52 +01:00
Add support for global (static) variables
This commit is contained in:
parent
c269bae443
commit
dd29280641
@ -26,6 +26,7 @@ import java.util.Map;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import de.inetsoftware.classparser.ConstantRef;
|
||||||
import de.inetsoftware.jwebassembly.WasmException;
|
import de.inetsoftware.jwebassembly.WasmException;
|
||||||
import de.inetsoftware.jwebassembly.module.FunctionName;
|
import de.inetsoftware.jwebassembly.module.FunctionName;
|
||||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||||
@ -387,6 +388,24 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
codeStream.writeVaruint32( idx );
|
codeStream.writeVaruint32( idx );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void writeGlobalAccess( boolean load, FunctionName name, ConstantRef ref ) throws IOException {
|
||||||
|
Global var = globals.get( name.fullName );
|
||||||
|
if( var == null ) { // if not declared then create a definition in the global section
|
||||||
|
var = new Global();
|
||||||
|
var.id = globals.size();
|
||||||
|
var.type = ValueType.getValueType( ref.getType(), 0 );
|
||||||
|
var.mutability = true;
|
||||||
|
globals.put( name.fullName, var );
|
||||||
|
}
|
||||||
|
int op = load ? GET_GLOBAL : SET_GLOBAL;
|
||||||
|
codeStream.writeOpCode( op );
|
||||||
|
codeStream.writeVaruint32( var.id );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -24,6 +24,8 @@ import de.inetsoftware.jwebassembly.module.ValueType;
|
|||||||
*/
|
*/
|
||||||
class Global {
|
class Global {
|
||||||
|
|
||||||
|
int id;
|
||||||
|
|
||||||
ValueType type;
|
ValueType type;
|
||||||
|
|
||||||
boolean mutability;
|
boolean mutability;
|
||||||
|
@ -648,8 +648,14 @@ public class ModuleGenerator {
|
|||||||
instr = new WasmBlockInstruction( WasmBlockOperator.RETURN, type, codePos );
|
instr = new WasmBlockInstruction( WasmBlockOperator.RETURN, type, codePos );
|
||||||
endWithReturn = true;
|
endWithReturn = true;
|
||||||
break;
|
break;
|
||||||
//TODO case 178: // getstatic
|
case 178: // getstatic
|
||||||
//TODO case 179: // putstatic
|
ConstantRef ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
|
||||||
|
instr = new WasmGlobalInstruction( true, ref, codePos );
|
||||||
|
break;
|
||||||
|
case 179: // putstatic
|
||||||
|
ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
|
||||||
|
instr = new WasmGlobalInstruction( false, ref, codePos );
|
||||||
|
break;
|
||||||
//TODO case 180: // getfield
|
//TODO case 180: // getfield
|
||||||
//TODO case 181: // putfield
|
//TODO case 181: // putfield
|
||||||
//TODO case 182: // invokevirtual
|
//TODO case 182: // invokevirtual
|
||||||
|
@ -22,6 +22,8 @@ import java.util.List;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import de.inetsoftware.classparser.ConstantRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Module Writer base class.
|
* Module Writer base class.
|
||||||
*
|
*
|
||||||
@ -144,6 +146,21 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
*/
|
*/
|
||||||
protected abstract void writeStore( int idx ) throws IOException;
|
protected abstract void writeStore( int idx ) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a set_global variable
|
||||||
|
* @param load
|
||||||
|
* true: if load or GET
|
||||||
|
* @param name
|
||||||
|
* the variable name
|
||||||
|
* @param ref
|
||||||
|
* the definition of the variable
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
|
*/
|
||||||
|
protected abstract void writeGlobalAccess( boolean load, FunctionName name, ConstantRef ref ) throws IOException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a add operator
|
* Write a add operator
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 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.ConstantRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WasmInstruction for set and get global variables.
|
||||||
|
*
|
||||||
|
* @author Volker Berlin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class WasmGlobalInstruction extends WasmInstruction {
|
||||||
|
|
||||||
|
private boolean load;
|
||||||
|
|
||||||
|
private ConstantRef ref;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an instance of a load/store instruction
|
||||||
|
*
|
||||||
|
* @param load
|
||||||
|
* true: if load or GET
|
||||||
|
* @param ref
|
||||||
|
* reference to a static field
|
||||||
|
* @param javaCodePos
|
||||||
|
* the code position/offset in the Java method
|
||||||
|
*/
|
||||||
|
WasmGlobalInstruction( boolean load, ConstantRef ref, int javaCodePos ) {
|
||||||
|
super( javaCodePos );
|
||||||
|
this.load = load;
|
||||||
|
this.ref = ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void writeTo( @Nonnull ModuleWriter writer ) throws IOException {
|
||||||
|
FunctionName name = new FunctionName( ref );
|
||||||
|
writer.writeGlobalAccess( load, name, ref );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
ValueType getPushValueType() {
|
||||||
|
return load ? ValueType.getValueType( ref.getType(), 0 ) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
int getPopCount() {
|
||||||
|
return load ? 0 : 1;
|
||||||
|
}
|
||||||
|
}
|
@ -16,11 +16,13 @@
|
|||||||
package de.inetsoftware.jwebassembly.text;
|
package de.inetsoftware.jwebassembly.text;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import de.inetsoftware.classparser.ConstantRef;
|
||||||
import de.inetsoftware.jwebassembly.module.FunctionName;
|
import de.inetsoftware.jwebassembly.module.FunctionName;
|
||||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||||
import de.inetsoftware.jwebassembly.module.NumericOperator;
|
import de.inetsoftware.jwebassembly.module.NumericOperator;
|
||||||
@ -42,6 +44,8 @@ public class TextModuleWriter extends ModuleWriter {
|
|||||||
|
|
||||||
private int inset;
|
private int inset;
|
||||||
|
|
||||||
|
private HashSet<String> globals = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance.
|
* Create a new instance.
|
||||||
*
|
*
|
||||||
@ -153,6 +157,22 @@ public class TextModuleWriter extends ModuleWriter {
|
|||||||
methodOutput.append( "set_local " ).append( Integer.toString( idx ) );
|
methodOutput.append( "set_local " ).append( Integer.toString( idx ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void writeGlobalAccess( boolean load, FunctionName name, ConstantRef ref ) throws IOException {
|
||||||
|
if( !globals.contains( name.fullName ) ) {
|
||||||
|
// declare global variable if not already declared.
|
||||||
|
output.append( "\n " );
|
||||||
|
String type = ValueType.getValueType( ref.getType(), 0 ).toString();
|
||||||
|
output.append( "(global $" ).append( name.fullName ).append( type ).append( ' ' ).append( type ).append( ".const 0)" );
|
||||||
|
globals.add( name.fullName );
|
||||||
|
}
|
||||||
|
newline( methodOutput );
|
||||||
|
methodOutput.append( load ? "get_local " : "set_local " ).append( name.fullName );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user