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

Class NullTypeExtension

src/type-extensions/null.ts:7–74  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

5import { LuaReturn, LuaState } from '../types'
6
7class NullTypeExtension extends TypeExtension<unknown> {
8 private gcPointer: number
9
10 public constructor(thread: Global) {
11 super(thread, 'js_null')
12
13 this.gcPointer = thread.lua.module.addFunction((functionStateAddress: LuaState) => {
14 // Throws a lua error which does a jump if it does not match.
15 const userDataPointer = thread.lua.luaL_checkudata(functionStateAddress, 1, this.name)
16 const referencePointer = thread.lua.module.getValue(userDataPointer, '*')
17 thread.lua.unref(referencePointer)
18
19 return LuaReturn.Ok
20 }, 'ii')
21
22 if (thread.lua.luaL_newmetatable(thread.address, this.name)) {
23 const metatableIndex = thread.lua.lua_gettop(thread.address)
24
25 // Mark it as uneditable
26 thread.lua.lua_pushstring(thread.address, 'protected metatable')
27 thread.lua.lua_setfield(thread.address, metatableIndex, '__metatable')
28
29 // Add the gc function
30 thread.lua.lua_pushcclosure(thread.address, this.gcPointer, 0)
31 thread.lua.lua_setfield(thread.address, metatableIndex, '__gc')
32
33 // Add an __index method that returns nothing.
34 thread.pushValue(() => null)
35 thread.lua.lua_setfield(thread.address, metatableIndex, '__index')
36
37 thread.pushValue(() => 'null')
38 thread.lua.lua_setfield(thread.address, metatableIndex, '__tostring')
39
40 thread.pushValue((self: unknown, other: unknown) => self === other)
41 thread.lua.lua_setfield(thread.address, metatableIndex, '__eq')
42 }
43 // Pop the metatable from the stack.
44 thread.lua.lua_pop(thread.address, 1)
45
46 // Create a new table, this is unique and will be the "null" value by attaching the
47 // metatable created above. The first argument is the target, the second options.
48 super.pushValue(thread, new Decoration<unknown>({}, {}))
49 // Put it into the global field named null.
50 thread.lua.lua_setglobal(thread.address, 'null')
51 }
52
53 public getValue(thread: Thread, index: number): null {
54 const refUserData = thread.lua.luaL_testudata(thread.address, index, this.name)
55 if (!refUserData) {
56 throw new Error(`data does not have the expected metatable: ${this.name}`)
57 }
58 return null
59 }
60
61 // any because LuaDecoration is not exported from the Lua lib.
62 public pushValue(thread: Thread, decoration: any): boolean {
63 if (decoration?.target !== null) {
64 return false

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected