It turns out my test was backwards: it fed the json text into a string
object then pulled it out, which of course round-tripped correctly. Now
things do round-trip correctly, but I had to ignore white-space
differences and edit the numbers as text->double->text doesn't
necessarily round-trip well (though double->text->double does with 17
digits).
I don't know why the last argument was handled differently. I suspect it
was a hold-over from before I added list handling. Removing it seems to
have made no significant difference (all tests pass still).
They're not actually used yet because all the calculations are giving me
a headache, but the improved handling of text direction in
Text_PassageView, along with passing the information, is important
enough, I think.
When the parameter is a reference, implicit casting is not allowed, but
when the parameter is by value and the argument is a reference, the
argument is dereferenced and promotion is allowed.
However, this covers only the selection of generic functions. It doesn't
deal with otherwise overloaded functions, nor does it do the actual
dereferencing or address taking.
Before adding references, looking at just type.type was ok whether or
not the type was an alias, but checking the deref flag needs the type to
be basic and not alias.
Simple functions now get to the code-gen phase (where they fail since
it's the wrong for other reasons). Parameter types aren't right for
spir-v yet as non-const params need to be references.
I realized that spir-v pointers are essentially references (the way
they're used) since OpVariable requires a pointer type rather than the
base type. Thus, under the hood, references are just pointers with
automatic dereferencing. However, nothing uses references yet, and I
expect to run into issues with is_pointer vs is_reference vs is_ptr
(high-level pointer, reference, low-level pointer, respectively).
Since begin_function creates the parameter and locals scopes, there's no
need for another scope for the function body. This fixes the detection
of shadowed parameters for Ruamoko and QuakeC.
It's currently passing for Ruamoko, but glsl doesn't catch shadowed
params. There's a bit of a conflict and I want to make sure I don't lose
the checking.
I'd gotten tired of all the convoluted progs version checks, and with
the addition of spirv, they're not even always relevant, and adding C
(when I get to it) will make things even worse. However, for now the
first victim is just the parameter/return value size check.
BSP textures have pre-generated mips, including the transparent
textures, but mips don't play nicely with the transparency color (255):
it gets blended to other colors (at least in ad tears). Regenerating the
mips from the rgba texture (using transparent black) produces nice
results.
Also, needed to discard on 0 alpha to avoid weird interactions with fog
(I didn't know ad tears had fog: I guess I had last loaded it before
implementing fog).
Now declarations can be deferred too, thus things like generic/template
and inline functions should be possible. However, the most important
thing is this is a step towards a cleaner middle layer for compilation,
separating front-end language from back-end code-gen.
I don't remember why I thought it was a good idea at the time, but I
decided that having the union was a bit iffy and making the list
"official" would be a good idea. In the end, it removed a nice chunk of
code (redundant list manipulations).
And they even pass validation (though it turns out there's a bug in
glslangValidator regarding specialization constants with expressions (or
possibly spirv-val, but it seems to be the former as my bug report shows
signs of activity in that direction)).
https://github.com/KhronosGroup/glslang/issues/3748
I want to use new_field_expr for specialized field expressions instead.
However, I don't particularly like new_deffield_expr as a name, but I
can't think of anything better just yet.
So far, this affects only glsl (because only glsl marks expressions as
constexpr), but it does get specialization constant initializers for
global variables working.
Now, ctor expressions are collected and emitted after all other code,
and the ctor function being created outside of class_finish_module means
it's no longer limited to just class related initialization.
I plan to do this eventually for Ruamoko, but I need it to keep working
for now; it's rather nice having multiple languages. I expect this will
open up a lot of options for inlining, generic/template function
instantiation, etc. Right now, it's helping with specialization
constants in glsl.
Including anti-commutativity. I hadn't set them before because I was
uncertain and got conflicting answers, but when I took a look again, it
seems IEEE 754 does guarantee commutativity for multiplication and
addition, so long as NaN isn't involved (and then it seems to be because
`a==a` is always false when a is a NaN).
Both for geometric algebra and in general (since it's just in
unary_expr). However, it doesn't quite work for float stuff (eg,
`vector × vector`, but that's only because the anti-commutative flag
isn't set.
Instead of forcing it via unnecessary alignment. I didn't feel like
using aligned malloc to silence ubsan when really the alignment was just
to force the size to be aligned.
One is potentially legit (depends on what really happens when allocating
0-length arrays on the stack), but the offset null pointer ones are
dubious as `a` should never be null when `size` is non-zero, and when
`size` is zero, everything gets corrected.
Maybe there's a different trick to making gcc see that the dimension was
already check, but this works nicely size if the two calculations
differ, there are bigger problems.
Switching to native ruamoko bool for vkgen resulted in bool getting
incorrectly parsed as a string (which mean getting the string's address
written to the value). Fixes the randomly enabled debug pipelines (and
probably a few randomly disabled normal pipelines, though less likely as
they're usually implicitly initialized). The one bit of actual legit UB
(ie, that which wasn't immediately mitigated one way or another) found
by ubsan, and it was a data error.
Fixes ubsan's (random!) complaints about memblock not being aligned. I
should probably look into making the progs loader code ensure the memory
is aligned itself.
While I guess ubsan is right that shifting a 1 bit into the sign of an
int can cause problems, but that's assuming the int is numeric. And it
doesn't help that unsigned char promotes to int instead of unsigned int.
Recent vulkan validation layers started complaining about vertex
processing stages having read-write buffers without atomics enabled
(fair enough), but I decided to get all the buffers that don't need to
be written.
They're currently wrong since they're meant to be for specialization
constants (and that whole system is currently broken anyway) but are
instead raw code expressions, but progress is progress.
Result type and constant handling is now table-driven, resulting in the
removal of seven switch statements (and thus a lot less hassle when
extending types or expressions). Also, (u)long and (u)short are fully
implemented.
In addition, other than result type handing for boolean results, any
back-end specific implementation is now in the back-end.
It's nowhere near complete, but unary and binary expressions that are
marked as constant will not be subject to constant folding. This is
necessary for proper support of specialization constants.