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

Strange behavior of QuickJS interpreter #338

Open
LazataknesSoftware opened this issue Aug 2, 2024 · 2 comments
Open

Strange behavior of QuickJS interpreter #338

LazataknesSoftware opened this issue Aug 2, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@LazataknesSoftware
Copy link

LazataknesSoftware commented Aug 2, 2024

I am trying to run following code:

let w = /\/(?<group>\w+)(:(?<value>\w+))?/i
//scriptArgs = require("process").argv
// for Node.js 
let r = []
scriptArgs.slice(1).map(a => r.push(w.exec(a).groups))
for (let z of r) {
console.log(z)
}

Error in QuickJS:

TypeError: toPrimitive
at log (native)
at <eval> (args.js:7)

In Node.js that code work without problems, but it does not on QuickJS. I don't understand why.

Note: if I will run console.log({a:2}) in REPL, then it will work without problems!

QuickJS version 2024-01-13
Termux on Android 9.0 Go
I installed it (QuickJS) by: pkg i quickjs

@chqrlie
Copy link
Collaborator

chqrlie commented Aug 3, 2024

Here is a more telling test:

let w = /\/(?<group>\w+)(:(?<value>\w+))?/i;
let m = w.exec("/a:2");
console.log('console.log(m):');
console.log(m);
console.log('console.log(m.toString()):');
console.log(m.toString());
console.log('console.log(Object.getPrototypeOf(m) == Object.getPrototypeOf([])):');
console.log(Object.getPrototypeOf(m) == Object.getPrototypeOf([]));
console.log('console.log(Object.getPrototypeOf(m.groups)):');
console.log(Object.getPrototypeOf(m.groups));
console.log('console.log(m.groups.toString):');
console.log(m.groups.toString);
console.log('console.log(m.groups):');
console.log(m.groups);

node outputs this:

console.log(m):
[
  '/a:2',
  'a',
  ':2',
  '2',
  index: 0,
  input: '/a:2',
  groups: [Object: null prototype] { group: 'a', value: '2' }
]
console.log(m.toString()):
/a:2,a,:2,2
console.log(Object.getPrototypeOf(m) == Object.getPrototypeOf([])):
true
console.log(Object.getPrototypeOf(m.groups)):
null
console.log(m.groups.toString):
undefined
console.log(m.groups):
[Object: null prototype] { group: 'a', value: '2' }

while QuickJS outputs this:

console.log(m):
/a:2,a,:2,2
console.log(m.toString()):
/a:2,a,:2,2
console.log(Object.getPrototypeOf(m) == Object.getPrototypeOf([])):
true
console.log(Object.getPrototypeOf(m.groups)):
null
console.log(m.groups.toString):
undefined
console.log(m.groups):
TypeError: toPrimitive
    at log (native)
    at <eval> (issue-338.js:14)

The problem is in console.log. Node's implementation is more advanced than QuickJS'. m.groups is a special object with a null prototype, hence it has neither a toString nor a valueOf method, so console.log(m.groups) throws an exception when converting its argument to a primitive object.

If you type m.groups in the REPL, it will show as { group: "a", value: "2" } because REPL uses more advanced code to dump expression values.

console.log is not specified in the ECMA Standard, but is supported with some variations in all browsers and most javascript runtimes. I shall try and extend support in QuickJS to match the Firefox specification, along with the substitutions, except %c.

@chqrlie chqrlie added the enhancement New feature or request label Aug 3, 2024
@LazataknesSoftware
Copy link
Author

I.e. if Object.getPrototypeOf(object) is null, then it is cannot be processed by console.log(object) or print(object)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants