From dfe88311ded98bf1a1d851a7bbc221187afb6ad4 Mon Sep 17 00:00:00 2001 From: Shen Yi Hong Date: Mon, 1 Apr 2024 19:13:59 +0800 Subject: [PATCH] feat: implement `GoRoutineOp` support in heap --- src/go-slang/goroutine.ts | 16 +++++++++++----- src/go-slang/lib/heap/config.ts | 2 +- src/go-slang/lib/heap/index.ts | 24 +++++++++++++----------- src/go-slang/lib/heap/tags.ts | 1 + 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/go-slang/goroutine.ts b/src/go-slang/goroutine.ts index 8fd1635ef..56b59d4a2 100644 --- a/src/go-slang/goroutine.ts +++ b/src/go-slang/goroutine.ts @@ -181,11 +181,17 @@ const Interpreter: { } const { callee, args } = call as CallExpression - return C.pushR(...H.allocM([callee, ...args]), { - type: CommandType.GoRoutineOp, - calleeNodeId: A.track(callee).uid as number, - arity: args.length - }) + return C.pushR( + ...H.allocM([ + callee, + ...args, + { + type: CommandType.GoRoutineOp, + calleeNodeId: A.track(callee).uid as number, + arity: args.length + } + ]) + ) }, EmptyStatement: () => void {}, diff --git a/src/go-slang/lib/heap/config.ts b/src/go-slang/lib/heap/config.ts index 31b6093f4..9f009bc6b 100644 --- a/src/go-slang/lib/heap/config.ts +++ b/src/go-slang/lib/heap/config.ts @@ -2,7 +2,7 @@ // The default size of the heap in words // Total heap size (in bytes) = DEFAULT_HEAP_SIZE * WORD_SIZE -export const DEFAULT_HEAP_SIZE = 1024 // in words +export const DEFAULT_HEAP_SIZE = 4096 // in words // The smallest addressable unit in the heap // We can think of it as the heap containing N number of words, each of size WORD_SIZE diff --git a/src/go-slang/lib/heap/index.ts b/src/go-slang/lib/heap/index.ts index a01e74730..15fae250c 100644 --- a/src/go-slang/lib/heap/index.ts +++ b/src/go-slang/lib/heap/index.ts @@ -6,6 +6,7 @@ import { ClosureOp, CommandType, EnvOp, + GoRoutineOp, Node, PopS, UnaryOp, @@ -72,6 +73,7 @@ export class Heap { case CommandType.BinaryOp: return this.allocateUnaryBinaryOp(value) case CommandType.CallOp: + case CommandType.GoRoutineOp: return this.allocateCallOp(value) case CommandType.BuiltinOp: return this.allocateBuiltinOp(value) @@ -103,8 +105,9 @@ export class Heap { return heap_addr } + const tag = this.tag(heap_addr) const mem_addr = heap_addr * WORD_SIZE - switch (this.tag(heap_addr)) { + switch (tag) { case PointerTag.False: return false case PointerTag.True: @@ -125,21 +128,18 @@ export class Heap { idNodeUid: this.memory.getInt16(mem_addr + 1) } as AssignOp case PointerTag.UnaryOp: - return { - type: CommandType.UnaryOp, - opNodeId: this.memory.getInt16(mem_addr + 1) - } as UnaryOp case PointerTag.BinaryOp: return { - type: CommandType.BinaryOp, + type: tag === PointerTag.UnaryOp ? CommandType.UnaryOp : CommandType.BinaryOp, opNodeId: this.memory.getInt16(mem_addr + 1) - } as BinaryOp + } as UnaryOp | BinaryOp case PointerTag.CallOp: + case PointerTag.GoRoutineOp: return { - type: CommandType.CallOp, + type: tag === PointerTag.CallOp ? CommandType.CallOp : CommandType.GoRoutineOp, calleeNodeId: this.memory.getInt16(mem_addr + 1), arity: this.memory.getInt16(mem_addr + 3) - } as CallOp + } as CallOp | GoRoutineOp case PointerTag.BuiltInOp: return { type: CommandType.BuiltinOp, @@ -225,8 +225,10 @@ export class Heap { } /* Memory Layout of a CallOp: [0:tag, 1-2:calleeNodeId, 3-4:arity, 5-6:size, 7:_unused_] (1 word) */ - private allocateCallOp({ calleeNodeId, arity }: CallOp): HeapAddress { - const ptr_heap_addr = this.allocateTaggedPtr(PointerTag.CallOp) + private allocateCallOp({ type, calleeNodeId, arity }: CallOp | GoRoutineOp): HeapAddress { + const ptr_heap_addr = this.allocateTaggedPtr( + type === CommandType.CallOp ? PointerTag.CallOp : PointerTag.GoRoutineOp + ) const ptr_mem_addr = ptr_heap_addr * WORD_SIZE // NOTE: assume there will be no more than 2^16 AST nodes diff --git a/src/go-slang/lib/heap/tags.ts b/src/go-slang/lib/heap/tags.ts index 4f6c26f26..e72a6e331 100644 --- a/src/go-slang/lib/heap/tags.ts +++ b/src/go-slang/lib/heap/tags.ts @@ -8,6 +8,7 @@ export enum PointerTag { UnaryOp, BinaryOp, CallOp, + GoRoutineOp, BuiltInOp, ClosureOp, EnvOp,