forked from defunkt/ReefVM
fromValue can convert native functions now
This commit is contained in:
parent
676f53c66b
commit
0f39e9401e
|
|
@ -1,4 +1,4 @@
|
||||||
import { wrapNative } from "./function"
|
import { wrapNative, getOriginalFunction } from "./function"
|
||||||
import { OpCode } from "./opcode"
|
import { OpCode } from "./opcode"
|
||||||
import { Scope } from "./scope"
|
import { Scope } from "./scope"
|
||||||
import { VM } from "./vm"
|
import { VM } from "./vm"
|
||||||
|
|
@ -183,7 +183,7 @@ export function fromValue(v: Value, vm?: VM): any {
|
||||||
if (!vm || !(vm instanceof VM)) throw new Error('VM is required for function conversion')
|
if (!vm || !(vm instanceof VM)) throw new Error('VM is required for function conversion')
|
||||||
return fnFromValue(v, vm)
|
return fnFromValue(v, vm)
|
||||||
case 'native':
|
case 'native':
|
||||||
return '<function>'
|
return getOriginalFunction(v.fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -113,3 +113,74 @@ test("toValue - converts wrapped Reef functions back to original Value", async (
|
||||||
expect(backToValue).toBe(reefFunction) // Same reference
|
expect(backToValue).toBe(reefFunction) // Same reference
|
||||||
expect(backToValue.type).toBe("function")
|
expect(backToValue.type).toBe("function")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("fromValue - converts native function back to original JS function", async () => {
|
||||||
|
const { VM, toBytecode, toValue, fromValue } = await import("#reef")
|
||||||
|
|
||||||
|
const bytecode = toBytecode([["HALT"]])
|
||||||
|
const vm = new VM(bytecode)
|
||||||
|
|
||||||
|
// Create a native JS function
|
||||||
|
const originalFn = (x: number, y: number) => x * y
|
||||||
|
|
||||||
|
// Convert to Value (wraps it as a native function)
|
||||||
|
const nativeValue = toValue(originalFn, vm)
|
||||||
|
expect(nativeValue.type).toBe("native")
|
||||||
|
|
||||||
|
// Convert back to JS - should get the original function
|
||||||
|
const convertedFn = fromValue(nativeValue, vm)
|
||||||
|
expect(typeof convertedFn).toBe("function")
|
||||||
|
|
||||||
|
// Verify it's the same function
|
||||||
|
expect(convertedFn).toBe(originalFn)
|
||||||
|
|
||||||
|
// Verify it works correctly
|
||||||
|
expect(convertedFn(3, 4)).toBe(12)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("fromValue - native function roundtrip preserves functionality", async () => {
|
||||||
|
const { VM, toBytecode, toValue, fromValue } = await import("#reef")
|
||||||
|
|
||||||
|
const bytecode = toBytecode([["HALT"]])
|
||||||
|
const vm = new VM(bytecode)
|
||||||
|
|
||||||
|
// Create a native function with state
|
||||||
|
let callCount = 0
|
||||||
|
const countingFn = (n: number) => {
|
||||||
|
callCount++
|
||||||
|
return n * callCount
|
||||||
|
}
|
||||||
|
|
||||||
|
// Roundtrip through Value
|
||||||
|
const nativeValue = toValue(countingFn, vm)
|
||||||
|
const roundtrippedFn = fromValue(nativeValue, vm)
|
||||||
|
|
||||||
|
// Verify it maintains state across calls
|
||||||
|
expect(roundtrippedFn(10)).toBe(10) // 10 * 1
|
||||||
|
expect(roundtrippedFn(10)).toBe(20) // 10 * 2
|
||||||
|
expect(roundtrippedFn(10)).toBe(30) // 10 * 3
|
||||||
|
expect(callCount).toBe(3)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("fromValue - async native function roundtrip", async () => {
|
||||||
|
const { VM, toBytecode, toValue, fromValue } = await import("#reef")
|
||||||
|
|
||||||
|
const bytecode = toBytecode([["HALT"]])
|
||||||
|
const vm = new VM(bytecode)
|
||||||
|
|
||||||
|
// Create an async native function
|
||||||
|
const asyncFn = async (x: number, y: number) => {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1))
|
||||||
|
return x + y
|
||||||
|
}
|
||||||
|
|
||||||
|
// Roundtrip through Value
|
||||||
|
const nativeValue = toValue(asyncFn, vm)
|
||||||
|
expect(nativeValue.type).toBe("native")
|
||||||
|
|
||||||
|
const roundtrippedFn = fromValue(nativeValue, vm)
|
||||||
|
|
||||||
|
// Verify it works
|
||||||
|
const result = await roundtrippedFn(5, 7)
|
||||||
|
expect(result).toBe(12)
|
||||||
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user