about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-09-23 11:01:09 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-09-23 11:11:37 +0200
commit0bbde048a414bdf6dcdf7e00cc429bf8d8d2a5f0 (patch)
tree29b3c6e7841c141d535076aa9bd49d0bf37c26cf
parent49813cffb12d00886bfd3d3a1a027deafad49bbd (diff)
Make sure no dynamic allocas are used before they are allocated
Closes #965
-rw-r--r--src/comp/middle/trans.rs55
-rw-r--r--src/comp/middle/trans_common.rs8
-rw-r--r--src/comp/middle/trans_objects.rs2
3 files changed, 29 insertions, 36 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 865417031d0..e5736071060 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -1186,17 +1186,17 @@ fn make_generic_glue_inner(cx: @local_ctxt, sp: span, t: ty::t,
 
     let ty_param_count = std::vec::len::<uint>(ty_params);
     let lltyparams = llvm::LLVMGetParam(llfn, 3u);
-    let copy_args_bcx = new_raw_block_ctxt(fcx, fcx.llcopyargs);
+    let load_env_bcx = new_raw_block_ctxt(fcx, fcx.llloadenv);
     let lltydescs = [mutable];
     let p = 0u;
     while p < ty_param_count {
-        let llparam = GEP(copy_args_bcx, lltyparams, [C_int(p as int)]);
-        llparam = Load(copy_args_bcx, llparam);
+        let llparam = GEP(load_env_bcx, lltyparams, [C_int(p as int)]);
+        llparam = Load(load_env_bcx, llparam);
         std::vec::grow_set(lltydescs, ty_params[p], 0 as ValueRef, llparam);
         p += 1u;
     }
 
-    // TODO: Implement some kind of freeze operation in the standard library.
+    // FIXME: Implement some kind of freeze operation in the standard library.
     let lltydescs_frozen = [];
     for lltydesc: ValueRef in lltydescs { lltydescs_frozen += [lltydesc]; }
     fcx.lltydescs = lltydescs_frozen;
@@ -2653,7 +2653,7 @@ fn find_environment_tydescs(bcx: @block_ctxt, envty: ty::t, closure: ValueRef)
 // with the upvars and type descriptors.
 fn load_environment(enclosing_cx: @block_ctxt, fcx: @fn_ctxt, envty: ty::t,
                     upvars: @[ast::def], copying: bool) {
-    let bcx = new_raw_block_ctxt(fcx, fcx.llcopyargs);
+    let bcx = new_raw_block_ctxt(fcx, fcx.llloadenv);
 
     let ty = ty::mk_imm_box(bcx_tcx(bcx), envty);
 
@@ -3322,8 +3322,8 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
     // Since we might need to construct derived tydescs that depend on
     // our bound tydescs, we need to load tydescs out of the environment
     // before derived tydescs are constructed. To do this, we load them
-    // in the copy_args block.
-    let copy_args_bcx = new_raw_block_ctxt(fcx, fcx.llcopyargs);
+    // in the load_env block.
+    let load_env_bcx = new_raw_block_ctxt(fcx, fcx.llloadenv);
 
     // The 'llenv' that will arrive in the thunk we're creating is an
     // environment that will contain the values of its arguments and a pointer
@@ -3336,7 +3336,7 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
     // (Issue #586)
     check (type_has_static_size(ccx, closure_ty));
     let llclosure_ptr_ty = type_of(ccx, sp, closure_ty);
-    let llclosure = PointerCast(copy_args_bcx, fcx.llenv, llclosure_ptr_ty);
+    let llclosure = PointerCast(load_env_bcx, fcx.llenv, llclosure_ptr_ty);
 
     // "target", in this context, means the function that's having some of its
     // arguments bound and that will be called inside the thunk we're
@@ -3388,13 +3388,13 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
     let i: uint = 0u;
     while i < ty_param_count {
         // Silly check
-        check type_is_tup_like(copy_args_bcx, closure_ty);
+        check type_is_tup_like(load_env_bcx, closure_ty);
         let lltyparam_ptr =
-            GEP_tup_like(copy_args_bcx, closure_ty, llclosure,
+            GEP_tup_like(load_env_bcx, closure_ty, llclosure,
                          [0, abi::box_rc_field_body,
                           abi::closure_elt_ty_params, i as int]);
-        copy_args_bcx = lltyparam_ptr.bcx;
-        let td = Load(copy_args_bcx, lltyparam_ptr.val);
+        load_env_bcx = lltyparam_ptr.bcx;
+        let td = Load(load_env_bcx, lltyparam_ptr.val);
         llargs += [td];
         fcx.lltydescs += [td];
         i += 1u;
@@ -4972,7 +4972,7 @@ fn mk_standard_basic_blocks(llfn: ValueRef) ->
              str::as_buf("static_allocas",
                          {|buf| llvm::LLVMAppendBasicBlock(llfn, buf) }),
          ca:
-             str::as_buf("copy_args",
+             str::as_buf("load_env",
                          {|buf| llvm::LLVMAppendBasicBlock(llfn, buf) }),
          dt:
              str::as_buf("derived_tydescs",
@@ -5001,7 +5001,7 @@ fn new_fn_ctxt_w_id(cx: @local_ctxt, sp: span, llfndecl: ValueRef,
           llenv: llvm::LLVMGetParam(llfndecl, 2u),
           llretptr: llvm::LLVMGetParam(llfndecl, 0u),
           mutable llstaticallocas: llbbs.sa,
-          mutable llcopyargs: llbbs.ca,
+          mutable llloadenv: llbbs.ca,
           mutable llderivedtydescs_first: llbbs.dt,
           mutable llderivedtydescs: llbbs.dt,
           mutable lldynamicallocas: llbbs.da,
@@ -5082,10 +5082,9 @@ fn create_llargs_for_fn_args(cx: @fn_ctxt, proto: ast::proto,
     }
 }
 
-fn copy_args_to_allocas(fcx: @fn_ctxt, scope: @block_ctxt, args: [ast::arg],
-                        arg_tys: [ty::arg], ignore_mut: bool) {
-    let llcopyargs = new_raw_block_ctxt(fcx, fcx.llcopyargs);
-    let bcx = llcopyargs;
+fn copy_args_to_allocas(fcx: @fn_ctxt, bcx: @block_ctxt, args: [ast::arg],
+                        arg_tys: [ty::arg], ignore_mut: bool)
+    -> @block_ctxt {
     let arg_n: uint = 0u;
     for aarg: ast::arg in args {
         let arg_ty = arg_tys[arg_n].ty;
@@ -5097,23 +5096,23 @@ fn copy_args_to_allocas(fcx: @fn_ctxt, scope: @block_ctxt, args: [ast::arg],
             // Overwrite the llargs entry for locally mutated params
             // with a local alloca.
             if mutated {
-                let aptr = bcx.fcx.llargs.get(aarg.id);
+                let aptr = fcx.llargs.get(aarg.id);
                 let {bcx: bcx, val: alloc} = alloc_ty(bcx, arg_ty);
                 bcx =
                     copy_val(bcx, INIT, alloc,
                              load_if_immediate(bcx, aptr, arg_ty), arg_ty);
-                bcx.fcx.llargs.insert(aarg.id, alloc);
-                add_clean(scope, alloc, arg_ty);
+                fcx.llargs.insert(aarg.id, alloc);
+                add_clean(bcx, alloc, arg_ty);
             }
           }
           ast::by_move. {
-            add_clean(scope, bcx.fcx.llargs.get(aarg.id), arg_ty);
+            add_clean(bcx, fcx.llargs.get(aarg.id), arg_ty);
           }
           _ { }
         }
         arg_n += 1u;
     }
-    fcx.llcopyargs = llcopyargs.llbb;
+    ret bcx;
 }
 
 fn arg_tys_of_fn(ccx: @crate_ctxt, id: ast::node_id) -> [ty::arg] {
@@ -5170,11 +5169,11 @@ fn populate_fn_ctxt_from_llself(fcx: @fn_ctxt, llself: val_self_pair) {
 }
 
 
-// Ties up the llstaticallocas -> llcopyargs -> llderivedtydescs ->
+// Ties up the llstaticallocas -> llloadenv -> llderivedtydescs ->
 // lldynamicallocas -> lltop edges, and builds the return block.
 fn finish_fn(fcx: @fn_ctxt, lltop: BasicBlockRef) {
-    Br(new_raw_block_ctxt(fcx, fcx.llstaticallocas), fcx.llcopyargs);
-    Br(new_raw_block_ctxt(fcx, fcx.llcopyargs), fcx.llderivedtydescs_first);
+    Br(new_raw_block_ctxt(fcx, fcx.llstaticallocas), fcx.llloadenv);
+    Br(new_raw_block_ctxt(fcx, fcx.llloadenv), fcx.llderivedtydescs_first);
     Br(new_raw_block_ctxt(fcx, fcx.llderivedtydescs), fcx.lldynamicallocas);
     Br(new_raw_block_ctxt(fcx, fcx.lldynamicallocas), lltop);
 
@@ -5210,7 +5209,7 @@ fn trans_closure(bcx_maybe: option::t<@block_ctxt>,
     let block_ty = node_id_type(cx.ccx, f.body.node.id);
 
     let arg_tys = arg_tys_of_fn(fcx.lcx.ccx, id);
-    copy_args_to_allocas(fcx, bcx, f.decl.inputs, arg_tys, false);
+    bcx = copy_args_to_allocas(fcx, bcx, f.decl.inputs, arg_tys, false);
 
     // Figure out if we need to build a closure and act accordingly
     let res =
@@ -5362,8 +5361,8 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id,
     }
     let arg_tys = arg_tys_of_fn(cx.ccx, variant.node.id);
     let bcx = new_top_block_ctxt(fcx);
-    copy_args_to_allocas(fcx, bcx, fn_args, arg_tys, true);
     let lltop = bcx.llbb;
+    bcx = copy_args_to_allocas(fcx, bcx, fn_args, arg_tys, true);
 
     // Cast the tag to a type we can GEP into.
     let llblobptr =
diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs
index fb32e6bfe9a..b0c64b1d474 100644
--- a/src/comp/middle/trans_common.rs
+++ b/src/comp/middle/trans_common.rs
@@ -183,12 +183,6 @@ type fn_ctxt =
     // after llderivedtydescs, because these sometimes depend on
     // information computed from derived tydescs.
 
-    // FIXME: Is llcopyargs actually the block containing the allocas
-    // for incoming function arguments?  Or is it merely the block
-    // containing code that copies incoming args to space already
-    // alloca'd by code in llallocas?
-
-
     // The token used to clear the dynamic allocas at the end of this frame.
 
     // The 'self' object currently in use in this function, if there
@@ -245,7 +239,7 @@ type fn_ctxt =
      llenv: ValueRef,
      llretptr: ValueRef,
      mutable llstaticallocas: BasicBlockRef,
-     mutable llcopyargs: BasicBlockRef,
+     mutable llloadenv: BasicBlockRef,
      mutable llderivedtydescs_first: BasicBlockRef,
      mutable llderivedtydescs: BasicBlockRef,
      mutable lldynamicallocas: BasicBlockRef,
diff --git a/src/comp/middle/trans_objects.rs b/src/comp/middle/trans_objects.rs
index 5688048085d..01f7eec5873 100644
--- a/src/comp/middle/trans_objects.rs
+++ b/src/comp/middle/trans_objects.rs
@@ -55,7 +55,7 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
                               ty::ret_ty_of_fn(ccx.tcx, ctor_id), fn_args,
                               ty_params);
     let arg_tys: [ty::arg] = arg_tys_of_fn(ccx, ctor_id);
-    copy_args_to_allocas(fcx, bcx, fn_args, arg_tys, true);
+    bcx = copy_args_to_allocas(fcx, bcx, fn_args, arg_tys, true);
 
     // Pick up the type of this object by looking at our own output type, that
     // is, the output type of the object constructor we're building.