(thread: Thread, decoration: Decoration<FunctionType, FunctionDecoration>)
| 143 | } |
| 144 | |
| 145 | public pushValue(thread: Thread, decoration: Decoration<FunctionType, FunctionDecoration>): boolean { |
| 146 | if (typeof decoration.target !== 'function') { |
| 147 | return false |
| 148 | } |
| 149 | |
| 150 | // It's surprisingly inefficient to map JS functions to C functions so this creates a reference to the |
| 151 | // function which stays solely in JS. The cfunction called from Lua is created at the top of the class |
| 152 | // and it accesses the JS data through an upvalue. |
| 153 | |
| 154 | const pointer = thread.lua.ref(decoration) |
| 155 | // 4 = size of pointer in wasm. |
| 156 | const userDataPointer = thread.lua.lua_newuserdatauv(thread.address, PointerSize, 0) |
| 157 | thread.lua.module.setValue(userDataPointer, pointer, '*') |
| 158 | |
| 159 | if (LuaType.Nil === thread.lua.luaL_getmetatable(thread.address, this.name)) { |
| 160 | // Pop the pushed userdata. |
| 161 | thread.pop(1) |
| 162 | thread.lua.unref(pointer) |
| 163 | throw new Error(`metatable not found: ${this.name}`) |
| 164 | } |
| 165 | |
| 166 | // Set as the metatable for the function. |
| 167 | // -1 is the metatable, -2 is the userdata |
| 168 | thread.lua.lua_setmetatable(thread.address, -2) |
| 169 | |
| 170 | // Pass 1 to associate the closure with the userdata, pops the userdata. |
| 171 | thread.lua.lua_pushcclosure(thread.address, this.functionWrapper, 1) |
| 172 | |
| 173 | return true |
| 174 | } |
| 175 | |
| 176 | public getValue(thread: Thread, index: number): FunctionType { |
| 177 | // Create a copy of the function |
no test coverage detected