mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 02:44:47 +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.Nullable;
|
||||
|
||||
import de.inetsoftware.classparser.ConstantRef;
|
||||
import de.inetsoftware.jwebassembly.WasmException;
|
||||
import de.inetsoftware.jwebassembly.module.FunctionName;
|
||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||
@ -387,6 +388,24 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
||||
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}
|
||||
*/
|
||||
|
@ -24,6 +24,8 @@ import de.inetsoftware.jwebassembly.module.ValueType;
|
||||
*/
|
||||
class Global {
|
||||
|
||||
int id;
|
||||
|
||||
ValueType type;
|
||||
|
||||
boolean mutability;
|
||||
|
@ -648,8 +648,14 @@ public class ModuleGenerator {
|
||||
instr = new WasmBlockInstruction( WasmBlockOperator.RETURN, type, codePos );
|
||||
endWithReturn = true;
|
||||
break;
|
||||
//TODO case 178: // getstatic
|
||||
//TODO case 179: // putstatic
|
||||
case 178: // getstatic
|
||||
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 181: // putfield
|
||||
//TODO case 182: // invokevirtual
|
||||
|
@ -22,6 +22,8 @@ import java.util.List;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import de.inetsoftware.classparser.ConstantRef;
|
||||
|
||||
/**
|
||||
* Module Writer base class.
|
||||
*
|
||||
@ -144,6 +146,21 @@ public abstract class ModuleWriter implements Closeable {
|
||||
*/
|
||||
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
|
||||
*
|
||||
|
@ -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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import de.inetsoftware.classparser.ConstantRef;
|
||||
import de.inetsoftware.jwebassembly.module.FunctionName;
|
||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||
import de.inetsoftware.jwebassembly.module.NumericOperator;
|
||||
@ -36,11 +38,13 @@ import de.inetsoftware.jwebassembly.module.WasmBlockOperator;
|
||||
*/
|
||||
public class TextModuleWriter extends ModuleWriter {
|
||||
|
||||
private Appendable output;
|
||||
private Appendable output;
|
||||
|
||||
private StringBuilder methodOutput = new StringBuilder();
|
||||
private StringBuilder methodOutput = new StringBuilder();
|
||||
|
||||
private int inset;
|
||||
private int inset;
|
||||
|
||||
private HashSet<String> globals = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
@ -153,6 +157,22 @@ public class TextModuleWriter extends ModuleWriter {
|
||||
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}
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user