Skip to content

Commit dd29280

Browse files
VolkerVolker
authored andcommitted
Add support for global (static) variables
1 parent c269bae commit dd29280

File tree

6 files changed

+144
-5
lines changed

6 files changed

+144
-5
lines changed

src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import javax.annotation.Nonnull;
2727
import javax.annotation.Nullable;
2828

29+
import de.inetsoftware.classparser.ConstantRef;
2930
import de.inetsoftware.jwebassembly.WasmException;
3031
import de.inetsoftware.jwebassembly.module.FunctionName;
3132
import de.inetsoftware.jwebassembly.module.ModuleWriter;
@@ -387,6 +388,24 @@ protected void writeStore( int idx ) throws IOException {
387388
codeStream.writeVaruint32( idx );
388389
}
389390

391+
/**
392+
* {@inheritDoc}
393+
*/
394+
@Override
395+
protected void writeGlobalAccess( boolean load, FunctionName name, ConstantRef ref ) throws IOException {
396+
Global var = globals.get( name.fullName );
397+
if( var == null ) { // if not declared then create a definition in the global section
398+
var = new Global();
399+
var.id = globals.size();
400+
var.type = ValueType.getValueType( ref.getType(), 0 );
401+
var.mutability = true;
402+
globals.put( name.fullName, var );
403+
}
404+
int op = load ? GET_GLOBAL : SET_GLOBAL;
405+
codeStream.writeOpCode( op );
406+
codeStream.writeVaruint32( var.id );
407+
}
408+
390409
/**
391410
* {@inheritDoc}
392411
*/

src/de/inetsoftware/jwebassembly/binary/Global.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
*/
2525
class Global {
2626

27+
int id;
28+
2729
ValueType type;
2830

2931
boolean mutability;

src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -648,8 +648,14 @@ private void writeCode( CodeInputStream byteCode, ConstantPool constantPool ) t
648648
instr = new WasmBlockInstruction( WasmBlockOperator.RETURN, type, codePos );
649649
endWithReturn = true;
650650
break;
651-
//TODO case 178: // getstatic
652-
//TODO case 179: // putstatic
651+
case 178: // getstatic
652+
ConstantRef ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
653+
instr = new WasmGlobalInstruction( true, ref, codePos );
654+
break;
655+
case 179: // putstatic
656+
ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
657+
instr = new WasmGlobalInstruction( false, ref, codePos );
658+
break;
653659
//TODO case 180: // getfield
654660
//TODO case 181: // putfield
655661
//TODO case 182: // invokevirtual

src/de/inetsoftware/jwebassembly/module/ModuleWriter.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import javax.annotation.Nonnull;
2323
import javax.annotation.Nullable;
2424

25+
import de.inetsoftware.classparser.ConstantRef;
26+
2527
/**
2628
* Module Writer base class.
2729
*
@@ -144,6 +146,21 @@ protected void prepareFunction( FunctionName name ) {}
144146
*/
145147
protected abstract void writeStore( int idx ) throws IOException;
146148

149+
/**
150+
* Write a set_global variable
151+
* @param load
152+
* true: if load or GET
153+
* @param name
154+
* the variable name
155+
* @param ref
156+
* the definition of the variable
157+
*
158+
* @throws IOException
159+
* if any I/O error occur
160+
*/
161+
protected abstract void writeGlobalAccess( boolean load, FunctionName name, ConstantRef ref ) throws IOException;
162+
163+
147164
/**
148165
* Write a add operator
149166
*
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
Copyright 2018 Volker Berlin (i-net software)
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
16+
*/
17+
package de.inetsoftware.jwebassembly.module;
18+
19+
import java.io.IOException;
20+
21+
import javax.annotation.Nonnull;
22+
23+
import de.inetsoftware.classparser.ConstantRef;
24+
25+
/**
26+
* WasmInstruction for set and get global variables.
27+
*
28+
* @author Volker Berlin
29+
*
30+
*/
31+
class WasmGlobalInstruction extends WasmInstruction {
32+
33+
private boolean load;
34+
35+
private ConstantRef ref;
36+
37+
/**
38+
* Create an instance of a load/store instruction
39+
*
40+
* @param load
41+
* true: if load or GET
42+
* @param ref
43+
* reference to a static field
44+
* @param javaCodePos
45+
* the code position/offset in the Java method
46+
*/
47+
WasmGlobalInstruction( boolean load, ConstantRef ref, int javaCodePos ) {
48+
super( javaCodePos );
49+
this.load = load;
50+
this.ref = ref;
51+
}
52+
53+
/**
54+
* {@inheritDoc}
55+
*/
56+
public void writeTo( @Nonnull ModuleWriter writer ) throws IOException {
57+
FunctionName name = new FunctionName( ref );
58+
writer.writeGlobalAccess( load, name, ref );
59+
}
60+
61+
/**
62+
* {@inheritDoc}
63+
*/
64+
ValueType getPushValueType() {
65+
return load ? ValueType.getValueType( ref.getType(), 0 ) : null;
66+
}
67+
68+
/**
69+
* {@inheritDoc}
70+
*/
71+
@Override
72+
int getPopCount() {
73+
return load ? 0 : 1;
74+
}
75+
}

src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@
1616
package de.inetsoftware.jwebassembly.text;
1717

1818
import java.io.IOException;
19+
import java.util.HashSet;
1920
import java.util.List;
2021

2122
import javax.annotation.Nonnull;
2223
import javax.annotation.Nullable;
2324

25+
import de.inetsoftware.classparser.ConstantRef;
2426
import de.inetsoftware.jwebassembly.module.FunctionName;
2527
import de.inetsoftware.jwebassembly.module.ModuleWriter;
2628
import de.inetsoftware.jwebassembly.module.NumericOperator;
@@ -36,11 +38,13 @@
3638
*/
3739
public class TextModuleWriter extends ModuleWriter {
3840

39-
private Appendable output;
41+
private Appendable output;
4042

41-
private StringBuilder methodOutput = new StringBuilder();
43+
private StringBuilder methodOutput = new StringBuilder();
4244

43-
private int inset;
45+
private int inset;
46+
47+
private HashSet<String> globals = new HashSet<>();
4448

4549
/**
4650
* Create a new instance.
@@ -153,6 +157,22 @@ protected void writeStore( int idx ) throws IOException {
153157
methodOutput.append( "set_local " ).append( Integer.toString( idx ) );
154158
}
155159

160+
/**
161+
* {@inheritDoc}
162+
*/
163+
@Override
164+
protected void writeGlobalAccess( boolean load, FunctionName name, ConstantRef ref ) throws IOException {
165+
if( !globals.contains( name.fullName ) ) {
166+
// declare global variable if not already declared.
167+
output.append( "\n " );
168+
String type = ValueType.getValueType( ref.getType(), 0 ).toString();
169+
output.append( "(global $" ).append( name.fullName ).append( type ).append( ' ' ).append( type ).append( ".const 0)" );
170+
globals.add( name.fullName );
171+
}
172+
newline( methodOutput );
173+
methodOutput.append( load ? "get_local " : "set_local " ).append( name.fullName );
174+
}
175+
156176
/**
157177
* {@inheritDoc}
158178
*/

0 commit comments

Comments
 (0)