Whiley / RFCs

Request for Comment (RFC) proposals for substantial changes to the Whiley language.
3 stars 2 forks source link

Support for Low Memory #98

Open DavePearce opened 3 years ago

DavePearce commented 3 years ago

(see also #97)

An interesting use case for Whiley is to run on embedded systems. In some cases, such systems do not support dynamic memory allocation and Whiley currently makes quite a lot of assumptions here. In particular, around arrays, open records and lambdas.

Some examples:

int[] xs = [0;n]

This allocates an array of arbitrary size. Normally this would be done on the heap so that, for example, it can be passed out of the function in question. However, it could also be allocated on the stack provided it did not escape the function in question.

int[] ys = xs

This copies an array of arbitrary size, again typically by allocating it into the heap. However, this depends on whether xs is live after this statement or not.

type fun_t is function(int)->(int)

function make(int x) -> fun_t:
     return &(int y -> x + y) 

This is constructing a closure which must be allocated on the heap. There is really no other way to do it.

Overview

The following provides a rough rule of thumb about where problems arise.

One option is to include an analysis to ensure the above requirements are met. We might have a modifier (e.g. static) which forces this analysis to run. All methods on a low memory embedded device might be required as static.

Valid Examples

static function head(int[] items) -> (int r)
requires |items| > 0:
   return items[0]

This is straightforward to implement in finite memory, even though it uses a variable of dynamic size.

Invalid Examples

static function f(int n) -> int:
   int[] xs = [0;n]
   return g(xs)

In principle, xs could be stack allocated. We need to infer the type int[n] for xs to make this possible.