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

Analyzer regression #5082

Closed
ncannasse opened this issue Apr 8, 2016 · 19 comments
Closed

Analyzer regression #5082

ncannasse opened this issue Apr 8, 2016 · 19 comments
Assignees
Milestone

Comments

@ncannasse
Copy link
Member

I know there was a similar opened issue but I can't find it anymore.

In CastleDB, I am doing the following:

(untyped content.find("[name=color]")).spectrum("set", toColor(l.props.color)).closest(".item").css( { display : l.idToIndex == null && !l.data.match(Tiles(_) | TileInstances(_)) ? "" : "none" } );

This now gets compiled to:

var tmp1 = this.content.find("[name=color]").spectrum;
...
tmp1("set",tmp2).closest(".item").css({ display : tmp3});

But in JS this will get the wrong "this", creating a runtime error
If you want to keep this behavior, it is necessary to use a FClosure field access on .spectrum

@ncannasse ncannasse added this to the 3.3.0-rc1 milestone Apr 8, 2016
@Simn
Copy link
Member

Simn commented Apr 8, 2016

That would be #4787, and goddammit who writes code like that...

@Simn
Copy link
Member

Simn commented Apr 8, 2016

I can't promise a fix for the RC. My naive attempts cause failing tests for #1827 and something going wrong in TestInt64.

I would like to point out that (untyped x).field causes the entire field chain to be type-less. It creates a monomorph so all subsequent field accesses are made on an open structure. This is actually worse than doing untyped x.field which at least tries to type things properly.

@ncannasse
Copy link
Member Author

It it because of the untyped? Or can the analyzer loose this context in other scenarios?

@ncannasse
Copy link
Member Author

Does no seem to be untyped-specific, since doing the following produces the same output, while being perfectly valid:

(content.find("[name=color]") : Dynamic).spectrum("set", toColor(l.props.color)).closest(".item").css( { display : l.idToIndex == null && !l.data.match(Tiles(_) | TileInstances(_)) ? "" : "none" } );

This is a serious regression IMHO (silently fails at runtime and hard to pinpoint)

@ncannasse
Copy link
Member Author

Trying also the following, not working either:

var tmp : Dynamic = content.find("[name=color]");
tmp.spectrum("set", toColor(l.props.color)).closest(".item").css( { display : l.idToIndex == null && !l.data.match(Tiles(_) | TileInstances(_)) ? "" : "none" } );

@Simn
Copy link
Member

Simn commented Apr 15, 2016

It can happen with Dynamic and open structures when you expect to retain native semantics, which I find to be pretty crazy to begin with. In the general case the .spectrum field access has to be factored out because an argument could influence it. I've explained that in #4787.

@ncannasse
Copy link
Member Author

@Simn this is not native semantics, this is because you're not creating a TClosure when making the .spectrum field access as you should.

@Simn
Copy link
Member

Simn commented Apr 15, 2016

Wait, that's the issue? Why didn't I read thatyou say so?

@ncannasse
Copy link
Member Author

It's written in my first post :)

@Simn
Copy link
Member

Simn commented Apr 15, 2016

This might help with your actual case because we have an FAnon field access there, but it wouldn't help with Dynamic. There's no FClosure for Dynamic.

@Simn
Copy link
Member

Simn commented Apr 15, 2016

Actually it doesn't even help with your actual case. This is what the AST has because you make the .spectrum field access on an open structure:

{
        cf_name = spectrum;
        cf_doc = None;
        cf_type = TFun([:TInst(String, []), :TMono (Some (TInst(String, [])))], TMono (Some (TAnon)));
        cf_public = true;
        cf_meta = [];
        cf_kind = (default,null);
        cf_params = [];
        cf_expr = None;
    }

Note the cf_kind, it's not a method but a variable. We cannot create a FClosure on that because we cannot distinguish it from real function-field-variables.

@Simn Simn modified the milestones: 3.3.0, 3.3.0-rc1 May 23, 2016
@Simn
Copy link
Member

Simn commented May 23, 2016

There's nothing I can do here for the RC. I'll have to discuss this with Nicolas afterwards.

@Simn
Copy link
Member

Simn commented Jun 16, 2016

Note that I still don't know what to do with this. If you have any smart idea please let me know.

@ncannasse
Copy link
Member Author

I don't see much of a solution here expect preventing the analyzer to create tmp vars which are TFun fields accesses, Because even if they were closures, this might lead to allocating some memory and we don't want that.

@ncannasse
Copy link
Member Author

Clarifying: we can create a TFun tmp if it comes from a class var, but not from a class method, and not from an anon either.

@Simn
Copy link
Member

Simn commented Jun 16, 2016

Yes but the problem is that due to your untyped we don't know if it's a var or a method. The cf_kind is going to be Var by default.

@ncannasse
Copy link
Member Author

Yes, you have to look at the object as well, if it's a TInst then you are allowed to create a tmp Var, if not then you should not do it.

@Simn
Copy link
Member

Simn commented Jun 16, 2016

That still doesn't sound quite right to me, but I'll take a look.

@Simn
Copy link
Member

Simn commented Jul 18, 2016

I have applied the fix as you suggested. I still don't think it's foolproof like that, but it probably requires some maliciousness to cause problems with it.

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

No branches or pull requests

2 participants