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

flx_args is overwritten while parsing #23

Open
Winand opened this issue May 7, 2018 · 4 comments
Open

flx_args is overwritten while parsing #23

Winand opened this issue May 7, 2018 · 4 comments
Labels
bug Something isn't working

Comments

@Winand
Copy link
Contributor

Winand commented May 7, 2018

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 */
@Winand Winand changed the title flx_args variable is overwritten while parsing flx_args is overwritten while parsing May 7, 2018
@almarklein almarklein added the bug Something isn't working label May 14, 2018
@almarklein
Copy link
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 :)

@Winand
Copy link
Contributor Author

Winand commented Oct 5, 2018

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

@almarklein
Copy link
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
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants