Allocation
Allocation in Boson is going to be similar to how it is done in C. The reason for this is simplicity and control. The complexity around garbage collection and the runtime needed to support it make it undesirable. Boson is intended to be a language suitable for programming applications and operating system kernels. As such, the core language and runtime need to be kept fairly small.
Unlike C, we don’t want to pass in byte counts and receive void * back.
This lacks the type safety we want to achieve in Boson.
Instead, we want a function that will take a type name and return back a pointer of the proper type.
This can’t be a regular function, since the type it returns is variable, and it will require support from the compiler itself.
The pseudo-declaration for the function, we’ll just call it alloc
, might be:
func alloc(t Type) *T
Where Type
is the pseudo-type representing a type in Boson and *T
is a pointer to a new instance with zero value of whatever type t
represents.
Of course, since Boson does not support garbage collection, we also need a free
function which follows suit:
func free(*T)
free(x)
The usage would then be:
var x *int = alloc(int)
free(x)
Inner Workings
In C, malloc
and free
are just regular functions. They’re part of the standard library.
One consequence of this is that you can compile C programs that don’t include the standard library, and you can, instead, use your own allocator.
This is useful when writing code that will in very primitive environments, e.g. an operating system kernel.
In Boson, we want to be able to write code with a minimal runtime. It would be nice if Boson had this property.
However, since alloc
and free
require compiler support, it seems like we need to figure out a way to disable them and let users write their own variable-type functions.
This is a tall order, though. Disabling runtime features in the compiler is simpler, but having a special syntax and compiler rules just for alloc
and free
isn’t what we want.
Instead, we will do the most stupidly simple thing I can think of.
alloc
and free
will be fake functions which, when encountered by the compiler, will be replaced by code which calls raw_alloc
or raw_free
, Functions very much like malloc
and free
in C:
func raw_alloc(n isize) []byte
func raw_free(buf []byte)
Note: I’m not sure about the function signatures yet. I have yet to write the [Unsafe] section where I’ll devise methods for dealing with inherently unsafe operations.
It’s likely that rather than using a nice type like []byte
, raw_alloc
and raw_free
should use some kind of unsafe raw pointer. I’m not sure yet if that will be necessary.
These should behave very similarly to how malloc
and free
behave in C. raw_alloc
will take a number of bytes to allocate, n
, and it will return a []byte
. raw_free
will free a chunk of bytes.
Unlike C’s malloc
, if raw_alloc
cannot allocate space, it will panic
This solves our issue. If we don’t link the standard library, the linker will error if you try to call alloc
or free
.
If we define our own raw_alloc
and raw_free
, alloc
and free
will work as expected, and we still get all the type safety the original functions provided.