]> git.lizzy.rs Git - rust.git/commitdiff
fix how we walk functions to match new closure fmt
authorNiko Matsakis <niko@alum.mit.edu>
Fri, 6 Jan 2012 20:06:35 +0000 (12:06 -0800)
committerNiko Matsakis <niko@alum.mit.edu>
Sat, 7 Jan 2012 06:40:31 +0000 (22:40 -0800)
15 files changed:
mk/target.mk
src/comp/middle/trans_closure.rs
src/rt/rust.cpp
src/rt/rust_builtin.cpp
src/rt/rust_internal.h
src/rt/rust_kernel.cpp
src/rt/rust_scheduler.cpp
src/rt/rust_shape.cpp
src/rt/rust_shape.h
src/rt/rust_task.cpp
src/rt/rust_task.h
src/rt/rust_upcall.cpp
src/rt/rust_util.h
src/rt/test/rust_test_runtime.cpp
src/test/stdtest/task.rs

index 2ac8fe73ad30cd3252d08f7429b2ad77d23735e9..9ca01837f155fd252ed41c2783c5a11dc73b1cef 100644 (file)
@@ -35,11 +35,6 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB): \
        @$$(call E, compile_and_link: $$@)
        $$(STAGE$(1)_T_$(2)_H_$(3)) --lib -o $$@ $$< && touch $$@
 
-$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_RUNTIME): \
-               rt/$(2)/$$(CFG_RUNTIME)
-       @$$(call E, cp: $$@)
-       $$(Q)cp $$< $$@
-
 $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_RUSTLLVM): \
                rustllvm/$(2)/$$(CFG_RUSTLLVM)
        @$$(call E, cp: $$@)
@@ -62,10 +57,49 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC):                \
 
 endef
 
+# The stage0 (snapshot) compiler produces binaries that expect the
+# snapshot runtime.  Therefore, the stage1 compiler and libraries
+# (which are produced by stage0) should use the runtime from the
+# snapshot.  The stage2 compiler and libraries (which are produced by
+# stage1) will be the first that are expecting to run against the
+# runtime as defined in the working directory.
+#
+# Arguments are the same as for TARGET_BASE_STAGE_N
+define TARGET_RT_FROM_SNAPSHOT
+
+$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_RUNTIME): \
+               $$(HLIB$(1)_H_$(3))/$$(CFG_RUNTIME)
+       @$$(call E, cp: $$@)
+       $$(Q)cp $$< $$@
+
+endef
+
+# This rule copies from the runtime for the working directory.  It
+# applies to targets produced by stage1 or later.  See comment on
+# previous rule.
+#
+# Arguments are the same as for TARGET_BASE_STAGE_N
+define TARGET_RT_FROM_WD
+
+$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_RUNTIME): \
+               rt/$(2)/$$(CFG_RUNTIME)
+       @$$(call E, cp: $$@)
+       $$(Q)cp $$< $$@
+
+endef
+
 # In principle, each host can build each target:
 $(foreach source,$(CFG_TARGET_TRIPLES),                                                \
  $(foreach target,$(CFG_TARGET_TRIPLES),                                       \
-  $(eval $(call TARGET_STAGE_N,0,$(source),$(target)))         \
-  $(eval $(call TARGET_STAGE_N,1,$(source),$(target)))         \
-  $(eval $(call TARGET_STAGE_N,2,$(source),$(target)))         \
-  $(eval $(call TARGET_STAGE_N,3,$(source),$(target)))))
+  $(eval $(call TARGET_STAGE_N,0,$(target),$(source)))         \
+  $(eval $(call TARGET_STAGE_N,1,$(target),$(source)))         \
+  $(eval $(call TARGET_STAGE_N,2,$(target),$(source)))         \
+  $(eval $(call TARGET_STAGE_N,3,$(target),$(source)))))
+
+$(eval $(call TARGET_RT_FROM_SNAPSHOT,0,$(CFG_HOST_TRIPLE),$(CFG_HOST_TRIPLE)))
+
+$(foreach source,$(CFG_TARGET_TRIPLES),                                                \
+ $(foreach target,$(CFG_TARGET_TRIPLES),                                       \
+  $(eval $(call TARGET_RT_FROM_WD,1,$(target),$(source)))      \
+  $(eval $(call TARGET_RT_FROM_WD,2,$(target),$(source)))      \
+  $(eval $(call TARGET_RT_FROM_WD,3,$(target),$(source)))))
index 57791f17ee0f6e059b740f3246e60723d0e30930..aed74da88a03c798d4c3ff287a13fb3045bea8ca 100644 (file)
@@ -646,8 +646,12 @@ fn make_opaque_cbox_take_glue(
     -> @block_ctxt {
     // Easy cases:
     alt ck {
-      ty::closure_block. { ret bcx; }
-      ty::closure_shared. { ret incr_refcnt_of_boxed(bcx, Load(bcx, cboxptr)); }
+      ty::closure_block. {
+        ret bcx;
+      }
+      ty::closure_shared. {
+        ret incr_refcnt_of_boxed(bcx, Load(bcx, cboxptr));
+      }
       ty::closure_send. { /* hard case: */ }
     }
 
@@ -858,7 +862,8 @@ fn trans_bind_thunk(cx: @local_ctxt,
     // Copy in the type parameters.
     check type_is_tup_like(l_bcx, cboxptr_ty);
     let {bcx: l_bcx, val: param_record} =
-        GEP_tup_like(l_bcx, cboxptr_ty, llclosure, [0, abi::cbox_elt_ty_params]);
+        GEP_tup_like(l_bcx, cboxptr_ty, llclosure,
+                     [0, abi::cbox_elt_ty_params]);
     let off = 0;
     for param in param_bounds {
         let dsc = Load(l_bcx, GEPi(l_bcx, param_record, [0, off])),
index 03acdaa91e0381ba6a6304a56f7cdf3ff28b017c..6542c7237a76ef930b17ceeb7fd94a76f25ce1b6 100644 (file)
@@ -1,4 +1,5 @@
 #include "rust_internal.h"
+#include "rust_util.h"
 #include <cstdio>
 
 struct
index 4f951a7faf0af67daf40eac0bf29ba8829f27074..264e6fdb325b679e9e53240c340239a74fcfa445 100644 (file)
@@ -3,6 +3,7 @@
 #include "rust_internal.h"
 #include "rust_scheduler.h"
 #include "rust_task.h"
+#include "rust_util.h"
 
 #if !defined(__WIN32__)
 #include <sys/time.h>
@@ -420,11 +421,6 @@ rust_get_task() {
     return rust_scheduler::get_task();
 }
 
-struct fn_env_pair {
-    spawn_fn f;
-    rust_boxed_closure *env;
-};
-
 extern "C" CDECL void
 start_task(rust_task_id id, fn_env_pair *f) {
     rust_task *task = rust_scheduler::get_task();
index 889b5f62018457ab36a0f2dd9c3040db7ad7af34..b83d74f6bfe3179bb6caf38a3bc968c24459c55d 100644 (file)
@@ -241,8 +241,6 @@ struct rust_timer {
     ~rust_timer();
 };
 
-#include "rust_util.h"
-
 typedef void CDECL (glue_fn)(void *, void *,
                              const type_desc **, void *);
 typedef void CDECL (cmp_glue_fn)(void *, void *,
@@ -254,6 +252,30 @@ struct rust_shape_tables {
     uint8_t *resources;
 };
 
+struct rust_opaque_closure;
+
+// The type of functions that we spawn, which fall into two categories:
+// - the main function: has a NULL environment, but uses the void* arg
+// - unique closures of type fn~(): have a non-NULL environment, but
+//   no arguments (and hence the final void*) is harmless
+typedef void (*CDECL spawn_fn)(void*, rust_opaque_closure*, void *);
+
+// corresponds to the layout of a fn(), fn@(), fn~() etc
+struct fn_env_pair {
+    spawn_fn f;
+    rust_opaque_closure *env;
+};
+
+// corresponds the closures generated in trans_closure.rs
+struct rust_opaque_closure {
+    intptr_t ref_count;
+    const type_desc *td;
+    // The size/types of these will vary per closure, so they
+    // cannot be statically expressed.  See trans_closure.rs:
+    const type_desc *captured_tds[0];
+    // struct bound_data;
+};
+
 struct type_desc {
     // First part of type_desc is known to compiler.
     // first_param = &descs[1] if dynamic, null if static.
@@ -297,7 +319,6 @@ extern "C" type_desc *rust_clone_type_desc(type_desc*);
 // indent-tabs-mode: nil
 // c-basic-offset: 4
 // buffer-file-coding-system: utf-8-unix
-// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
 // End:
 //
 
index f009541053d08d85094c479232928d5aa9477653..3078f6b78c4fa30cebfbaa8d8fd0eb24ee0165c6 100644 (file)
@@ -1,4 +1,5 @@
 #include "rust_internal.h"
+#include "rust_util.h"
 
 #define KLOG_(...)                              \
     KLOG(this, kern, __VA_ARGS__)
@@ -216,6 +217,5 @@ rust_kernel::win32_require(LPCTSTR fn, BOOL ok) {
 // indent-tabs-mode: nil
 // c-basic-offset: 4
 // buffer-file-coding-system: utf-8-unix
-// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
 // End:
 //
index bf40fea36ee0ca807f8fe7e3b239a832db043a1c..1df703069754466f249fe086b0420a65ae071016 100644 (file)
@@ -3,6 +3,7 @@
 #include <cassert>
 #include <pthread.h>
 #include "rust_internal.h"
+#include "rust_util.h"
 #include "globals.h"
 
 #ifndef _WIN32
@@ -414,6 +415,5 @@ rust_scheduler::get_task() {
 // indent-tabs-mode: nil
 // c-basic-offset: 4
 // buffer-file-coding-system: utf-8-unix
-// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
 // End:
 //
index bd388ffff82acd6dbe06a4d676aca7786a1bf4f0..1743aaad9dd3c92ad0f6f1bce586e929e8665546 100644 (file)
@@ -47,13 +47,9 @@ type_param::make(const type_desc **tydescs, unsigned n_tydescs,
 // Constructs type parameters from a function shape. This is a bit messy,
 // because it requires that the function shape have a specific format.
 type_param *
-type_param::from_fn_shape(const uint8_t *sp, ptr dp, arena &arena) {
-    const type_desc *tydesc = bump_dp<const type_desc *>(dp);
-    const type_desc **tydescs = (const type_desc **)dp;
-    unsigned n_tydescs = tydesc->n_obj_params & 0x7fffffff;
-    for (unsigned i = 0; i < n_tydescs; i++)
-        bump_dp<const type_desc*>(dp);
-    return make(tydescs, n_tydescs, arena);
+type_param::from_fn_shape(rust_opaque_closure *env, arena &arena) {
+    unsigned n_tydescs = env->td->n_obj_params & 0x7fffffff;
+    return make(env->captured_tds, n_tydescs, arena);
 }
 
 // Constructs type parameters from an object shape. This is also a bit messy,
index e6f3cfcd3d3b13335173e4f74005b2e7a5f13a6c..af21865f828c0f0bd70864f8e12dced716b5e292 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <iostream>
 #include "rust_internal.h"
+#include "rust_util.h"
 
 // ISAAC pollutes our namespace.
 #undef align
@@ -300,7 +301,7 @@ public:
     const type_param *params;   // subparameters
 
     // Constructs type parameters from a function shape.
-    static type_param *from_fn_shape(const uint8_t *sp, ptr dp, arena &arena);
+    static type_param *from_fn_shape(rust_opaque_closure *env, arena &arena);
     // Creates type parameters from an object shape description.
     static type_param *from_obj_shape(const uint8_t *sp, ptr dp,
                                       arena &arena);
@@ -952,23 +953,17 @@ data<T,U>::walk_tag(tag_info &tinfo) {
 template<typename T,typename U>
 void
 data<T,U>::walk_fn_contents(ptr &dp) {
-    dp += sizeof(void *);   // Skip over the code pointer.
-
-    uint8_t *box_ptr = bump_dp<uint8_t *>(dp);
-    if (!box_ptr)
+    fn_env_pair pair = bump_dp<fn_env_pair>(dp);
+    if (!pair.env)
         return;
 
-    type_desc *subtydesc =
-        *reinterpret_cast<type_desc **>(box_ptr + sizeof(void *));
-    ptr closure_dp(box_ptr + sizeof(void *));
-
     arena arena;
-    type_param *params = type_param::from_fn_shape(subtydesc->shape,
-                                                   closure_dp, arena);
-
-    closure_dp += sizeof(void *);
-    T sub(*static_cast<T *>(this), subtydesc->shape, params,
-          subtydesc->shape_tables, closure_dp);
+    type_param *params =
+      type_param::from_fn_shape(pair.env, arena);
+    const type_desc *closure_td = pair.env->td;
+    ptr closure_dp((uintptr_t)pair.env);
+    T sub(*static_cast<T *>(this), closure_td->shape, params,
+          closure_td->shape_tables, closure_dp);
     sub.align = true;
     sub.walk();
 }
index cade11e372d9271b7ba3e21ec79fd7e1d28322a6..79a6abdcf397a7b0d0bbf3dab79513c94532e948 100644 (file)
@@ -293,7 +293,7 @@ rust_task::~rust_task()
 struct spawn_args {
     rust_task *task;
     spawn_fn f;
-    rust_boxed_closure *envptr;
+    rust_opaque_closure *envptr;
     void *argptr;
 };
 
@@ -347,12 +347,13 @@ void task_start_wrapper(spawn_args *a)
         failed = true;
     }
 
-    rust_boxed_closure* boxed_env = (rust_boxed_closure*)a->envptr;
-    if(boxed_env) {
+    rust_opaque_closure* env = a->envptr;
+    if(env) {
         // free the environment.
-        const type_desc *td = boxed_env->closure.td;
-        td->drop_glue(NULL, NULL, td->first_param, &boxed_env->closure);
-        upcall_shared_free(boxed_env);
+        const type_desc *td = env->td;
+        LOG(task, task, "Freeing env %p with td %p", env, td);
+        td->drop_glue(NULL, NULL, td->first_param, env);
+        upcall_shared_free(env);
     }
 
     // The cleanup work needs lots of stack
@@ -364,7 +365,7 @@ void task_start_wrapper(spawn_args *a)
 
 void
 rust_task::start(spawn_fn spawnee_fn,
-                 rust_boxed_closure *envptr,
+                 rust_opaque_closure *envptr,
                  void *argptr)
 {
     LOG(this, task, "starting task from fn 0x%" PRIxPTR
index 6be28f41574c356c18dee2cf2ffaaef99ff048f8..d0e3d0e2ad6dfe76d0b75d2ff15b876643a727ae 100644 (file)
@@ -21,18 +21,6 @@ struct chan_handle {
     rust_port_id port;
 };
 
-struct rust_closure {
-    const type_desc *td;
-    // ... see trans_closure.rs for full description ...
-};
-
-struct rust_boxed_closure {
-    intptr_t ref_count;
-    rust_closure closure;
-};
-
-typedef void (*CDECL spawn_fn)(void*, rust_boxed_closure*, void *);
-
 struct rust_box;
 
 struct stk_seg {
@@ -145,7 +133,7 @@ rust_task : public kernel_owned<rust_task>, rust_cond
     ~rust_task();
 
     void start(spawn_fn spawnee_fn,
-               rust_boxed_closure *env,
+               rust_opaque_closure *env,
                void *args);
     void start();
     bool running();
index 6baac699e8f27c06dfed902b79845a034825646f..a520770be3a2046f7fcb11d5dcc8acec2b9ede79 100644 (file)
@@ -12,6 +12,7 @@
 #include "rust_scheduler.h"
 #include "rust_unwind.h"
 #include "rust_upcall.h"
+#include "rust_util.h"
 #include <stdint.h>
 
 
index 50545b2131025f6dc810a56f4552bdb3b33fd72f..37a1eb93e1dc3e9babfef37190ef5ac2ab16a889 100644 (file)
@@ -210,7 +210,6 @@ make_str(rust_kernel* kernel, char* c, size_t strlen, const char* name) {
 // indent-tabs-mode: nil
 // c-basic-offset: 4
 // buffer-file-coding-system: utf-8-unix
-// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
 // End:
 //
 
index 7bfa06fdc99477c79e6473fac1c96ada45a740f9..815d55acd868527614b2078b759fdbe57bb2f46e 100644 (file)
@@ -39,7 +39,7 @@ rust_domain_test::run() {
     return true;
 }
 
-void task_entry(void *, rust_boxed_closure *, void *) {
+void task_entry(void *, rust_opaque_closure *, void *) {
     printf("task entry\n");
 }
 
index 7945aaed7447829b59487a465dd2c36b616e6117..d1408d183d525cb4254668dcc924d5a5fa274a57 100644 (file)
@@ -53,7 +53,7 @@ fn test_join_chan_fail() {
 
 #[test]
 fn spawn_polymorphic() {
-    fn foo<send T>(x: T) { log(error, x); }
+    fn foo<T:send>(x: T) { log(error, x); }
     task::spawn {|| foo(true);};
     task::spawn {|| foo(42);};
 }