Skip to content

Commit

Permalink
refact(rivetc.codegen): don't alloc tagged enum's struct values (#55)
Browse files Browse the repository at this point in the history
With this PR, this snippet:

```swift
enum Tagged {
    StructVariant {
       field: int;
    }
}

func main() {
    t := Tagged.StructVariant(field: 1);
}
```

Will no longer require a heap allocation.

Mutability is also forced more, not only are the fields verified to be mutable, but also the objects that have said fields.
  • Loading branch information
StunxFS authored Dec 16, 2023
1 parent 1854980 commit 542ce20
Show file tree
Hide file tree
Showing 50 changed files with 370 additions and 395 deletions.
10 changes: 5 additions & 5 deletions lib/core/src/StaticBuffer.c.ri
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import c/libc;

struct StaticBuffer {
buf: [25]mut uint8;
mut buf: [25]mut uint8;
mut len: uint;

pub func push(mut self, byte: uint8) {
Expand All @@ -16,22 +16,22 @@ struct StaticBuffer {
self.len += 1;
}

pub func as_uint64(&self) -> uint64 {
pub func as_uint64(mut self) -> uint64 {
self.buf[self.len] = 0;
return unsafe { libc.strtoul(&self.buf[0], none, 10) };
}

pub func as_uint(&self) -> uint {
pub func as_uint(mut self) -> uint {
self.buf[self.len] = 0;
return unsafe { @as(uint, libc.strtoul(&self.buf[0], none, 10)) };
}

pub func as_int(&self) -> int {
pub func as_int(mut self) -> int {
self.buf[self.len] = 0;
return unsafe { @as(int, libc.strtol(&self.buf[0], none, 10))};
}

pub func as_string(&self) -> string {
pub func as_string(mut self) -> string {
self.buf[self.len] = 0;
return unsafe { string.from_raw_with_len(&self.buf[0], self.len).clone() };
}
Expand Down
2 changes: 1 addition & 1 deletion lib/core/src/TestRunner.ri
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ struct Test {
}
struct TestRunner {
tests: []mut Test;
mut tests: []mut Test;
mut ok_tests: uint64;
mut fail_tests: uint64;
mut skip_tests: uint64;
Expand Down
2 changes: 1 addition & 1 deletion lib/core/src/backtrace.c.ri
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func bt_print_callback(

func bt_error_handler(data: rawptr, msg_ptr: ?[&]mut uint8, errnum: int32) {
unsafe {
bdata := @as(&mut BacktraceData, data);
mut bdata := @as(&mut BacktraceData, data);
if !bdata.has_error {
bdata.has_error = true;
console_ewrite(" libbacktrace error: ");
Expand Down
2 changes: 1 addition & 1 deletion lib/core/src/errors.ri
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct CallTrace {
const RETURN_TRACE_MAX_SIZE := 50;

struct ReturnTrace {
traces: [RETURN_TRACE_MAX_SIZE]mut CallTrace;
mut traces: [RETURN_TRACE_MAX_SIZE]mut CallTrace;
mut cur_idx: uint;

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion lib/core/src/rune.ri
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ extend rune < Stringable {

pub func as_bytes(self) -> []uint8 {
res := []uint8(cap: 5);
res_v := @as(DynArray, res);
mut res_v := @as(DynArray, res);
res_v.len = utf32_decode_to_buffer(self, unsafe { @as([&]mut uint8, res_v.ptr) });
return res;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/rivet/src/ast/CHeader.ri
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ extend Table {
"{} -x c -E -dM /dev/null".fmt(self.prefs.target_backend_compiler)
) {
defines_ := result.output.split_into_lines();
defines := CDefines();
mut defines := CDefines();
for define in defines_ {
mut tokens := define.tokenize(b' ');
_ = tokens.next(); // skip '#define'
Expand Down
30 changes: 15 additions & 15 deletions lib/rivet/src/ast/Decl.ri
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub enum Decl {
docs: []Comment;
attributes: Attributes;
abi: ABI;
decls: []Decl;
mut decls: []Decl;
pos: token.Pos;
},
Alias {
Expand All @@ -42,8 +42,8 @@ pub enum Decl {
attributes: Attributes;
is_public: bool;
name: string;
bases: []mut Type;
decls: []Decl;
mut bases: []mut Type;
mut decls: []Decl;
pos: token.Pos;
mut sym: Sym;
},
Expand All @@ -53,10 +53,10 @@ pub enum Decl {
is_public: bool;
name: string;
mut underlying_type: Type;
bases: []mut Type;
variants: []EnumVariantDecl;
mut bases: []mut Type;
mut variants: []mut EnumVariantDecl;
is_tagged: bool;
decls: []Decl;
mut decls: []Decl;
pos: token.Pos;
mut sym: Sym;
},
Expand All @@ -65,8 +65,8 @@ pub enum Decl {
attributes: Attributes;
is_public: bool;
name: string;
bases: []mut Type;
decls: []Decl;
mut bases: []mut Type;
mut decls: []Decl;
is_opaque: bool;
pos: token.Pos;
mut sym: Sym;
Expand All @@ -85,8 +85,8 @@ pub enum Decl {
Extend {
attributes: Attributes;
mut type: Type;
bases: []mut Type;
decls: []Decl;
mut bases: []mut Type;
mut decls: []Decl;
pos: token.Pos;
},
Const {
Expand All @@ -106,7 +106,7 @@ pub enum Decl {
is_public: bool;
is_extern: bool;
abi: ABI;
lefts: []ObjectData;
mut lefts: []mut ObjectData;
mut right: Expr;
pos: token.Pos;
mut sym: Sym;
Expand All @@ -125,10 +125,10 @@ pub enum Decl {
is_operator: bool;
abi: ABI;
name: string;
args: []Arg;
mut args: []mut Arg;
has_named_args: bool;
mut ret_type: Type;
stmts: []mut Stmt;
mut stmts: []mut Stmt;
mut scope: Scope;
has_body: bool;
self_is_mut: bool;
Expand All @@ -143,7 +143,7 @@ pub enum Decl {
docs: []Comment;
attributes: Attributes;
name: string;
stmts: []mut Stmt;
mut stmts: []mut Stmt;
scope: Scope;
pos: token.Pos;
mut defer_stmts: []Stmt.Defer;
Expand Down Expand Up @@ -187,7 +187,7 @@ pub struct EnumVariantDecl {
pub has_type: bool;
pub has_value: bool;
pub value: Expr;
pub decls: []Decl;
pub mut decls: []Decl;
pub pos: token.Pos;
}

Expand Down
27 changes: 14 additions & 13 deletions lib/rivet/src/ast/Expr.ri
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub enum Expr < traits.Stringable {
pos: token.Pos;
mut type: Type;

pub func clean_paren(self) -> Expr {
pub func clean_paren(&self) -> Expr {
mut res := self.expr;
while res is .Paren(paren) {
res = paren.expr;
Expand Down Expand Up @@ -98,7 +98,7 @@ pub enum Expr < traits.Stringable {
mut variant: EnumVariant;
},
TupleLiteral {
values: []mut Expr;
mut values: []mut Expr;
pos: token.Pos;
mut type: Type;
},
Expand All @@ -114,7 +114,7 @@ pub enum Expr < traits.Stringable {
pos: token.Pos;
},
ArrayLiteral {
values: []mut Expr;
mut values: []mut Expr;
is_dyn: bool;
pos: token.Pos;
mut type: Type;
Expand Down Expand Up @@ -170,7 +170,7 @@ pub enum Expr < traits.Stringable {
},
Call {
mut left: Expr;
mut args: []CallArg;
mut args: []mut CallArg;
mut spread_expr: Expr;
has_spread_expr: bool;
mut err_handler: CallErrorHandler;
Expand All @@ -184,7 +184,7 @@ pub enum Expr < traits.Stringable {
mut is_enum_variant: bool;
mut enum_variant_sym: TypeSym;

func has_named_args(self) -> bool {
func has_named_args(&self) -> bool {
for arg in self.args {
if arg.is_named {
return true;
Expand All @@ -193,7 +193,7 @@ pub enum Expr < traits.Stringable {
return false;
}

func get_named_arg(self, name: string) -> ?CallArg {
func get_named_arg(&self, name: string) -> ?CallArg {
for arg in self.args {
if arg.is_named && arg.name == name {
return arg;
Expand All @@ -204,7 +204,7 @@ pub enum Expr < traits.Stringable {

/// Returns the number of pure arguments, that is, not named, that
/// this call has.
func pure_args_count(self) -> uint {
func pure_args_count(&self) -> uint {
mut l: uint := 0;
for arg in self.args {
if !arg.is_named {
Expand All @@ -218,13 +218,13 @@ pub enum Expr < traits.Stringable {
}

#[inline]
func has_err_handler(self) -> bool {
func has_err_handler(&self) -> bool {
return self.err_handler.has_expr || self.err_handler.is_propagate;
}
},
BuiltinCall {
name: string;
args: []CallArg;
mut args: []mut CallArg;
pos: token.Pos;
mut builtin: Builtin := .Invalid;
mut type: Type;
Expand Down Expand Up @@ -266,15 +266,15 @@ pub enum Expr < traits.Stringable {
mut defer_stmts: []Stmt.Defer;
},
If {
branches: []IfBranch;
mut branches: []mut IfBranch;
has_else: bool;
pos: token.Pos;
mut expected_type: Type;
mut type: Type;
},
Match {
mut expr: Expr;
branches: []MatchBranch;
mut branches: []mut MatchBranch;
mut is_typematch: bool;
has_else: bool;
mut scope: Scope;
Expand All @@ -286,8 +286,9 @@ pub enum Expr < traits.Stringable {
// Examples:
// - if x := optional_or_result_fn() { ... }
// - while byte := reader.read() { ... }
// - match x := optional_or_result_fn(); x == some { ... }
Guard {
vars: []ObjectData;
mut vars: []mut ObjectData;
mut expr: Expr;
has_cond: bool;
mut cond: Expr;
Expand Down Expand Up @@ -633,7 +634,7 @@ pub struct IfBranch {

#[boxed]
pub struct MatchBranch {
pub patterns: []mut Expr;
pub mut patterns: []mut Expr;
pub has_var: bool;
pub var_is_mut: bool;
pub var_name: string;
Expand Down
18 changes: 9 additions & 9 deletions lib/rivet/src/ast/Scope.ri
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ pub struct Scope {
pub mut owner: ?Sym;
pub mut parent: ?Scope;
pub mut detached_from_parent: bool;
pub mut childrens: []Scope;
pub mut syms: []Sym;
pub mut childrens: []mut Scope;
pub mut syms: []mut Sym;
pub mut is_local: bool;

pub func add(mut self, sym: Sym) -> ! {
Expand All @@ -27,7 +27,7 @@ pub struct Scope {
}

pub func add_or_get(mut self, sym: Sym) -> !Sym {
if old_sym := self.find(sym.name) {
if mut old_sym := self.find(sym.name) {
if sym is TypeSym(type_sym) && old_sym is TypeSym(mut old_type_sym) {
if old_type_sym.update(type_sym)! {
return old_sym;
Expand Down Expand Up @@ -116,24 +116,24 @@ pub struct Scope {
}

pub func update_type(self, name: string, type: Type) {
if sym := self.lookup(name) {
if sym is Var(var_info) {
if mut sym := self.lookup(name) {
if sym is Var(mut var_info) {
var_info.type = type;
}
}
}

pub func update_is_hidden_ref(self, name: string, is_hidden_ref: bool) {
if sym := self.lookup(name) {
if sym is Var(var_info) {
if mut sym := self.lookup(name) {
if sym is Var(mut var_info) {
var_info.is_hidden_ref = is_hidden_ref;
}
}
}

pub func update_is_used(self, name: string, is_used: bool) {
if sym := self.lookup(name) {
if sym is Var(var_info) {
if mut sym := self.lookup(name) {
if sym is Var(mut var_info) {
var_info.is_used = is_used;
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/rivet/src/ast/SourceFile.ri
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import ../token;
#[boxed]
pub struct SourceFile {
pub path: string;
pub decls: []Decl;
pub mut decls: []mut Decl;
pub mut mod: Module;
pub mut imported_symbols: ImportedSymbols;
pub mut pos: token.Pos;
Expand Down
5 changes: 3 additions & 2 deletions lib/rivet/src/ast/Stmt.ri
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub enum Stmt {
Comment(Comment),
Expr(Expr),
VarDecl {
lefts: []ObjectData;
mut lefts: []mut ObjectData;
mut right: Expr;
mut scope: Scope;
pos: token.Pos;
Expand All @@ -27,7 +27,7 @@ pub enum Stmt {
For {
mut index: ObjectData;
has_index: bool;
values: []ObjectData;
mut values: []mut ObjectData;
mut iterable: Expr;
mut stmt: Stmt;
mut scope: Scope;
Expand All @@ -39,6 +39,7 @@ pub enum Stmt {
Error,
Success
}

mut expr: Expr;
mode: Mode;
pos: token.Pos;
Expand Down
2 changes: 1 addition & 1 deletion lib/rivet/src/ast/Sym.ri
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ pub struct Module < Sym {
if type_sym := self.scope.find(unique_name) {
return @as(TypeSym, type_sym);
}
type_sym := TypeSym(
mut type_sym := TypeSym(
is_public: true,
name: unique_name,
info: .DynArray(elem_type, is_mut),
Expand Down
Loading

0 comments on commit 542ce20

Please sign in to comment.