Skip to content

Conversation

@nabetti1720
Copy link
Contributor

Description of changes

The console implementation has been tweaked to be more web standards compliant.

Checklist

  • Created unit tests in tests/unit and/or in Rust for my feature if needed
  • Ran make fix to format JS and apply Clippy auto fixes
  • Made sure my code didn't add any additional warnings: make check
  • Added relevant type info in types/ directory
  • Updated documentation if needed (API.md/README.md/Other)

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@nabetti1720 nabetti1720 changed the title feat(console): Improve console interface compatibility feat(console): Improve console namespace compatibility Nov 30, 2025
@nabetti1720 nabetti1720 marked this pull request as draft November 30, 2025 12:00
@nabetti1720 nabetti1720 marked this pull request as ready for review November 30, 2025 12:05
Copy link
Collaborator

@richarddavison richarddavison left a comment

Choose a reason for hiding this comment

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

Minor change. Thanks for this once!

let console = Object::new(ctx.clone())?;
// NOTE: Console must be created from an empty object with no prototype.
// https://console.spec.whatwg.org/#console-namespace
let console = ctx.eval::<Object, &str>("Object.create({})")?;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This could be done in qjs directly.
qjs::JS_NewObjectProto add a comment that this should exist as a high level API in rquickjs as well:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried the following implementation, but WPT started failing again. Am I using it wrong?

// let console = ctx.eval::<Object, &str>("Object.create({})")?;

    let console = unsafe {
        let proto = "{}".into_js(&ctx)?.as_raw();
        let js_value = qjs::JS_NewObjectProto(ctx.as_raw().as_ptr(), proto);
        Value::from_raw(ctx.clone(), js_value)
            .into_object()
            .or_throw(&ctx)?
    };
console > should pass console-is-a-namespace.any.js tests
Error: [The prototype chain must be correct] not an object

console > should pass console-namespace-object-class-string.any.js tests
Error: [@@toStringTag exists on the namespace object with the appropriate descriptor] not a function

Copy link
Collaborator

Choose a reason for hiding this comment

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

Here is the problem @nabetti1720

 let proto = "{}".into_js(&ctx)?.as_raw();

This is a string "{}" It should be

 let photo = Object::new(ctx.clone())?;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@richarddavison I tried to fix it as advised, but now I get a new segmentation fault.

let proto = Object::new(ctx.clone())?.as_raw(); // need Object -> JSValue
cargo run -- test -d bundle/js/__tests__/wpt 2> wpt_errors.tmp
/bin/sh: line 1: 48807 Segmentation fault: 11  cargo run -- test -d bundle/js/__tests__/wpt 2> wpt_errors.tmp

The same issue occurs when you run the following command on the built binary instead of WPT.

% llrt -e "console.log('foo');"
zsh: segmentation fault  llrt -e "console.log('foo');"

% llrt -v
zsh: segmentation fault  llrt -v

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is a memory issue. When we drop the proto variable it also free's the raw values pointer. So a fix would be to do:

let proto = Object::new(ctx.clone())?
let raw = proto.as_raw();
mem::forget(proto);

And then use raw

Copy link
Contributor Author

Choose a reason for hiding this comment

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

    let console = unsafe {
        let proto = Object::new(ctx.clone())?;
        let raw = proto.as_raw();
        std::mem::forget(proto);
        let js_value = qjs::JS_NewObjectProto(ctx.as_raw().as_ptr(), raw);
        Value::from_raw(ctx.clone(), js_value)
            .into_object()
            .or_throw(&ctx)?
    };

I tried implementing it like this. WPT is now working again, but the following error occurs when the process ends.

Assertion failed: (list_empty(&rt->gc_obj_list)), function JS_FreeRuntime, file quickjs.c, line 2205.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Happy to contribute to a higher level interface in rquickjs, can you open an issue for me @nabetti1720

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Sytten I have created the following issue in the rquickjs repository, but I wonder if the intent of the problem is clear?
DelSkayn/rquickjs#572

Copy link
Collaborator

Choose a reason for hiding this comment

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

Tbh I need to brush up on prototype. I didnt even know the base object had a prototype. I think it should be easy enough to create a new method.

let console = Object::new(ctx.clone())?;
// NOTE: Console must be created from an empty object with no prototype.
// https://console.spec.whatwg.org/#console-namespace
let console = ctx.eval::<Object, &str>("Object.create({})")?;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is a memory issue. When we drop the proto variable it also free's the raw values pointer. So a fix would be to do:

let proto = Object::new(ctx.clone())?
let raw = proto.as_raw();
mem::forget(proto);

And then use raw

@richarddavison
Copy link
Collaborator

F.Y.I blocked by: DelSkayn/rquickjs#572

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants