Commit aba02613 authored by Jürg Billeter's avatar Jürg Billeter

codegen: Add CodeGenerator.load_local

parent 7d8bc26e
......@@ -26,7 +26,7 @@
/**
* Code visitor generating C Code.
*/
public class Vala.CCodeBaseModule : CodeGenerator {
public abstract class Vala.CCodeBaseModule : CodeGenerator {
public class EmitContext {
public Symbol? current_symbol;
public ArrayList<Symbol> symbol_stack = new ArrayList<Symbol> ();
......
......@@ -24,7 +24,7 @@
using GLib;
public class Vala.CCodeControlFlowModule : CCodeMethodModule {
public abstract class Vala.CCodeControlFlowModule : CCodeMethodModule {
public override void visit_if_statement (IfStatement stmt) {
ccode.open_if (get_cvalue (stmt.condition));
......
......@@ -471,59 +471,21 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
}
} else if (expr.symbol_reference is LocalVariable) {
var local = (LocalVariable) expr.symbol_reference;
if (local.is_result) {
// used in postconditions
// structs are returned as out parameter
if (local.variable_type != null && local.variable_type.is_real_non_null_struct_type ()) {
set_cvalue (expr, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result")));
} else {
set_cvalue (expr, new CCodeIdentifier ("result"));
}
} else if (local.captured) {
// captured variables are stored on the heap
var block = (Block) local.parent_symbol;
set_cvalue (expr, new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_variable_cname (local.name)));
if (array_type != null) {
for (int dim = 1; dim <= array_type.rank; dim++) {
append_array_size (expr, new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_length_cname (get_variable_cname (local.name), dim)));
}
} else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
set_delegate_target (expr, new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (get_variable_cname (local.name))));
set_delegate_target_destroy_notify (expr, new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_destroy_notify_cname (get_variable_cname (local.name))));
}
} else {
set_cvalue (expr, get_variable_cexpression (local.name));
if (array_type != null) {
for (int dim = 1; dim <= array_type.rank; dim++) {
append_array_size (expr, get_variable_cexpression (get_array_length_cname (get_variable_cname (local.name), dim)));
}
} else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
if (current_method != null && current_method.coroutine) {
set_delegate_target (expr, new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (get_variable_cname (local.name))));
set_delegate_target_destroy_notify (expr, new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_destroy_notify_cname (get_variable_cname (local.name))));
} else {
set_delegate_target (expr, new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (local.name))));
if (expr.value_type.value_owned) {
set_delegate_target_destroy_notify (expr, new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (local.name))));
} else {
set_delegate_target_destroy_notify (expr, new CCodeConstant ("NULL"));
}
}
}
expr.target_value = load_local (local);
if (expr.parent_node is ReturnStatement &&
current_return_type.value_owned &&
local.variable_type.value_owned &&
!variable_accessible_in_finally (local)) {
/* return expression is local variable taking ownership and
* current method is transferring ownership */
if (expr.parent_node is ReturnStatement &&
current_return_type.value_owned &&
local.variable_type.value_owned &&
!local.captured &&
!variable_accessible_in_finally (local)) {
/* return expression is local variable taking ownership and
* current method is transferring ownership */
// don't ref expression
expr.value_type.value_owned = true;
// don't ref expression
expr.value_type.value_owned = true;
// don't unref variable
local.active = false;
}
// don't unref variable
local.active = false;
}
} else if (expr.symbol_reference is FormalParameter) {
var p = (FormalParameter) expr.symbol_reference;
......@@ -627,5 +589,64 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
}
}
}
}
public TargetValue get_local_cvalue (LocalVariable local) {
var result = new GLibValue (local.variable_type);
var array_type = local.variable_type as ArrayType;
var delegate_type = local.variable_type as DelegateType;
if (local.is_result) {
// used in postconditions
// structs are returned as out parameter
if (local.variable_type != null && local.variable_type.is_real_non_null_struct_type ()) {
result.cvalue = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result"));
} else {
result.cvalue = new CCodeIdentifier ("result");
}
} else if (local.captured) {
// captured variables are stored on the heap
var block = (Block) local.parent_symbol;
result.cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_variable_cname (local.name));
if (array_type != null) {
for (int dim = 1; dim <= array_type.rank; dim++) {
result.append_array_length_cvalue (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_length_cname (get_variable_cname (local.name), dim)));
}
} else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
result.delegate_target_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (get_variable_cname (local.name)));
result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
}
} else {
result.cvalue = get_variable_cexpression (local.name);
if (array_type != null) {
for (int dim = 1; dim <= array_type.rank; dim++) {
result.append_array_length_cvalue (get_variable_cexpression (get_array_length_cname (get_variable_cname (local.name), dim)));
}
} else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
if (current_method != null && current_method.coroutine) {
result.delegate_target_cvalue = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (get_variable_cname (local.name)));
result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
} else {
result.delegate_target_cvalue = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (local.name)));
if (local.variable_type.value_owned) {
result.delegate_target_destroy_notify_cvalue = new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
}
}
}
}
return result;
}
TargetValue load_variable (Variable variable, TargetValue value) {
return value;
}
public override TargetValue load_local (LocalVariable local) {
var result = (GLibValue) get_local_cvalue (local);
if (local.variable_type is DelegateType && result.delegate_target_destroy_notify_cvalue == null) {
result.delegate_target_destroy_notify_cvalue = new CCodeConstant ("NULL");
}
return load_variable (local, result);
}
}
......@@ -26,7 +26,7 @@ using GLib;
/**
* The link between a method and generated code.
*/
public class Vala.CCodeMethodModule : CCodeStructModule {
public abstract class Vala.CCodeMethodModule : CCodeStructModule {
public override bool method_has_wrapper (Method method) {
return (method.get_attribute ("NoWrapper") == null);
}
......
......@@ -24,7 +24,7 @@
using GLib;
public class Vala.CCodeStructModule : CCodeBaseModule {
public abstract class Vala.CCodeStructModule : CCodeBaseModule {
public override void generate_struct_declaration (Struct st, CCodeFile decl_space) {
if (add_symbol_declaration (decl_space, st, st.get_cname ())) {
return;
......
......@@ -25,7 +25,7 @@
/**
* Code visitor generating C Code.
*/
public class Vala.DovaBaseModule : CodeGenerator {
public abstract class Vala.DovaBaseModule : CodeGenerator {
public class EmitContext {
public Symbol? current_symbol;
public ArrayList<Symbol> symbol_stack = new ArrayList<Symbol> ();
......
......@@ -20,7 +20,7 @@
* Jürg Billeter <j@bitron.ch>
*/
public class Vala.DovaControlFlowModule : DovaMethodModule {
public abstract class Vala.DovaControlFlowModule : DovaMethodModule {
public override void visit_if_statement (IfStatement stmt) {
ccode.open_if (get_cvalue (stmt.condition));
......
......@@ -189,16 +189,7 @@ public class Vala.DovaMemberAccessModule : DovaControlFlowModule {
set_cvalue (expr, ccall);
} else if (expr.symbol_reference is LocalVariable) {
var local = (LocalVariable) expr.symbol_reference;
if (local.is_result) {
// used in postconditions
set_cvalue (expr, new CCodeIdentifier ("result"));
} else if (local.captured) {
// captured variables are stored on the heap
var block = (Block) local.parent_symbol;
set_cvalue (expr, new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_variable_cname (local.name)));
} else {
set_cvalue (expr, get_variable_cexpression (local.name));
}
expr.target_value = load_local (local);
} else if (expr.symbol_reference is FormalParameter) {
var p = (FormalParameter) expr.symbol_reference;
if (p.name == "this") {
......@@ -252,5 +243,30 @@ public class Vala.DovaMemberAccessModule : DovaControlFlowModule {
}
}
}
public TargetValue get_local_cvalue (LocalVariable local) {
var result = new GLibValue (local.variable_type);
if (local.is_result) {
// used in postconditions
result.cvalue = new CCodeIdentifier ("result");
} else if (local.captured) {
// captured variables are stored on the heap
var block = (Block) local.parent_symbol;
result.cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_variable_cname (local.name));
} else {
result.cvalue = get_variable_cexpression (local.name);
}
return result;
}
TargetValue load_variable (Variable variable, TargetValue value) {
return value;
}
public override TargetValue load_local (LocalVariable local) {
return load_variable (local, get_local_cvalue (local));
}
}
......@@ -23,7 +23,7 @@
/**
* The link between a method and generated code.
*/
public class Vala.DovaMethodModule : DovaStructModule {
public abstract class Vala.DovaMethodModule : DovaStructModule {
public override bool method_has_wrapper (Method method) {
return (method.get_attribute ("NoWrapper") == null);
}
......
......@@ -22,7 +22,7 @@
using GLib;
public class Vala.DovaStructModule : DovaBaseModule {
public abstract class Vala.DovaStructModule : DovaBaseModule {
public override void generate_struct_declaration (Struct st, CCodeFile decl_space) {
if (add_symbol_declaration (decl_space, st, st.get_cname ())) {
return;
......
......@@ -33,4 +33,6 @@ public abstract class Vala.CodeGenerator : CodeVisitor {
}
public abstract LocalVariable create_local (DataType type);
public abstract TargetValue load_local (LocalVariable local);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment