Extraordinary project. I had several questions which I believe I have answered for myself (pizlonator please correct if wrong):
1. How do we prevent loading a bogus lower through misaligned store or load?
Answer: Misaligned pointer load/stores are trapped; this is simply not allowed.
2. How are pointer stores through a pointer implemented (e.g. `*(char **)p = s`) - does the runtime have to check if *p is "flight" or "heap" to know where to store the lower?
Answer: no. Flight (i.e. local) pointers whose address is taken are not literally implemented as two adjacent words; rather the call frame is allocated with the same object layout as a heap object. The flight pointer is its "intval" and its paired "lower" is at the same offset in the "aux" allocation (presumably also allocated as part of the frame?).
3. How are use-after-return errors prevented? Say I store a local pointer in a global variable and then return. Later, I call a new function which overwrites the original frame - can't I get a bogus `lower` this way?
Answer: no. Call frames are allocated by the GC, not the usual C stack. The global reference will keep the call frame alive.
That leads to the following program, which definitely should not work, and yet does. ~Amazing~ Unbelievable:
#include <stdio.h>
char *bottles[100];
__attribute__((noinline))
void beer(int count) {
char buf[64];
sprintf(buf, "%d bottles of beer on the wall", count);
bottles[count] = buf;
}
int main(void) {
for (int i=0; i < 100; i++) beer(i);
for (int i=99; i >= 0; i--) puts(bottles[i]);
}
Hmmm ... there's a danger here that people will test their programs compiled with Fil-C and think that they are safe to compile with a "normal" compiler. I would hope for an option to flag any undefined behavior.
What's interesting about it is that it supports SPR AVS, which is a new USB power delivery spec. I'm not aware of any other chargers that support this.
Yes, every wasm program that uses linear memory (which includes all those created by llvm toolchains) must ship with its own allocator. You only get to use the wasm GC provided allocator if your program is using the gc types, which can’t be stored in a linear memory.
Yes, but Emscripten comes with a minimal allocator that's good enough for most C code (e.g. code with low alloc/free frequency) and only adds minimal size overhead:
My favorite FP Fun Fact is that float comparisons can (almost) use integer comparisons. To determine if a > b, reinterpret a and b as signed ints and just compare those like any old ints. It (almost) works!
The implication is that the next biggest float is (almost) always what you get when you reinterpret its bits as an integer, and add one. For example, start with the zero float: all bits zero. Add one using integer arithmetic. In int-speak it's just one; in float-speak it's a tiny-mantissa denormal. But that's the next float; and `nextafter` is implemented using integer arithmetic.
Learning that floats are ordered according to integer comparisons makes it feel way more natural. But of course there's the usual asterisks: this fails with NaNs, infinities, and negative zero. We get a few nice things, but only a few.
This isn't accurate. It's true for positive numbers, and when comparing a positive to a negative, but false for comparisons between negative numbers. Standard floating point uses sign-magnitude representation, while signed integers these days use 2s-complement. On negative numbers, comparisons are reversed between these two encodings. Incrementing a float as if it were an integer will, in ordinary circumstances, get you the next one larger in magnitude, but with the same sign -- i.e., you go up for positives but down for negatives. Whereas with signed integers, you always go up except when there's an overflow into the sign bit.
A more correct version of the statement would be that comparison is the same as on sign-magnitude integers. Of course, this still has the caveats you already mentioned.
One of the unambiguously nice things about Posits (unlike floats) is that they use a 2s compliment scheme which makes it actually true for all values that they sort like integers.
yeah. having a total order just makes everything so much nicer. total order is one of the defining properties of the reals, and realistically if the user calls sort (or puts one in a B-tree), you have to put the NaNs at one side or the other (unless you're C/C++ and allow that to launch the nukes)
For what it's worth, here's the Rust std implementation [1] of the total (as in, makes NaNs comparable) comparison algorithm given by IEE 751:
let mut left = self.to_bits() as i32;
let mut right = other.to_bits() as i32;
// In case of negatives, flip all the bits except the sign
// to achieve a similar layout as two's complement integers
left ^= (((left >> 31) as u32) >> 1) as i32;
right ^= (((right >> 31) as u32) >> 1) as i32;
left.cmp(&right)
I seriously do NOT want the two plus hours back I spent diddling ( 1 bit not ) all those bits. I first learned it in binary on an HP, and then had to learn it on an IBM mainframe, and then got an 8087, and it was so incredibly fast, but error crept in for Fourier transforms. Started using extended double to keep the errors at bay. Hilbert spaces here we came.
The killer app was not Lotus 1-2-3 v2, but Turbo Pascal w/ 8087 support. It screamed through tensors and 3D spaces, places we only saw on plotters.
It was not until I got a G3 and used Graphing calculator that I could explore sombrero functions of increasing frequency.
Affine types, variance, higher-rank trait bounds, phantom data, MaybeUninit, and the whole macro and proc-macro systems are some examples of concepts that I found to be challenging when learning Rust.
Dyn-safety is another but I had encountered that previously in Swift.
Oklo | Remote (US) or Santa Clara or Brooklyn | Full time | https://oklo.com
Join us in pioneering the next generation of nuclear reactors! You'll leverage your software skills alongside nuclear engineers to model, simulate, design, and deploy advanced fission power technology. You will work at the forefront of the nuclear industry, developing novel techniques to reach new levels of safety, efficiency, and resiliency. Come be a part of powering the future with advanced fission power plants to provide clean, reliable, affordable energy.
reply