MCPcopy Create free account
hub / github.com/ceifa/wasmoon / UserdataTypeExtension

Class UserdataTypeExtension

src/type-extensions/userdata.ts:15–67  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

13}
14
15class UserdataTypeExtension extends TypeExtension<any, UserdataDecorationOptions> {
16 private readonly gcPointer: number
17
18 public constructor(thread: Global) {
19 super(thread, 'js_userdata')
20
21 this.gcPointer = thread.lua.module.addFunction((functionStateAddress: LuaState) => {
22 // Throws a lua error which does a jump if it does not match.
23 const userDataPointer = thread.lua.luaL_checkudata(functionStateAddress, 1, this.name)
24 const referencePointer = thread.lua.module.getValue(userDataPointer, '*')
25 thread.lua.unref(referencePointer)
26
27 return LuaReturn.Ok
28 }, 'ii')
29
30 if (thread.lua.luaL_newmetatable(thread.address, this.name)) {
31 const metatableIndex = thread.lua.lua_gettop(thread.address)
32
33 // Mark it as uneditable
34 thread.lua.lua_pushstring(thread.address, 'protected metatable')
35 thread.lua.lua_setfield(thread.address, metatableIndex, '__metatable')
36
37 // Add the gc function
38 thread.lua.lua_pushcclosure(thread.address, this.gcPointer, 0)
39 thread.lua.lua_setfield(thread.address, metatableIndex, '__gc')
40 }
41
42 // Pop the metatable from the stack.
43 thread.lua.lua_pop(thread.address, 1)
44 }
45
46 public isType(_thread: Thread, _index: number, type: LuaType, name?: string): boolean {
47 return type === LuaType.Userdata && name === this.name
48 }
49
50 public getValue(thread: Thread, index: number): any {
51 const refUserdata = thread.lua.lua_touserdata(thread.address, index)
52 const referencePointer = thread.lua.module.getValue(refUserdata, '*')
53 return thread.lua.getRef(referencePointer)
54 }
55
56 public pushValue(thread: Thread, decoratedValue: Decoration<any, UserdataDecorationOptions>): boolean {
57 if (!decoratedValue.options.reference) {
58 return false
59 }
60
61 return super.pushValue(thread, decoratedValue)
62 }
63
64 public close(): void {
65 this.thread.lua.module.removeFunction(this.gcPointer)
66 }
67}
68
69export default function createTypeExtension(thread: Global): TypeExtension<Error> {
70 return new UserdataTypeExtension(thread)

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected