Adds RecordArray that generalizes several tasks performed by debugger.

This commit is contained in:
konsoletyper 2014-08-22 17:38:41 +04:00
parent fed5637d4d
commit 0f81841cf5
2 changed files with 240 additions and 0 deletions

View File

@ -0,0 +1,92 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.common;
import java.util.Arrays;
/**
*
* @author Alexey Andreev
*/
public class RecordArray {
private int recordSize;
private int arraysPerRecord;
private int[] data;
private int[] substart;
private int[] subdata;
RecordArray(int recordSize, int arraysPerRecord, int[] data, int[] substart, int[] subdata) {
this.recordSize = recordSize;
this.arraysPerRecord = arraysPerRecord;
this.data = data;
this.substart = substart;
this.subdata = subdata;
}
public Record get(int index) {
return new Record(index * recordSize, index * arraysPerRecord);
}
public int size() {
return data.length / recordSize;
}
public int getRecordSize() {
return recordSize;
}
public int arraysPerRecord() {
return arraysPerRecord;
}
public class Record {
int offset;
int arrayOffset;
Record(int offset, int arrayOffset) {
this.offset = offset;
this.arrayOffset = arrayOffset;
}
public int getPosition() {
return offset / recordSize;
}
public int get(int index) {
if (index >= recordSize) {
throw new IndexOutOfBoundsException("Index out of bounds: " + index + " of " + recordSize);
}
return data[offset + index];
}
public int size() {
return recordSize;
}
public int[] getArray(int index) {
if (index > arraysPerRecord) {
throw new IndexOutOfBoundsException("Index out of bounds: " + index + " of " + arraysPerRecord);
}
int start = substart[arrayOffset + index];
int end = substart[arrayOffset + index + 1];
return Arrays.copyOfRange(subdata, start, end);
}
public int numArrays() {
return arraysPerRecord;
}
}
}

View File

@ -0,0 +1,148 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.common;
/**
*
* @author Alexey Andreev
*/
public class RecordArrayBuilder {
private int recordSize;
private int arraysPerRecord;
private IntegerArray data = new IntegerArray(1);
private IntegerArray substart = new IntegerArray(1);
private IntegerArray subdata = new IntegerArray(1);
private IntegerArray subnext = new IntegerArray(1);
public RecordArrayBuilder(int recordSize, int arraysPerRecord) {
this.recordSize = recordSize;
this.arraysPerRecord = arraysPerRecord;
}
public Record get(int index) {
return new Record(index * recordSize, index * arraysPerRecord);
}
public Record add() {
int offset = data.size();
for (int i = 0; i < recordSize; ++i) {
data.add(0);
}
int arrayOffset = substart.size();
for (int i = 0; i < arraysPerRecord; ++i) {
substart.add(-1);
}
return new Record(offset, arrayOffset);
}
public int size() {
return data.size() / recordSize;
}
public int getRecordSize() {
return recordSize;
}
public int getArraysPerRecord() {
return arraysPerRecord;
}
public RecordArray build() {
int[] builtSubstart = new int[substart.size() + 1];
IntegerArray builtSubdata = new IntegerArray(1);
for (int i = 0; i < substart.size(); ++i) {
int ptr = substart.get(i);
while (ptr >= 0) {
builtSubdata.add(subdata.get(ptr));
ptr = subnext.get(ptr);
}
builtSubstart[i + 1] = builtSubdata.size();
}
return new RecordArray(recordSize, arraysPerRecord, data.getAll(), builtSubstart, builtSubdata.getAll());
}
public class Record {
private int offset;
private int arrayOffset;
public Record(int offset, int arrayOffset) {
this.offset = offset;
this.arrayOffset = arrayOffset;
}
public int getPosition() {
return offset / recordSize;
}
public int get(int index) {
if (index >= recordSize) {
throw new IndexOutOfBoundsException("Index out of bounds: " + index + " of " + recordSize);
}
return data.get(index + offset);
}
public int size() {
return recordSize;
}
public int numArrays() {
return arraysPerRecord;
}
public RecordSubArray getArray(int index) {
if (index > arraysPerRecord) {
throw new IndexOutOfBoundsException("Index out of bounds: " + index + " of " + arraysPerRecord);
}
return new RecordSubArray(arrayOffset + index);
}
}
public class RecordSubArray {
private int offset;
public RecordSubArray(int offset) {
this.offset = offset;
}
public int[] getData() {
IntegerArray array = new IntegerArray(1);
int ptr = substart.get(offset);
while (ptr >= 0) {
array.add(subdata.get(ptr));
ptr = subnext.get(ptr);
}
int[] result = array.getAll();
int half = result.length / 2;
for (int i = 0; i < half; ++i) {
int tmp = result[i];
result[i] = result[result.length - i - 1];
result[result.length - i - 1] = tmp;
}
return result;
}
public void clear() {
substart.set(offset, -1);
}
public void add(int value) {
int ptr = substart.get(offset);
substart.set(offset, subdata.size());
subdata.add(value);
subnext.add(ptr);
}
}
}