Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: generic heap object comparison #34

Merged
merged 3 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/go-slang/goroutine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,16 +304,16 @@ const Interpreter: {

CallExpression: ({ callee, args }: CallExpression, { C, E, S, H, A }) => {
if (callee.type !== NodeType.QualifiedIdentifier) {
C.pushR(
return C.pushR(
...H.allocM([
callee,
...args,
{ type: CommandType.CallOp, calleeNodeId: A.track(callee).uid, arity: args.length }
])
)
return
}

const qualifiedIdStr = callee.pkg.name + '.' + callee.method.name
const className = H.resolve(E.lookup(callee.pkg.name))
if (className === null) {
return Result.fail(new UndefinedError(callee.pkg.name, callee.loc!))
Expand All @@ -328,7 +328,7 @@ const Interpreter: {

const action = methodActions[callee.method.name]?.()
if (!action) {
return Result.fail(new UndefinedError(callee.method.name, callee.method.loc!))
return Result.fail(new UndefinedError(qualifiedIdStr, callee.method.loc!))
}

const waitGroupHeapAddress = E.lookup(callee.pkg.name)
Expand All @@ -344,7 +344,7 @@ const Interpreter: {

const action = methodActions[callee.method.name]?.()
if (!action) {
return Result.fail(new UndefinedError(callee.method.name, callee.method.loc!))
return Result.fail(new UndefinedError(qualifiedIdStr, callee.method.loc!))
}

const mutexHeapAddress = E.lookup(callee.pkg.name)
Expand All @@ -353,7 +353,7 @@ const Interpreter: {
}

// Should be unreachable
return Result.fail(new UndefinedError(callee.method.name, callee.method.loc!))
return Result.fail(new UndefinedError(qualifiedIdStr, callee.method.loc!))
},

ExpressionStatement: ({ expression }: ExpressionStatement, { C, H }) =>
Expand Down
13 changes: 5 additions & 8 deletions src/go-slang/lib/channel.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { WORD_SIZE } from './heap/config'
import { HeapObject } from './heap/types'

/* prettier-ignore */
export class Channel {
protected memory: DataView

constructor(memory: DataView) { this.memory = memory }
export class Channel extends HeapObject{
constructor(memory: DataView) { super(memory) }

protected get maxBufSize(): number { return this.memory.getUint16(5) }

Expand All @@ -13,8 +12,6 @@ export class Channel {
protected getSlotValue(slotIdx: number): number { return this.memory.getFloat64(this.getSlotAddr(slotIdx)) }

protected setSlotValue(slotIdx: number, value: number): void { this.memory.setFloat64(this.getSlotAddr(slotIdx), value) }

public addr(): number { return this.memory.byteOffset }
}

export class UnbufferedChannel extends Channel {
Expand Down Expand Up @@ -108,7 +105,7 @@ export class UnbufferedChannel extends Channel {
}

public toString(): string {
return `UnbufferedChan(addr=0x${this.addr().toString(16)})`
return `UnbufferedChan(addr=0x${this.addr.toString(16)})`
}

private hasSender(): boolean { return this.sendId !== UnbufferedChannel.NULL_ID } // prettier-ignore
Expand Down Expand Up @@ -174,7 +171,7 @@ export class BufferedChannel extends Channel {
}

public toString(): string {
return `BufferedChan(addr=0x${this.addr().toString(16)})`
return `BufferedChan(addr=0x${this.addr.toString(16)})`
}

public isBufferFull(): boolean {
Expand Down
16 changes: 16 additions & 0 deletions src/go-slang/lib/heap/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export class HeapObject {
protected memory: DataView

constructor(memory: DataView) {
this.memory = memory
}

protected get addr(): number {
return this.memory.byteOffset
}

public isEqual(other: HeapObject): boolean {
// it is only equal if it is the same object in memory
return this.addr === other.addr
}
}
7 changes: 4 additions & 3 deletions src/go-slang/lib/mutex.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
export class Mutex {
protected memory: DataView
import { HeapObject } from './heap/types'

export class Mutex extends HeapObject {
protected LOCKED_OFFSET = 7

toString(): string {
return `Mutex { isLocked: ${this.getisLocked()} }`
}

constructor(memory: DataView) {
this.memory = memory
super(memory)
}

protected getisLocked(): boolean {
Expand Down
13 changes: 7 additions & 6 deletions src/go-slang/lib/operators.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { RuntimeSourceError } from '../../errors/runtimeSourceError'
import { InvalidOperationError } from '../error'
import { BinaryOperator, UnaryOperator } from '../types'
import { Channel } from './channel'
import { HeapObject } from './heap/types'
import { Result } from './utils'

function _typeof(value: any): string {
if (value instanceof Channel) {
return 'chan'
if (value instanceof HeapObject) {
return 'heapObj'
}

const typeName = typeof value
Expand Down Expand Up @@ -134,16 +134,17 @@ function evaluateRelationalOp(
)
}

if (_typeof(left) === 'chan') {
if (_typeof(left) === 'heapObj') {
if (operator !== '==' && operator !== '!=') {
return Result.fail(
new InvalidOperationError(
`${left} ${operator} ${right} (operator ${operator} not defined on chan)`
)
)
}
left = (left as Channel).addr()
right = (right as Channel).addr()
// compare the memory address of the two heap objects
left = left.addr
right = right.addr
}

let result = undefined
Expand Down
7 changes: 4 additions & 3 deletions src/go-slang/lib/waitgroup.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
export class WaitGroup {
protected memory: DataView
import { HeapObject } from './heap/types'

export class WaitGroup extends HeapObject {
protected COUNT_OFFSET = 1

toString(): string {
return `WaitGroup { count: ${this.getCount()} }`
}

constructor(memory: DataView) {
this.memory = memory
super(memory)
}

protected getCount(): number {
Expand Down
Loading