Skip to content

flx_args is overwritten while parsing #23

Open

Description

@Winand

pscript generates broken code for functions like def partial2(func, *args, **keywords):
When trying to parse *args it overwrites arguments[0]:

    func = arguments[0].flx_args[0]; /* overwrites here */
    args = arguments[0].flx_args.slice(1); /* arguments[0].flx_args == undefined */

Activity

  1. changed the title [-]`flx_args` variable is overwritten while parsing[/-] [+]`flx_args` is overwritten while parsing[/+] on May 7, 2018
  2. almarklein commented on Oct 5, 2018

    @almarklein
    Member

    I am sorry, but I am having trouble understanding the problem. I don't see how fle_args[0] is overwritten; it is only indexed, right?

    I tried to work with the example in your PR:

    from pscript import py2js, evaljs
    
    def partial2(a1, a2, *args, **kwargs):
        print(a1, a2)
        print(args)
        print(kwargs)
        print('--')
    
    def main():
        partial2(3, 4, 5, 6, foo=3, bar=4)
    
    js = py2js(partial2)
    # print(js)
    print(evaljs(js + py2js(main) + 'main(); partial2(3, 4, 5)'))

    Which produces this, which seems fine:

    3 4
    [ 5, 6 ]
    { foo: 3, bar: 4 }
    --
    3 4
    [ 5 ]
    {}
    --
    null
    

    Could you please try to adjust this code for it to cause the error on your end? That would hopefully make things more explicit :)

  3. Winand commented on Oct 5, 2018

    @Winand
    ContributorAuthor

    Ok, I created a file test.py:

    def partial2(a1, a2, *args, **kwargs):
        print(a1, a2)
        print(args)
        print(kwargs)
        print('--')
    
    def main():
        partial2(3, 4, 5, 6, foo=3, bar=4)
    
    main()
    partial2(3, 4, 5)
    

    Then I compiled it to test.js with script2js:

    /* Do not edit, autogenerated by pscript */
    
    var _pyfunc_op_error = function (etype, msg) { // nargs: 2
        var e = new Error(etype + ': ' + msg);
        e.name = etype
        return e;
    };
    var _pyfunc_op_parse_kwargs = function (arg_names, arg_values, kwargs, strict) { // nargs: 3
        for (var i=0; i<arg_values.length; i++) {
            var name = arg_names[i];
            if (kwargs[name] !== undefined) {
                arg_values[i] = kwargs[name];
                delete kwargs[name];
            }
        }
        if (strict && Object.keys(kwargs).length > 0) {
            throw _pyfunc_op_error('TypeError',
                'Function ' + strict + ' does not accept **kwargs.');
        }
        return kwargs;
    };
    var main, partial2;
    partial2 = function flx_partial2 (a1, a2) {
        var args, kwargs, stub1_args;
        kwargs = {};
        if (arguments.length == 1 && typeof arguments[0] == 'object' && Object.keys(arguments[0]).toString() == 'flx_args,flx_kwargs') {
            kwargs = _pyfunc_op_parse_kwargs([], [], arguments[0].flx_kwargs);
            stub1_args = arguments[0].flx_args;
            a1 = stub1_args[0];
            a2 = stub1_args[1];
            args = arguments[0].flx_args.slice(2);
        } else {args = Array.prototype.slice.call(arguments, 2);}
        console.log(a1 + " " + a2);
        console.log(args);
        console.log(kwargs);
        console.log("--");
        return null;
    };
    
    main = function flx_main () {
        partial2({flx_args: [3, 4, 5, 6], flx_kwargs: {foo: 3, bar: 4}});
        return null;
    };
    
    main();
    partial2(3, 4, 5);
    

    When running this script in Chrome 70 I get the following error:
    image

    How is it possible?
    I couldn't believe it but when we assign a1 = stub1_args[0]; we assign 3 to arguments[0] 😞
    image

  4. almarklein commented on Oct 5, 2018

    @almarklein
    Member

    Wow! This is madness ... but I can confirm it on both Chrome and Firefox (Windows 10). It looks like a1 is somehow bound to the same spot in memory as argumens[0], but that's not how variables are supposed to work, right? Is this some obscure result of the browser's JS optimization?

    JS is full of surprises :(

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions