mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 02:44:47 +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