diff --git a/src/go-slang/ece.ts b/src/go-slang/ece.ts index f7bd06fb8..5199d039c 100644 --- a/src/go-slang/ece.ts +++ b/src/go-slang/ece.ts @@ -111,9 +111,6 @@ export function evaluate(program: SourceFile, slangContext: SlangContext): Value } } - // TEMP: for debugging purposes - console.log('Total memory allocated: ', H._debug_num_allocations() * 8, 'bytes') - return 'Program exited' } @@ -128,8 +125,8 @@ const interpreter: { E.declare(id.name, { type: CommandType.ClosureOp, funcDeclNodeUid, envId: E.id() } as ClosureOp) }, - Block: ({ statements }: Block, { C, E }) => { - C.pushR(...statements, { type: CommandType.EnvOp, envId: E.id() }) + Block: ({ statements }: Block, { C, E, H }) => { + C.pushR(...statements, H.alloc({ type: CommandType.EnvOp, envId: E.id() })) E.extend({}) }, @@ -240,7 +237,7 @@ const interpreter: { return new FuncArityError(calleeId.name, values.length, params.length) } - C.pushR(body, RetMarker, { type: CommandType.EnvOp, envId: E.id() }) + C.pushR(body, RetMarker, H.alloc({ type: CommandType.EnvOp, envId: E.id() })) // set the environment to the closure's environment E.setId(envId).extend(Object.fromEntries(zip(paramNames, values))) }, diff --git a/src/go-slang/lib/heap/index.ts b/src/go-slang/lib/heap/index.ts index c6f0fbcb7..f6fa76c20 100644 --- a/src/go-slang/lib/heap/index.ts +++ b/src/go-slang/lib/heap/index.ts @@ -1,4 +1,13 @@ -import { BuiltinOp, CallOp, ClosureOp, CommandType, Node, isCommand, isNode } from '../../types' +import { + BuiltinOp, + CallOp, + ClosureOp, + CommandType, + EnvOp, + Node, + isCommand, + isNode +} from '../../types' import { AstMap } from '../astMap' import { DEFAULT_HEAP_SIZE, WORD_SIZE } from './config' import { PointerTag } from './tags' @@ -56,6 +65,8 @@ export class Heap { return this.allocateBuiltinOp(value) case CommandType.ClosureOp: return this.allocateClosureOp(value) + case CommandType.EnvOp: + return this.allocateEnvOp(value) } } @@ -106,6 +117,11 @@ export class Heap { funcDeclNodeUid: this.memory.getInt16(mem_addr + 1), envId: this.memory.getInt16(mem_addr + 3) } as ClosureOp + case PointerTag.EnvOp: + return { + type: CommandType.EnvOp, + envId: this.memory.getInt16(mem_addr + 1) + } as EnvOp } } @@ -177,6 +193,17 @@ export class Heap { return ptr_heap_addr } + /* Memory Layout of an EnvOp: [0:tag, 1-2:envId, 3-4:_unused_, 5-6:size, 7:_unused_] (1 word) */ + private allocateEnvOp({ envId }: EnvOp): HeapAddress { + const ptr_heap_addr = this.allocateTaggedPtr(PointerTag.EnvOp) + + const ptr_mem_addr = ptr_heap_addr * WORD_SIZE + // NOTE: assume there will be no more than 2^16 envs + this.memory.setInt16(ptr_mem_addr + 1, envId) + + return ptr_heap_addr + } + /** * Allocate a tagged pointer in the heap * diff --git a/src/go-slang/lib/heap/tags.ts b/src/go-slang/lib/heap/tags.ts index dbdecf902..a0c745aac 100644 --- a/src/go-slang/lib/heap/tags.ts +++ b/src/go-slang/lib/heap/tags.ts @@ -5,5 +5,6 @@ export enum PointerTag { AstNode, CallOp, BuiltInOp, - ClosureOp + ClosureOp, + EnvOp }