Let's get started with this.
TSAGenerator is still highly incomplete with lots of TODOs. A number of pieces are copy-and-pasted from other visitors (implementation visitor or declaration visitor) and I left quite some stuff behind #if 0 for now, because that way it is easier for me to see what's still missing in those cases and since the entire thing is a 1-person experimental project right now, I don't see any issues with leaving a bit of a mess that is to be completed and cleaned up in follow-up work.
v8_enable_experimental_tq_to_tsa = trueTODO: Revert before landing.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
Let's get started with this.
TSAGenerator is still highly incomplete with lots of TODOs. A number of pieces are copy-and-pasted from other visitors (implementation visitor or declaration visitor) and I left quite some stuff behind #if 0 for now, because that way it is easier for me to see what's still missing in those cases and since the entire thing is a 1-person experimental project right now, I don't see any issues with leaving a bit of a mess that is to be completed and cleaned up in follow-up work.
A right, and what is complete for now is the `ToString` builtin
```
TS_BUILTIN(ToString, StringBuiltinsAssemblerTS) {
auto context = Parameter<Context>(Descriptor::kContext);
auto o = Parameter<JSAny>(Descriptor::kO);
Return(ToStringImpl(context, o));
}
```
and the required `ToStringImpl` macro, which looks like that:
```
template <typename Next>
class TorqueGeneratedStringBuiltinsReducer : public Next {
public:
BUILTIN_REDUCER(TorqueGeneratedStringBuiltins)
V<String> ToStringImpl(V<Context> context, V<JSAny> o) {
Label<String> _return(this);ScopedVar<JSAny> result(this, o);
WHILE(true) {
TYPESWITCH(result) {
CASE_(V<Number>, num): {
GOTO(_return, __ NumberToString(num));
}
CASE_(V<String>, str): {
GOTO(_return, str);
}
CASE_(V<Oddball>, oddball): {
GOTO(_return, __ LoadField(oddball, FIELD(Oddball, to_string_)));
}
CASE_(V<JSReceiver>, receiver): {
result = __ NonPrimitiveToPrimitive_String_Inline(context, receiver);
CONTINUE;
}
CASE_(V<Symbol>, _): {
__ ThrowTypeError(context, MessageTemplate::kSymbolToString);
}
CASE_(V<JSAny>, _): {
GOTO(_return, __ template CallRuntime<runtime::ToString>(context, {{}, result}));
}
}
}
__ Unreachable();
BIND(_return, return_value);
return return_value;
}
};
```
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Code-Review | +1 |
So why do you need this? Looks like this usually happens in the Torque Parser, but for TSA you desugar later? Why not use the TYPESWITCH of TSA? (maybe add a comment explaining when/why you need to desugar typeswitches)
// const x2 : T2 = cast<T2>(%assume_impossible<T1>(_value));nit: you're missing an `otherwise _NextCase` at the end of this line
if (cases[i].name) name = *cases[i].name;Seems superfluous
// TODO(nicohartmann): Handle simple cases where this can be avoided.What do you mean "cases where this can be avoided"?
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
So why do you need this? Looks like this usually happens in the Torque Parser, but for TSA you desugar later? Why not use the TYPESWITCH of TSA? (maybe add a comment explaining when/why you need to desugar typeswitches)
There used to not exist an ast node representing a `typeswitch` in Torque, but the parser immediately desugared this into a chain of `try { ... = Cast<Type>(value) otherwise Next; }` and it's very hard to turn this back into a nice TSA `TYPESWITCH` from that, so in order to map the torque code as close as possible to TSA, I introduced a new ast node for typeswitches which can then be consumed by the TSAGenerator and will only be lowered later (for the CSA generation to preserve the original behavior).
Side note: Initially, the idea was to have this order of events:
`Parser -> TSAGeneration -> Desugaring -> CSAGeneration` and hence there was a dedicated phase for desugaring high-level nodes (currently only typeswitch). However, in the meantime I had to give up on that strategy because part of the CSA stuff needs to run before TSAGeneration, which doesn't work like that in a single pipeline anymore. In the new setup, Torque is invoked twice (once for CSA and once for TSA), so it would now be enough to desugar/or not in the parser depending on the run, because the TSA run ends after TSAGeneration and doesn't need to lower the graph for anything else anymore.
If this strategy works for the rest of the TSA backend, I will eventually put this back into the parser potentially (and the AstVisitor will also be obsolete then), but I will keep it for a little while in case I run into other issues where delayed desugaring helps.
// const x2 : T2 = cast<T2>(%assume_impossible<T1>(_value));nit: you're missing an `otherwise _NextCase` at the end of this line
Done
if (cases[i].name) name = *cases[i].name;Nico HartmannSeems superfluous
Done
// TODO(nicohartmann): Handle simple cases where this can be avoided.What do you mean "cases where this can be avoided"?
```
macro MyFavouriteConstant(): int32 { return 42; }
```
would currently generate something like
```
Label<Word32> _return(this);
GOTO(_return, 42);
BIND(_return, return_value);
return return_value;
```
and it would be nice to just emit
```
return __ Word32Constant(42);
```
for that instead. (So that's macros with a single return at the very end basically).
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |