mirror of
https://github.com/DaanVandenBosch/phantasmal-world.git
synced 2025-04-05 23:38:30 +08:00
Reworked VirtualMachineMemoryBuffer to extend ArrayBufferCursor.
This commit is contained in:
parent
aad45b0929
commit
2909b1bb3e
@ -74,6 +74,8 @@ import {
|
|||||||
Kind,
|
Kind,
|
||||||
} from "../opcodes";
|
} from "../opcodes";
|
||||||
import Logger from "js-logger";
|
import Logger from "js-logger";
|
||||||
|
import { ArrayBufferCursor } from "../../../core/data_formats/cursor/ArrayBufferCursor";
|
||||||
|
import { Endianness } from "../../../core/data_formats/Endianness";
|
||||||
|
|
||||||
const logger = Logger.get("quest_editor/scripting/vm");
|
const logger = Logger.get("quest_editor/scripting/vm");
|
||||||
|
|
||||||
@ -167,7 +169,7 @@ function ranges_overlap(a: Range, b: Range): boolean {
|
|||||||
return a[0] <= b[1] && b[0] <= a[1];
|
return a[0] <= b[1] && b[0] <= a[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
class VirtualMachineMemoryBuffer extends ArrayBuffer {
|
class VirtualMachineMemoryBuffer extends ArrayBufferCursor {
|
||||||
/**
|
/**
|
||||||
* The memory this buffer belongs to.
|
* The memory this buffer belongs to.
|
||||||
*/
|
*/
|
||||||
@ -178,7 +180,7 @@ class VirtualMachineMemoryBuffer extends ArrayBuffer {
|
|||||||
public readonly address: number;
|
public readonly address: number;
|
||||||
|
|
||||||
constructor(memory: VirtualMachineMemory, address: number, size: number) {
|
constructor(memory: VirtualMachineMemory, address: number, size: number) {
|
||||||
super(size);
|
super(new ArrayBuffer(size), Endianness.Little);
|
||||||
this.memory = memory;
|
this.memory = memory;
|
||||||
this.address = address;
|
this.address = address;
|
||||||
}
|
}
|
||||||
@ -190,6 +192,10 @@ class VirtualMachineMemoryBuffer extends ArrayBuffer {
|
|||||||
public free(): void {
|
public free(): void {
|
||||||
this.memory.free(this.address);
|
this.memory.free(this.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public zero(): void {
|
||||||
|
new Uint32Array(this.backing_buffer).fill(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -374,12 +380,10 @@ class VirtualMachineMemory {
|
|||||||
|
|
||||||
export class VirtualMachine {
|
export class VirtualMachine {
|
||||||
private memory = new VirtualMachineMemory();
|
private memory = new VirtualMachineMemory();
|
||||||
private register_store = this.memory.allocate(
|
private registers = this.memory.allocate(
|
||||||
REGISTER_SIZE * REGISTER_COUNT,
|
REGISTER_SIZE * REGISTER_COUNT,
|
||||||
REGISTERS_BASE_ADDRESS,
|
REGISTERS_BASE_ADDRESS,
|
||||||
)!;
|
)!;
|
||||||
private register_uint8_view = new Uint8Array(this.register_store);
|
|
||||||
private registers = new DataView(this.register_store);
|
|
||||||
private object_code: Segment[] = [];
|
private object_code: Segment[] = [];
|
||||||
private label_to_seg_idx: Map<number, number> = new Map();
|
private label_to_seg_idx: Map<number, number> = new Map();
|
||||||
private thread: Thread[] = [];
|
private thread: Thread[] = [];
|
||||||
@ -764,19 +768,19 @@ export class VirtualMachine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private get_sint(reg: number): number {
|
private get_sint(reg: number): number {
|
||||||
return this.registers.getInt32(REGISTER_SIZE * reg);
|
return this.registers.i32_at(REGISTER_SIZE * reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private set_sint(reg: number, value: number): void {
|
private set_sint(reg: number, value: number): void {
|
||||||
this.registers.setInt32(REGISTER_SIZE * reg, value);
|
this.registers.write_i32_at(REGISTER_SIZE * reg, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private get_uint(reg: number): number {
|
private get_uint(reg: number): number {
|
||||||
return this.registers.getUint32(REGISTER_SIZE * reg);
|
return this.registers.u32_at(REGISTER_SIZE * reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private set_uint(reg: number, value: number): void {
|
private set_uint(reg: number, value: number): void {
|
||||||
this.registers.setUint32(REGISTER_SIZE * reg, value);
|
this.registers.write_u32_at(REGISTER_SIZE * reg, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private do_numeric_op_with_register(
|
private do_numeric_op_with_register(
|
||||||
@ -958,11 +962,11 @@ export class VirtualMachine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private clear_registers(): void {
|
private clear_registers(): void {
|
||||||
this.register_uint8_view.fill(0);
|
this.registers.zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
private get_register_address(reg: number): number {
|
private get_register_address(reg: number): number {
|
||||||
return this.register_store.address + reg * REGISTER_SIZE;
|
return this.registers.address + reg * REGISTER_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -978,9 +982,8 @@ class Thread {
|
|||||||
*/
|
*/
|
||||||
public call_stack: ExecutionLocation[] = [];
|
public call_stack: ExecutionLocation[] = [];
|
||||||
|
|
||||||
private arg_stack_buf: VirtualMachineMemoryBuffer;
|
private arg_stack: VirtualMachineMemoryBuffer;
|
||||||
private arg_stack_counter: number = 0;
|
private arg_stack_counter: number = 0;
|
||||||
private arg_stack: DataView;
|
|
||||||
private arg_stack_types: ArgStackTypeList = Array(ARG_STACK_LENGTH).fill(
|
private arg_stack_types: ArgStackTypeList = Array(ARG_STACK_LENGTH).fill(
|
||||||
Kind.Any,
|
Kind.Any,
|
||||||
) as ArgStackTypeList;
|
) as ArgStackTypeList;
|
||||||
@ -993,14 +996,13 @@ class Thread {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
next: ExecutionLocation,
|
next: ExecutionLocation,
|
||||||
arg_stack_buf: VirtualMachineMemoryBuffer,
|
arg_stack: VirtualMachineMemoryBuffer,
|
||||||
global: boolean,
|
global: boolean,
|
||||||
) {
|
) {
|
||||||
this.call_stack = [next];
|
this.call_stack = [next];
|
||||||
this.global = global;
|
this.global = global;
|
||||||
|
|
||||||
this.arg_stack_buf = arg_stack_buf;
|
this.arg_stack = arg_stack;
|
||||||
this.arg_stack = new DataView(arg_stack_buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public call_stack_top(): ExecutionLocation {
|
public call_stack_top(): ExecutionLocation {
|
||||||
@ -1012,7 +1014,7 @@ class Thread {
|
|||||||
throw new Error("Argument stack: Stack overflow");
|
throw new Error("Argument stack: Stack overflow");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.arg_stack.setUint32(this.arg_stack_counter * ARG_STACK_SLOT_SIZE, data, true);
|
this.arg_stack.write_u32_at(this.arg_stack_counter * ARG_STACK_SLOT_SIZE, data);
|
||||||
this.arg_stack_types[this.arg_stack_counter] = type;
|
this.arg_stack_types[this.arg_stack_counter] = type;
|
||||||
|
|
||||||
this.arg_stack_counter++;
|
this.arg_stack_counter++;
|
||||||
@ -1034,14 +1036,14 @@ class Thread {
|
|||||||
|
|
||||||
switch (param.type.kind) {
|
switch (param.type.kind) {
|
||||||
case Kind.Byte:
|
case Kind.Byte:
|
||||||
args.push(this.arg_stack.getUint8(i));
|
args.push(this.arg_stack.u8_at(i * ARG_STACK_SLOT_SIZE));
|
||||||
break;
|
break;
|
||||||
case Kind.Word:
|
case Kind.Word:
|
||||||
args.push(this.arg_stack.getUint16(i, true));
|
args.push(this.arg_stack.u16_at(i * ARG_STACK_SLOT_SIZE));
|
||||||
break;
|
break;
|
||||||
case Kind.DWord:
|
case Kind.DWord:
|
||||||
case Kind.String:
|
case Kind.String:
|
||||||
args.push(this.arg_stack.getUint32(i, true));
|
args.push(this.arg_stack.u32_at(i * ARG_STACK_SLOT_SIZE));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unhandled param kind: Kind.${Kind[param.type.kind]}`);
|
throw new Error(`Unhandled param kind: Kind.${Kind[param.type.kind]}`);
|
||||||
@ -1054,6 +1056,6 @@ class Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public dispose(): void {
|
public dispose(): void {
|
||||||
this.arg_stack_buf.free();
|
this.arg_stack.free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user