stedolan / malfunction

Malfunctional Programming
Other
336 stars 19 forks source link

Unchecked vector access #24

Open ziman opened 4 years ago

ziman commented 4 years ago

Here's a program reading out of bounds:

$ echo '(module (_ (load.byte "" 1)) (export))' > example.mlf
$ malfunction compile example.mlf -o example

The program compiles fine. Then I run it.

$ ./example
Fatal error: exception Invalid_argument("index out of bounds")

It seems that the read is checked but I would expect to get a segfault or (most likely) nothing printed at all because that's what Malfunction does whenever you make any other mistake. I have not benchmarked how much overhead it incurs but not having unchecked array access feels wrong, especially in such an inherently unsafe environment.

Given that we don't want to add %primitives, I can see two options:

  1. Making Mvecget and Mvecset translate to the unchecked primitives instead. This will make them faster, and give you undefined behaviour if you get it wrong, which is consistent with the behaviour of Malfunction everywhere else.

  2. Creating new unchecked builtins. Then for debugging purposes, a compiler targetting Malfunction could switch to checked builtins to get a bit of runtime checking for free.

I'm happy to implement either. Are there better ways to do this?

stedolan commented 3 years ago

Missed this completely at the time, apologies! I'd probably go for option (2) here, even though as you say (1) is a bit more consistent. (Malfunction is mainly intended as a backend for safe statically-typed language compilers. Such compilers usually establish safety of field access / function arguments / etc. statically, but leave bounds checking until runtime, so the convenient thing is to have no runtime type checking but runtime bounds checking. It would also be good to have unchecked operations, though).