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

Default null to nil when injectObjects is not set #112

Merged
merged 1 commit into from
Apr 5, 2024

Conversation

gudzpoz
Copy link
Contributor

@gudzpoz gudzpoz commented Mar 22, 2024

The PR #101 handles null values only when injectObjects is set to true. When injectObjects is undefined or false, null values are not handled at all, somehow triggering a TypeError in PromiseTypeExtension or otherwise a The type 'object' is not supported by Lua error.

const { LuaFactory } = require('wasmoon')
const L = await factory.createEngine({ injectObjects: false })
L.global.pushValue(null) // TypeError here
Uncaught TypeError: Cannot read properties of null (reading 'then')
    at PromiseTypeExtension.pushValue (.../node_modules/.pnpm/[email protected]/node_modules/wasmoon/dist/index.js:916:102)
    at .../node_modules/.pnpm/[email protected]/node_modules/wasmoon/dist/index.js:244:82
    at Array.find (<anonymous>)
    at Global.pushValue (.../node_modules/.pnpm/[email protected]/node_modules/wasmoon/dist/index.js:244:46)

This PR adds a simple DefaultNullTypeExtension for cases when injectObjects is false.

fixes #104

Copy link
Contributor

@tims-bsquare tims-bsquare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one of those cases where I think your changes should be in thread.ts.

It looks like currently returning nil from Lua will map to JS null but pushing null doesn't correctly work which sounds like a bug there to me.

However, I'm not sure which should be the default, mapping to null or to undefined. Personally I'd say undefined because it's closer to what nil means in Lua but it is currently null on a return nil.

@ceifa I think supporting null in thread.ts:pushValue would be handy along with being sure you'd like to return null from thread.ts:getValue

src/engine.ts Outdated
@@ -31,11 +31,9 @@ export default class LuaEngine {
// Contains the :await functionality.
this.global.registerTypeExtension(1, createPromiseType(this.global, injectObjects))

if (injectObjects) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should've remained in if you were doing a type extension imo. I'd have said you should inject the default null type extension always with a lower priority and then allow this to override it

@gudzpoz
Copy link
Contributor Author

gudzpoz commented Apr 3, 2024

Thanks for the suggestion! It occurs to me that default null values can be handled in type-extensions/table.ts instead (as is done in the latest commit). Or do you prefer it to be handled in a standalone handler?

By the way, I can't think of a good way to move the changes into thread.ts. Do you mean something like this?

diff --git a/src/thread.ts b/src/thread.ts
index 12e26f4..53387e0 100755
--- a/src/thread.ts
+++ b/src/thread.ts
@@ -216,6 +216,12 @@ export default class Thread {
             case 'boolean':
                 this.lua.lua_pushboolean(this.address, target ? 1 : 0)
                 break
+            case 'object':
+                if (target === null && !((this.parent ?? this) as unknown as Global).injectObject) {
+                    this.lua.lua_pushnil(this.address)
+                    break
+                }
+            // Otherwise, fall through
             default:
                 if (!this.typeExtensions.find((wrapper) => wrapper.extension.pushValue(this, decoratedValue, userdata))) {
                     throw new Error(`The type '${typeof target}' is not supported by Lua`)

@tims-bsquare
Copy link
Contributor

Thanks for the suggestion! It occurs to me that default null values can be handled in type-extensions/table.ts instead (as is done in the latest commit). Or do you prefer it to be handled in a standalone handler?

By the way, I can't think of a good way to move the changes into thread.ts. Do you mean something like this?

diff --git a/src/thread.ts b/src/thread.ts
index 12e26f4..53387e0 100755
--- a/src/thread.ts
+++ b/src/thread.ts
@@ -216,6 +216,12 @@ export default class Thread {
             case 'boolean':
                 this.lua.lua_pushboolean(this.address, target ? 1 : 0)
                 break
+            case 'object':
+                if (target === null && !((this.parent ?? this) as unknown as Global).injectObject) {
+                    this.lua.lua_pushnil(this.address)
+                    break
+                }
+            // Otherwise, fall through
             default:
                 if (!this.typeExtensions.find((wrapper) => wrapper.extension.pushValue(this, decoratedValue, userdata))) {
                     throw new Error(`The type '${typeof target}' is not supported by Lua`)

Personally I think it should be handled in thread.ts with the other primitives, definitely not in the table extension though, it may be an object but not one with keys. The downside of that being you'd still need to allow extensions to overwrite null.

In thread.ts I think what you'd have to do is in the default case when no extensions are found then if the value is null then push nil and the same in reverse for the get.

To be clear though it may be better as a type extension separate from the current null and table types. I only suggest thread.ts because there's already some null/undefined handling in there.

Copy link
Contributor

@tims-bsquare tims-bsquare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy with this if you are @ceifa

Thanks for the iterations @gudzpoz

@ceifa
Copy link
Owner

ceifa commented Apr 5, 2024

LGTM

@ceifa ceifa merged commit 0377b49 into ceifa:main Apr 5, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unable to handle null values between js and the lua vm
3 participants