blob: 5630683f8329d55331ed72893f84022239749687 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
SLUL can in theory do safe FFI, "as long as the other side does it the
same way".
Type constraints:
All types
Must be initialized.
Alignment padding must be bitwise 0 (is this realistic to enforce?
maybe there should be a `calloc_as_uninitialized`)
(short)
int
long
Must be non-negative, unless marked with `signed` qualifier.
If there's a range constraint, then it must be in range.
Obj
References are non-nullable by default.
References must point to valid data (i.e. ).
All fields must be initialized.
Anything that is referenced must be valid.
No other reference to the object may be `var` unless ALL references
are `shared`.
non-shared non-var Obj
Must not be modified at all
non-shared Obj
Must not be modified by anyone else.
!Obj
Modifiable objects must have at most one reference to them.
non-closed enum
Enum must have one of the enum values in any version (i.e. the enum
could originate from a future version).
closed enum
Enum must have one of the enum values.
No more values may be added in future versions.
string
Is immutable.
Language specific stuff
-----------------------
C can support all of this, but C as always does not restrict itself to
safe operations, so UB is possible.
Rust currently still lacks a safe ABI as far as I know, so it can still have
UB. But there are (at least) three fundamental differences in SLUL vs Rust:
* The `shared` type qualifier doesn't have any equivalent in Rust.
* In SLUL, the last reference to an object can be removed without any
subsequent action. It will leak for a time and eventually get cleaned up
by either GC (if in use) or the later by the arena alloactor.
* Neither non-closed nor closed enums have any equivalent in Rust.
They only map to Rust enums (without the sum type / union part) in the
following two cases:
- When the enum is not part of API (in which case it is uninteresting
for FFI anyway).
- When the enum definition cannot ever change in future versions.
(I.e. SLUL implicitly has a soundness constraint on library changes,
that cannot be expressed in Rust.)
|