Skip to content

Commit

Permalink
✨ Update Debug Console, the type inference for struct type is buggy (…
Browse files Browse the repository at this point in the history
…can't obtain the typedef information from bc0)!
  • Loading branch information
MarkChenYutian committed Jun 26, 2022
1 parent a817b07 commit 98f463b
Show file tree
Hide file tree
Showing 19 changed files with 46,724 additions and 65 deletions.
46,424 changes: 46,422 additions & 2 deletions public/index.js

Large diffs are not rendered by default.

48 changes: 31 additions & 17 deletions src/exec/exec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import { CloneType, getType, maybeStringType, maybeValueType, String2Type } from "../types/c0type_utility";
import * as Arithmetic from "../utility/arithmetic";
import * as TypeUtil from "../types/c0type_utility";

import { build_c0_ptrValue, build_c0_value, js_cvt2_c0_value, is_same_value, build_c0_stringValue } from "../utility/c0_value";
import { c0_memory_error, c0_user_error, vm_error } from "../utility/errors";
import { read_ptr, shift_ptr } from "../utility/pointer_ops";
import { loadString } from "../utility/string_utility";
import { safe_pop_stack } from "./helpers";

/**
* Main function of C0VM.ts, perform transformation on VM_State and allocator
* @param state Current state of virtual machine
* @param allocator The heap memory allocator of current VM
* @returns `true` if the VM is still able to "step forward"
* @returns `false` if this step is the last step of current program
*/
export function step(state: VM_State, allocator: C0HeapAllocator): boolean {
const F = state.CurrFrame.P; // the function that is currently running on
if (globalThis.DEBUG_DUMP_STEP) {
Expand All @@ -21,11 +29,11 @@ export function step(state: VM_State, allocator: C0HeapAllocator): boolean {
const v = safe_pop_stack(state.CurrFrame.S);
const nv = {
value: new DataView(v.value.buffer.slice(v.value.byteOffset, v.value.byteLength)),
type: CloneType(v.type)
type: TypeUtil.CloneType(v.type)
};

state.CurrFrame.S.push(v);
state.CurrFrame.S.push(nv as C0Value<C0TypeClass>);
state.CurrFrame.S.push(nv);
break;
}

Expand Down Expand Up @@ -306,7 +314,7 @@ export function step(state: VM_State, allocator: C0HeapAllocator): boolean {
state.CurrFrame.PC += 1;

const str_ptr = safe_pop_stack(state.CurrFrame.S);
if (!maybeStringType(str_ptr)) {
if (!TypeUtil.maybeStringType(str_ptr)) {
throw new vm_error(`Type unmatch: expected a pointer in C0Value, received a ${str_ptr.type.type}`);
}
throw new c0_user_error(loadString(str_ptr, allocator));
Expand All @@ -317,11 +325,11 @@ export function step(state: VM_State, allocator: C0HeapAllocator): boolean {
state.CurrFrame.PC += 1;

const str_ptr = safe_pop_stack(state.CurrFrame.S);
if (!maybeStringType(str_ptr)) {
if (!TypeUtil.maybeStringType(str_ptr)) {
throw new vm_error(`Type unmatch: expected a string in C0Value, received a ${str_ptr.type.type}`);
}
const val = safe_pop_stack(state.CurrFrame.S);
if (!maybeValueType(val)) {
if (!TypeUtil.maybeValueType(val)) {
throw new vm_error(`Type unmatch: expected a value in C0Value, received a ${str_ptr.type.type}`);
}
if (val.value.getUint32(0) === 0) {
Expand Down Expand Up @@ -489,7 +497,7 @@ export function step(state: VM_State, allocator: C0HeapAllocator): boolean {
state.CurrFrame.PC += 2;

const ptr = allocator.malloc(s);
const T = String2Type(F.comment.get(state.CurrFrame.PC - 2).dataType);
const T = TypeUtil.String2Type(F.comment.get(state.CurrFrame.PC - 2).dataType);
if (T.type === C0TypeClass.ptr && T.kind === "struct") {
state.CurrFrame.S.push(
{value: ptr, type: T}
Expand Down Expand Up @@ -536,19 +544,18 @@ export function step(state: VM_State, allocator: C0HeapAllocator): boolean {
state.CurrFrame.PC += 1;

const a = safe_pop_stack(state.CurrFrame.S);
if (a.type.type !== C0TypeClass.ptr && a.type.type !== C0TypeClass.unknown) {
if (!TypeUtil.maybePointerType(a)) {
throw new vm_error("Type unmatch, AMLOAD expect to receive a pointer");
}
const mem_block = allocator.amload(a.value);
if (a.type.type === C0TypeClass.ptr) {
if (a.type.kind === "struct") {
state.CurrFrame.S.push(
// @ts-ignore
{value: mem_block, type: (getType(a.type) as C0Type<C0TypeClass>)}
{value: mem_block, type: (TypeUtil.getType(a.type))}
)
} else {
state.CurrFrame.S.push(
{value: mem_block, type: (a.type.value as C0Type<C0TypeClass.ptr>)}
{value: mem_block, type: (a.type.value)}
);
}
} else {
Expand Down Expand Up @@ -583,7 +590,7 @@ export function step(state: VM_State, allocator: C0HeapAllocator): boolean {
state.CurrFrame.PC += 1;

const a = safe_pop_stack(state.CurrFrame.S);
if (a.type.type !== C0TypeClass.ptr && a.type.type !== C0TypeClass.unknown) {
if (!TypeUtil.maybePointerType(a)) {
throw new vm_error("Type unmatch, CMLOAD expect to receive a pointer");
}
const mem_block = allocator.cmload(a.value);
Expand Down Expand Up @@ -620,13 +627,13 @@ export function step(state: VM_State, allocator: C0HeapAllocator): boolean {
state.CurrFrame.PC += 2;

const a = safe_pop_stack(state.CurrFrame.S);
if (a.type.type !== C0TypeClass.ptr && a.type.type !== C0TypeClass.unknown) {
if (!TypeUtil.maybePointerType(a)) {
throw new vm_error("Type unmatch, AADDF expect to receive a pointer");
}
const off_ptr = shift_ptr(a.value, f);

if (a.type.type === C0TypeClass.ptr) {
const new_type = (CloneType(a.type) as C0Type<C0TypeClass.ptr>);
const new_type = (TypeUtil.CloneType(a.type) as C0Type<C0TypeClass.ptr>);
if (new_type.kind !== "struct") throw new vm_error("AADDF should only be applied on a struct pointer");
new_type.offset += f;
state.CurrFrame.S.push(
Expand Down Expand Up @@ -657,8 +664,16 @@ export function step(state: VM_State, allocator: C0HeapAllocator): boolean {

allocator.deref(ptr).setUint32(0, f);
state.CurrFrame.S.push(
build_c0_ptrValue(ptr, "arr", String2Type(F.comment.get(state.CurrFrame.PC - 2).dataType))
{
value: ptr,
type: {type: C0TypeClass.ptr, kind: "arr", value: TypeUtil.String2Type(F.comment.get(state.CurrFrame.PC - 2).dataType)}
}
);

console.log("NEWARRAY");
console.log(F.comment.get(state.CurrFrame.PC - 2).dataType);
console.log(TypeUtil.String2Type(F.comment.get(state.CurrFrame.PC - 2).dataType));

break;
}

Expand All @@ -684,8 +699,7 @@ export function step(state: VM_State, allocator: C0HeapAllocator): boolean {

const i = safe_pop_stack(state.CurrFrame.S);
const a = safe_pop_stack(state.CurrFrame.S);
if ((i.type.type !== C0TypeClass.value && i.type.type !== C0TypeClass.unknown)
|| a.type.type !== C0TypeClass.ptr) {
if (!TypeUtil.maybeValueType(i) || a.type.type !== C0TypeClass.ptr) {
throw new vm_error("Type unmatch, expected to have {ptr, value}");
}

Expand Down
24 changes: 23 additions & 1 deletion src/exec/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,20 @@ import { createHeap, VM_Memory } from "../utility/memory";
import parse from "../parser/parse";
import { loadStringPool } from "../utility/string_utility";

/**
* The C0 Virtual Machine Runtime with interface of operation
*/
export default class C0VM_RuntimeState implements C0VM_RT{
public code: C0ByteCode;
public state: VM_State;
public allocator: C0HeapAllocator;

/**
* Creating a new C0VM Runtime
* @param rawByteCode The bc0 bytecode string
* @param heapSize Heap size (in bytes), optional, if not explicitly designated, then use the
* GlobalThis.MEM_POOL_DEFAULT_SIZE as the size.
*/
constructor(rawByteCode: string, heapSize?: number) {
this.code = parse(rawByteCode);
this.allocator = createHeap(VM_Memory, heapSize);
Expand All @@ -29,10 +38,19 @@ export default class C0VM_RuntimeState implements C0VM_RT{
};
}

/**
* Step forward for the C0VM Runtime State.
* @returns If the runtime state is able to perform next "step forward"
*/
public step_forward(): boolean {
return step(this.state, this.allocator);
}

/**
* Re-initialize the state **without passing in bytecode file**
* The parsed bytecode is stored in the .code property of runtime and is
* loaded again when this function is called.
*/
public restart(): void {
this.allocator.clear();
const str_ptr = loadStringPool(this.code.stringPool, this.allocator);
Expand All @@ -53,7 +71,11 @@ export default class C0VM_RuntimeState implements C0VM_RT{
};
}

/**
* A "peek hole" to help debug the VM
* @returns The memory dump when DEBUG is activated
*/
public debug(): any {
return this.allocator.debug_getMemPool();
if (globalThis.DEBUG) return this.allocator.debug_getMemPool();
}
}
9 changes: 8 additions & 1 deletion src/gui/code_editor_setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import LoadDocumentPlugin from "./extensions/loader_ui";
import { onViewUpdate } from "./extensions/on_view_update";
import { EditorState } from "@codemirror/state";

/**
* Initialize an editor state with given content
* @param s The string the editor will show in content area
* @returns Editor State
*/
export function new_editor_state(s: string): EditorState {
return EditorState.create({
extensions: [
Expand All @@ -35,11 +40,13 @@ export function new_editor_state(s: string): EditorState {

// Auto-detect language
// https://codemirror.net/examples/config/
/**
* Initialize the editor
*/
export function editor_init() {
globalThis.EDITOR_VIEW = new EditorView({
parent: document.getElementById(globalThis.UI_INPUT_ID),
state: new_editor_state("")
});
console.log(`[C0VM.ts] C0 Editor Initialized.`);
}

1 change: 1 addition & 0 deletions src/gui/console_emitter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* A message emitter that emits message to console. Used for test & debug.
* Or used in "node" ENVIRN_MODE
*/
export default class ConsoleEmitter implements MessageEmitter {
err(msg: string, detail?: string): void {
Expand Down
Loading

0 comments on commit 98f463b

Please sign in to comment.