Generalized program tree
This PR is a part of effort to address #1075. Scope of this PR is limited to only introduce the new IR type. Most of the work presented in this PR is due to @jordwalke (see rehp, I only brushed it up it and prepared for upstreaming.
Thanks. Would you mind restricting this PR To just introducing an additional IR. I don't want to review too many moving pieces at once.
Yeah, sure. Will do!
вс, 13 дек. 2020 г., 21:57 hhugo [email protected]:
Thanks. Would you mind restricting this PR To just introducing an additional IR. I don't want to review too many moving pieces at once.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ocsigen/js_of_ocaml/pull/1076#issuecomment-744052218, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAZXBBBTN7B2EPGSIV5N6TSUUFBXANCNFSM4UZWP2RQ .
I've trimmed this PR down to only introducing an additional IR.
I meant, restrict the PR to a new IR and plug it in - but exclude things that change the behavior
I meant, restrict the PR to a new IR and plug it in - but exclude things that change the behavior
Gotcha, I've restored the PR to original state and tweaked it a bit to produce exactly the same output. Tweaks included using EqEq in arity test and still generating 1 - x in generate.ml.
Hey @hhugo, have you had a chance to look more at this?
I'm writing this as an outsider but is this new IR type sufficiently general?
I wouldn't expect constructs like Typeof, ERegexp, and ERaw to be present in a general IR. Similarly, I don't think JS-specific primitives/externs should be handled in generate.ml.
Is it feasible to handle the JS features in javascript_from_ir.ml instead?
ERaw is essential for interop with target language. Special primitive takes source code in target language as a string, possibly interpolates it with arguments and injects into IR, which is then processed by language backend, and target language code gets emitted during generation.
As of Typeof and friends, generate.ml has a number of primitives declared like ones below:
register_bin_prim "caml_js_instanceof" `Pure (fun cx cy _ ->
bool (J.EBin (J.InstanceOf, cx, cy)));
register_un_prim "caml_js_typeof" `Pure (fun cx _ -> J.EUn (J.Typeof, cx))
I'm not completely sure if these could be somehow moved away from generate.ml, may be we could use ERaw and make Javascript backend register these primitives as macros instead.
I'm all for making the IR as general as possible, just wanted to take baby steps in the right direction :)
Or what you suggest @mnxn is to emit some EPrim in generate.ml and offload handling of primitives other than a set of well-known ones to target language IR processor? And consequently move all JS primitive related code from generate.ml into javascript_from_ir.ml?
Or what you suggest @mnxn is to emit some
EPrimingenerate.mland offload handling of primitives other than a set of well-known ones to target language IR processor? And consequently move all JS primitive related code fromgenerate.mlintojavascript_from_ir.ml?
Exactly.
I think that the primitives that start with caml_js should be handled by the javascript_from_ir module. Then the IR can be simplified and remove many JS variants.
Exactly. I think that the primitives that start with
caml_jsshould be handled by thejavascript_from_irmodule. Then the IR can be simplified and remove many JS variants.
Sounds good to me! Question to maintainers if this belongs to this PR, or better organized as subsequent one.
I'm looking into moving JS specific primitives outside of generate.ml as this makes sense in terms of generalization of IR.
Some are quite obvious like Prim (Extern "debugger", _). Some are not, like %closure.
Ideally primitives should be handled at two levels - first one would be generate.ml handling some built-in/special primitives so as not to repeat this code in each backend generator. And second one would be in specific backend, handling primitives that make sense only for one target language.
Probably passing a primitive from one level to another can be plugged in somewhere here: https://github.com/ocsigen/js_of_ocaml/blob/65c1fc1966cbedc4587da764d7871cfb965f972e/compiler/lib/generate.ml#L1194. Instead of generating generic ECall for primitives that we do not know - we can emit some EPrim IR node which can then be processed later by the target language backend.
I have not yet fully understood what that Share thing is doing, but it does track some primitives, in tandem with %closure that gets introduced in inliner (inline.ml). Splitting primitives in two levels would make target-language-specific primitives invisible for logic in generate.ml, they won't be tracked in Share. I'm not sure if that could hurt kittens. @hhugo could you please advise on this part? And do you think it makes sense to follow this path in general?
Is there still interest in such change ? Should it be rebased or closed ?
Not from my end unfortunately. Let's close this probably.