Skip to content

Inefficient bytecode for constructor-less ES6 child classes #752

@bnoordhuis

Description

@bnoordhuis

Refs: #750

Ex.

class Foo extends Bar { /* no construct() */ }

Emits:

        /* super */
        emit_op(s, OP_scope_get_var);
        emit_atom(s, JS_ATOM_this_active_func);
        emit_u16(s, 0);

        emit_op(s, OP_get_super);

        emit_op(s, OP_scope_get_var);
        emit_atom(s, JS_ATOM_new_target);
        emit_u16(s, 0);

        emit_op(s, OP_array_from);
        emit_u16(s, 0);
        emit_op(s, OP_push_i32);
        emit_u32(s, 0);

        /* arguments */
        emit_op(s, OP_scope_get_var);
        emit_atom(s, JS_ATOM_arguments);
        emit_u16(s, 0);

        emit_op(s, OP_append);
        /* drop the index */
        emit_op(s, OP_drop);

        emit_op(s, OP_apply);
        emit_u16(s, 1);
        /* set the 'this' value */
        emit_op(s, OP_dup);
        emit_op(s, OP_scope_put_var_init);
        emit_atom(s, JS_ATOM_this);
        emit_u16(s, 0);
        emit_class_field_init(s);

https://github.com/quickjs-ng/quickjs/blob/4b9d0ebdba3ace6b7f6de21c3e3806ab4055bd7e/quickjs.c#L21898-L21938

Pretty bulky and inefficient (splatting arguments, doing js_function_apply, etc.) Probably better handled through a dedicated opcode.

Affects WBT benchmarks like babylon that create tons of such objects.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions