about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-06-27 15:38:04 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-06-27 15:38:21 -0700
commite4b5d910dc0d5df159a5b9205ded878dfa57664c (patch)
tree66bdb0caaaf316d9abc8bd8b8732b5973b77f597 /src
parent45581673071b1294afb36c17766c57aa70425e19 (diff)
rustc: Directly emit calls to glue if possible
Diffstat (limited to 'src')
-rw-r--r--src/comp/middle/trans.rs29
1 files changed, 27 insertions, 2 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index e77fab450bb..b5f255a7b02 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -2893,13 +2893,38 @@ fn lazily_emit_tydesc_glue(&@block_ctxt cx, int field,
 fn call_tydesc_glue_full(&@block_ctxt cx, ValueRef v, ValueRef tydesc,
                          int field, &option::t[@tydesc_info] static_ti) {
     lazily_emit_tydesc_glue(cx, field, static_ti);
+
+    auto static_glue_fn = none;
+    alt (static_ti) {
+      case (none) { /* no-op */ }
+      case (some(?sti)) {
+        if (field == abi::tydesc_field_take_glue) {
+            static_glue_fn = sti.take_glue;
+        } else if (field == abi::tydesc_field_drop_glue) {
+            static_glue_fn = sti.drop_glue;
+        } else if (field == abi::tydesc_field_free_glue) {
+            static_glue_fn = sti.free_glue;
+        } else if (field == abi::tydesc_field_cmp_glue) {
+            static_glue_fn = sti.cmp_glue;
+        }
+      }
+    }
+
     auto llrawptr = cx.build.BitCast(v, T_ptr(T_i8()));
     auto lltydescs =
         cx.build.GEP(tydesc,
                      [C_int(0), C_int(abi::tydesc_field_first_param)]);
     lltydescs = cx.build.Load(lltydescs);
-    auto llfnptr = cx.build.GEP(tydesc, [C_int(0), C_int(field)]);
-    auto llfn = cx.build.Load(llfnptr);
+
+    auto llfn;
+    alt (static_glue_fn) {
+      case (none) {
+        auto llfnptr = cx.build.GEP(tydesc, [C_int(0), C_int(field)]);
+        llfn = cx.build.Load(llfnptr);
+      }
+      case (some(?sgf)) { llfn = sgf; }
+    }
+
     cx.build.Call(llfn,
                   [C_null(T_ptr(T_nil())), cx.fcx.lltaskptr,
                    C_null(T_ptr(T_nil())), lltydescs, llrawptr]);