mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 15:37:52 +01:00
Add a local variable manager
This commit is contained in:
parent
20da7f8fdd
commit
bc66cfa70e
@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
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.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.inetsoftware.jwebassembly.WasmException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This manager monitor the locale variables of a method to create a translation from the slot based index in Java to
|
||||||
|
* the variable based index in WebAssembly. An 8-byte variable of type long and double consumes in Java 2 slots, but
|
||||||
|
* only one index in WebAssmenbly.
|
||||||
|
*
|
||||||
|
* @author Volker Berlin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class LocaleVariableManager {
|
||||||
|
|
||||||
|
private LocaleVariable[] variables;
|
||||||
|
|
||||||
|
private int size;
|
||||||
|
|
||||||
|
private ArrayList<ValueType> localTypes = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
*/
|
||||||
|
LocaleVariableManager() {
|
||||||
|
// initialize with a initial capacity that should be enough for the most methods
|
||||||
|
variables = new LocaleVariable[8];
|
||||||
|
for( int i = 0; i < variables.length; i++ ) {
|
||||||
|
variables[i] = new LocaleVariable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the manager to an initial state
|
||||||
|
*/
|
||||||
|
void reset() {
|
||||||
|
for( int i = 0; i < size; i++ ) {
|
||||||
|
LocaleVariable var = variables[i];
|
||||||
|
var.valueType = null;
|
||||||
|
var.idx = -1;
|
||||||
|
}
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark a variable slot as used with its type.
|
||||||
|
*
|
||||||
|
* @param valueType
|
||||||
|
* the type of the local variable
|
||||||
|
* @param slot
|
||||||
|
* the memory/slot index of the local variable
|
||||||
|
*/
|
||||||
|
void use( ValueType valueType, int slot ) {
|
||||||
|
ensureCapacity( slot );
|
||||||
|
size = Math.max( size, slot + 1 );
|
||||||
|
LocaleVariable var = variables[slot];
|
||||||
|
if( var.valueType != null && var.valueType != valueType ) {
|
||||||
|
throw new WasmException( "Redefine local variable type from " + var.valueType + " to "
|
||||||
|
+ valueType, null, -1 );
|
||||||
|
}
|
||||||
|
var.valueType = valueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the WebAssembly index position on the consumed data.
|
||||||
|
*/
|
||||||
|
void calculate() {
|
||||||
|
int idx = 0;
|
||||||
|
for( int i = 0; i < size; i++ ) {
|
||||||
|
LocaleVariable var = variables[i];
|
||||||
|
if( var.valueType == null ) { // unused slot or extra slot for double and long values
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var.idx = idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data types of the local variables. The value is only valid until the next call.
|
||||||
|
*
|
||||||
|
* @param paramCount
|
||||||
|
* the count of method parameter which should be exclude
|
||||||
|
* @return the reused list with fresh values
|
||||||
|
*/
|
||||||
|
List<ValueType> getLocalTypes( int paramCount ) {
|
||||||
|
localTypes.clear();
|
||||||
|
for( int i = 0; i < size; i++ ) {
|
||||||
|
LocaleVariable var = variables[i];
|
||||||
|
if( var.idx >= paramCount ) {
|
||||||
|
localTypes.add( var.valueType );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return localTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the WebAssembly variable index of the given Java Slot.
|
||||||
|
*
|
||||||
|
* @param slot
|
||||||
|
* the memory/slot index of the local variable in Java
|
||||||
|
* @return the variable index in WebAssembly
|
||||||
|
*/
|
||||||
|
int get( int slot ) {
|
||||||
|
return variables[slot].idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that there is enough capacity.
|
||||||
|
*
|
||||||
|
* @param slot
|
||||||
|
* the needed slot
|
||||||
|
*/
|
||||||
|
private void ensureCapacity( int slot ) {
|
||||||
|
if( slot >= variables.length ) {
|
||||||
|
int i = variables.length;
|
||||||
|
variables = Arrays.copyOf( variables, slot + 1 );
|
||||||
|
for( ; i < variables.length; i++ ) {
|
||||||
|
variables[i] = new LocaleVariable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The state of a single local variable slot.
|
||||||
|
*/
|
||||||
|
private static class LocaleVariable {
|
||||||
|
private ValueType valueType;
|
||||||
|
|
||||||
|
private int idx = -1;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user