Skip to content

Commit

Permalink
compiler: fix code generation for lvalue expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
mertcandav committed Sep 15, 2024
1 parent dcae6df commit 4c863e6
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 71 deletions.
53 changes: 24 additions & 29 deletions src/julec/obj/cxx/expr.jule
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ impl exprCoder {
self.oc.write(".")
identCoder.field(self.oc.Buf, f.Decl)
self.oc.write("=")
self.possibleRefExpr(arg.Expr.Model)
self.oc.sc.handleCopy(arg.Expr.Model)
inited = true
continue fields
}
Expand Down Expand Up @@ -1313,6 +1313,7 @@ impl exprCoder {

fn handleTraitSubMoveSemantics(mut &self, mut m: &TraitSubIdentExprModel): (ordinary: bool) {
const tempVar = "__jule_temp"
const retVar = "__jule_result"
mut deref := false
mut dropKind := m.Expr.Kind
match type m.Expr.Model {
Expand All @@ -1324,38 +1325,35 @@ impl exprCoder {
// no need to handle drop semantics
ret true
}
match type uem.Expr.Model {
| &FnCallExprModel:
// Base expression comes from a function call.
// Need to be drop.
break
|:
if obj::IsLvalueBasedModel(uem.Expr.Model) {
// Expression come from safe place.
// Handle it in ordinary way.
ret true
}
// guaranteed: type abviously needs to be dropped
self.oc.write("({ auto ")
self.oc.write("(*({ auto ")
self.oc.write(tempVar)
self.oc.write(" = ")
self.possibleRefExpr(uem.Expr.Model)
self.oc.write("; ")
deref = true
dropKind = uem.Expr.Kind
| &FnCallExprModel:
|:
if !obj::TypeHaveSpecialDrop(m.Expr.Kind) {
// no need to handle drop semantics
ret true
}
if obj::IsLvalueBasedModel(m.Expr.Model) {
// Expression come from safe place.
// Handle it in ordinary way.
ret true
}
// guaranteed: type abviously needs to be dropped
self.oc.write("({ auto ")
self.oc.write("(*({ auto ")
self.oc.write(tempVar)
self.oc.write(" = ")
self.possibleRefExpr(m.Expr.Model)
self.oc.write("; ")
|:
// handle like ordinary expression
ret true
}
// guaranteed: type abviously needs to be dropped
self.oc.write("((")
Expand Down Expand Up @@ -1418,56 +1416,53 @@ impl exprCoder {
// no need to handle drop semantics
ret true
}
match type uem.Expr.Model {
| &FnCallExprModel:
// Base expression comes from a function call.
// Need to be drop.
break
|:
if obj::IsLvalueBasedModel(uem.Expr.Model) {
// Expression come from safe place.
// Handle it in ordinary way.
ret true
}
// guaranteed: type abviously needs to be dropped
self.oc.write("({ auto ")
self.oc.write("(*({ auto ")
self.oc.write(tempVar)
self.oc.write(" = ")
self.possibleRefExpr(uem.Expr.Model)
self.oc.write("; ")
deref = true
dropKind = uem.Expr.Kind
| &FnCallExprModel:
|:
if !obj::TypeHaveSpecialDrop(m.Expr.Kind) {
// no need to handle drop semantics
ret true
}
if obj::IsLvalueBasedModel(m.Expr.Model) {
// Expression come from safe place.
// Handle it in ordinary way.
ret true
}
// guaranteed: type abviously needs to be dropped
self.oc.write("({ auto ")
self.oc.write("(*({ auto ")
self.oc.write(tempVar)
self.oc.write(" = ")
self.possibleRefExpr(m.Expr.Model)
self.oc.write("; ")
|:
// handle like ordinary expression
ret true
}
// guaranteed: type abviously needs to be dropped
self.oc.tc.kind(self.oc.Buf, m.Field.Kind)
self.oc.write(" ")
self.oc.write(" *")
self.oc.write(retVar)
self.oc.write(" = ")
self.oc.write(" = &(")
self.oc.write(tempVar)
if deref {
self.oc.write("->")
} else {
self.oc.write(".")
}
identCoder.field(self.oc.Buf, m.Field.Decl)
self.oc.write("; ")
self.oc.write("); ")
self.oc.sc.dh.dropModel(tempVar, dropKind)
self.oc.write("(")
self.oc.write(retVar)
self.oc.write("); })")
self.oc.write("); }))")
ret false
}

Expand Down
31 changes: 0 additions & 31 deletions src/julec/obj/cxx/type.jule
Original file line number Diff line number Diff line change
Expand Up @@ -511,35 +511,4 @@ fn shouldInitialized(mut &t: &TypeKind): bool {
|:
ret true
}
}

// Returns element kind of t.
// Returns nil if type have not element type.
fn getElemKind(mut &t: &TypeKind): &TypeKind {
mut ptr := t.Ptr()
if ptr != nil {
if ptr.IsUnsafe() {
ret nil
}
ret ptr.Elem
}
mut sptr := t.Sptr()
if sptr != nil {
ret sptr.Elem
}
mut arr := t.Arr()
if arr != nil {
ret arr.Elem
}
mut slice := t.Slc()
if slice != nil {
ret slice.Elem
}
mut prim := t.Prim()
if prim != nil {
if prim.IsStr() {
ret primByte
}
}
ret nil
}
61 changes: 50 additions & 11 deletions src/julec/obj/determine.jule
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,55 @@ fn IsImplicitImport(imp: &ImportInfo): bool {
ret imp.Token == nil
}

// Returns element kind of t.
// Returns nil if type have not element type.
fn GetElemKind(mut &t: &sema::TypeKind): &sema::TypeKind {
mut ptr := t.Ptr()
if ptr != nil {
if ptr.IsUnsafe() {
ret nil
}
ret ptr.Elem
}
mut sptr := t.Sptr()
if sptr != nil {
ret sptr.Elem
}
mut arr := t.Arr()
if arr != nil {
ret arr.Elem
}
mut slice := t.Slc()
if slice != nil {
ret slice.Elem
}
mut prim := t.Prim()
if prim != nil {
if prim.IsStr() {
ret &sema::TypeKind{
Kind: &sema::Prim{
Kind: types::TypeKind.U8,
},
}
}
}
ret nil
}

// Similary to IsLvalueModel, but designed to determine whether expression is
// based on lvalue expression.
fn IsLvalueBasedModel(mut m: any): bool {
match type m {
| &sema::UnaryExprModel:
mut uem := (&sema::UnaryExprModel)(m)
if uem.Op.Id == lex::TokenId.Star {
ret IsLvalueBasedModel(uem.Expr.Model)
}
ret false
}
ret IsLvalueModel(m) != nil
}

// Reports whether expression model is lvalue expression model.
// Designed to determine copy semantics required expression models.
// Returns expression type of expression model if valid, nil otherwise.
Expand All @@ -128,17 +177,7 @@ fn IsLvalueModel(mut m: any): &TypeKind {
| &sema::UnaryExprModel:
mut unary := (&sema::UnaryExprModel)(m)
if unary.Op.Id == lex::TokenId.Star {
match {
| unary.Expr.Kind.Ptr() != nil:
mut p := unary.Expr.Kind.Ptr()
if p.IsUnsafe() {
ret nil
}
ret p.Elem
| unary.Expr.Kind.Sptr() != nil:
mut p := unary.Expr.Kind.Sptr()
ret p.Elem
}
ret GetElemKind(unary.Expr.Kind)
}
ret nil
| &sema::IndexingExprModel:
Expand Down

0 comments on commit 4c863e6

Please sign in to comment.