Skip to content

Commit 8506241

Browse files
committed
fix how we walk functions to match new closure fmt
1 parent 8e89df6 commit 8506241

15 files changed

+104
-67
lines changed

mk/target.mk

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,6 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB): \
3535
@$$(call E, compile_and_link: $$@)
3636
$$(STAGE$(1)_T_$(2)_H_$(3)) --lib -o $$@ $$< && touch $$@
3737

38-
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_RUNTIME): \
39-
rt/$(2)/$$(CFG_RUNTIME)
40-
@$$(call E, cp: $$@)
41-
$$(Q)cp $$< $$@
42-
4338
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_RUSTLLVM): \
4439
rustllvm/$(2)/$$(CFG_RUSTLLVM)
4540
@$$(call E, cp: $$@)
@@ -62,10 +57,49 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC): \
6257

6358
endef
6459

60+
# The stage0 (snapshot) compiler produces binaries that expect the
61+
# snapshot runtime. Therefore, the stage1 compiler and libraries
62+
# (which are produced by stage0) should use the runtime from the
63+
# snapshot. The stage2 compiler and libraries (which are produced by
64+
# stage1) will be the first that are expecting to run against the
65+
# runtime as defined in the working directory.
66+
#
67+
# Arguments are the same as for TARGET_BASE_STAGE_N
68+
define TARGET_RT_FROM_SNAPSHOT
69+
70+
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_RUNTIME): \
71+
$$(HLIB$(1)_H_$(3))/$$(CFG_RUNTIME)
72+
@$$(call E, cp: $$@)
73+
$$(Q)cp $$< $$@
74+
75+
endef
76+
77+
# This rule copies from the runtime for the working directory. It
78+
# applies to targets produced by stage1 or later. See comment on
79+
# previous rule.
80+
#
81+
# Arguments are the same as for TARGET_BASE_STAGE_N
82+
define TARGET_RT_FROM_WD
83+
84+
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_RUNTIME): \
85+
rt/$(2)/$$(CFG_RUNTIME)
86+
@$$(call E, cp: $$@)
87+
$$(Q)cp $$< $$@
88+
89+
endef
90+
6591
# In principle, each host can build each target:
6692
$(foreach source,$(CFG_TARGET_TRIPLES), \
6793
$(foreach target,$(CFG_TARGET_TRIPLES), \
68-
$(eval $(call TARGET_STAGE_N,0,$(source),$(target))) \
69-
$(eval $(call TARGET_STAGE_N,1,$(source),$(target))) \
70-
$(eval $(call TARGET_STAGE_N,2,$(source),$(target))) \
71-
$(eval $(call TARGET_STAGE_N,3,$(source),$(target)))))
94+
$(eval $(call TARGET_STAGE_N,0,$(target),$(source))) \
95+
$(eval $(call TARGET_STAGE_N,1,$(target),$(source))) \
96+
$(eval $(call TARGET_STAGE_N,2,$(target),$(source))) \
97+
$(eval $(call TARGET_STAGE_N,3,$(target),$(source)))))
98+
99+
$(eval $(call TARGET_RT_FROM_SNAPSHOT,0,$(CFG_HOST_TRIPLE),$(CFG_HOST_TRIPLE)))
100+
101+
$(foreach source,$(CFG_TARGET_TRIPLES), \
102+
$(foreach target,$(CFG_TARGET_TRIPLES), \
103+
$(eval $(call TARGET_RT_FROM_WD,1,$(target),$(source))) \
104+
$(eval $(call TARGET_RT_FROM_WD,2,$(target),$(source))) \
105+
$(eval $(call TARGET_RT_FROM_WD,3,$(target),$(source)))))

src/comp/middle/trans_closure.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,12 @@ fn make_opaque_cbox_take_glue(
646646
-> @block_ctxt {
647647
// Easy cases:
648648
alt ck {
649-
ty::closure_block. { ret bcx; }
650-
ty::closure_shared. { ret incr_refcnt_of_boxed(bcx, Load(bcx, cboxptr)); }
649+
ty::closure_block. {
650+
ret bcx;
651+
}
652+
ty::closure_shared. {
653+
ret incr_refcnt_of_boxed(bcx, Load(bcx, cboxptr));
654+
}
651655
ty::closure_send. { /* hard case: */ }
652656
}
653657

@@ -858,7 +862,8 @@ fn trans_bind_thunk(cx: @local_ctxt,
858862
// Copy in the type parameters.
859863
check type_is_tup_like(l_bcx, cboxptr_ty);
860864
let {bcx: l_bcx, val: param_record} =
861-
GEP_tup_like(l_bcx, cboxptr_ty, llclosure, [0, abi::cbox_elt_ty_params]);
865+
GEP_tup_like(l_bcx, cboxptr_ty, llclosure,
866+
[0, abi::cbox_elt_ty_params]);
862867
let off = 0;
863868
for param in param_bounds {
864869
let dsc = Load(l_bcx, GEPi(l_bcx, param_record, [0, off])),

src/rt/rust.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "rust_internal.h"
2+
#include "rust_util.h"
23
#include <cstdio>
34

45
struct

src/rt/rust_builtin.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "rust_internal.h"
44
#include "rust_scheduler.h"
55
#include "rust_task.h"
6+
#include "rust_util.h"
67

78
#if !defined(__WIN32__)
89
#include <sys/time.h>
@@ -420,11 +421,6 @@ rust_get_task() {
420421
return rust_scheduler::get_task();
421422
}
422423

423-
struct fn_env_pair {
424-
spawn_fn f;
425-
rust_boxed_closure *env;
426-
};
427-
428424
extern "C" CDECL void
429425
start_task(rust_task_id id, fn_env_pair *f) {
430426
rust_task *task = rust_scheduler::get_task();

src/rt/rust_internal.h

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,6 @@ struct rust_timer {
241241
~rust_timer();
242242
};
243243

244-
#include "rust_util.h"
245-
246244
typedef void CDECL (glue_fn)(void *, void *,
247245
const type_desc **, void *);
248246
typedef void CDECL (cmp_glue_fn)(void *, void *,
@@ -254,6 +252,30 @@ struct rust_shape_tables {
254252
uint8_t *resources;
255253
};
256254

255+
struct rust_opaque_closure;
256+
257+
// The type of functions that we spawn, which fall into two categories:
258+
// - the main function: has a NULL environment, but uses the void* arg
259+
// - unique closures of type fn~(): have a non-NULL environment, but
260+
// no arguments (and hence the final void*) is harmless
261+
typedef void (*CDECL spawn_fn)(void*, rust_opaque_closure*, void *);
262+
263+
// corresponds to the layout of a fn(), fn@(), fn~() etc
264+
struct fn_env_pair {
265+
spawn_fn f;
266+
rust_opaque_closure *env;
267+
};
268+
269+
// corresponds the closures generated in trans_closure.rs
270+
struct rust_opaque_closure {
271+
intptr_t ref_count;
272+
const type_desc *td;
273+
// The size/types of these will vary per closure, so they
274+
// cannot be statically expressed. See trans_closure.rs:
275+
const type_desc *captured_tds[0];
276+
// struct bound_data;
277+
};
278+
257279
struct type_desc {
258280
// First part of type_desc is known to compiler.
259281
// first_param = &descs[1] if dynamic, null if static.
@@ -297,7 +319,6 @@ extern "C" type_desc *rust_clone_type_desc(type_desc*);
297319
// indent-tabs-mode: nil
298320
// c-basic-offset: 4
299321
// buffer-file-coding-system: utf-8-unix
300-
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
301322
// End:
302323
//
303324

src/rt/rust_kernel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "rust_internal.h"
2+
#include "rust_util.h"
23

34
#define KLOG_(...) \
45
KLOG(this, kern, __VA_ARGS__)
@@ -216,6 +217,5 @@ rust_kernel::win32_require(LPCTSTR fn, BOOL ok) {
216217
// indent-tabs-mode: nil
217218
// c-basic-offset: 4
218219
// buffer-file-coding-system: utf-8-unix
219-
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
220220
// End:
221221
//

src/rt/rust_scheduler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <cassert>
44
#include <pthread.h>
55
#include "rust_internal.h"
6+
#include "rust_util.h"
67
#include "globals.h"
78

89
#ifndef _WIN32
@@ -414,6 +415,5 @@ rust_scheduler::get_task() {
414415
// indent-tabs-mode: nil
415416
// c-basic-offset: 4
416417
// buffer-file-coding-system: utf-8-unix
417-
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
418418
// End:
419419
//

src/rt/rust_shape.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,9 @@ type_param::make(const type_desc **tydescs, unsigned n_tydescs,
4747
// Constructs type parameters from a function shape. This is a bit messy,
4848
// because it requires that the function shape have a specific format.
4949
type_param *
50-
type_param::from_fn_shape(const uint8_t *sp, ptr dp, arena &arena) {
51-
const type_desc *tydesc = bump_dp<const type_desc *>(dp);
52-
const type_desc **tydescs = (const type_desc **)dp;
53-
unsigned n_tydescs = tydesc->n_obj_params & 0x7fffffff;
54-
for (unsigned i = 0; i < n_tydescs; i++)
55-
bump_dp<const type_desc*>(dp);
56-
return make(tydescs, n_tydescs, arena);
50+
type_param::from_fn_shape(rust_opaque_closure *env, arena &arena) {
51+
unsigned n_tydescs = env->td->n_obj_params & 0x7fffffff;
52+
return make(env->captured_tds, n_tydescs, arena);
5753
}
5854

5955
// Constructs type parameters from an object shape. This is also a bit messy,

src/rt/rust_shape.h

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <iostream>
1212
#include "rust_internal.h"
13+
#include "rust_util.h"
1314

1415
// ISAAC pollutes our namespace.
1516
#undef align
@@ -300,7 +301,7 @@ class type_param {
300301
const type_param *params; // subparameters
301302

302303
// Constructs type parameters from a function shape.
303-
static type_param *from_fn_shape(const uint8_t *sp, ptr dp, arena &arena);
304+
static type_param *from_fn_shape(rust_opaque_closure *env, arena &arena);
304305
// Creates type parameters from an object shape description.
305306
static type_param *from_obj_shape(const uint8_t *sp, ptr dp,
306307
arena &arena);
@@ -952,23 +953,17 @@ data<T,U>::walk_tag(tag_info &tinfo) {
952953
template<typename T,typename U>
953954
void
954955
data<T,U>::walk_fn_contents(ptr &dp) {
955-
dp += sizeof(void *); // Skip over the code pointer.
956-
957-
uint8_t *box_ptr = bump_dp<uint8_t *>(dp);
958-
if (!box_ptr)
956+
fn_env_pair pair = bump_dp<fn_env_pair>(dp);
957+
if (!pair.env)
959958
return;
960959

961-
type_desc *subtydesc =
962-
*reinterpret_cast<type_desc **>(box_ptr + sizeof(void *));
963-
ptr closure_dp(box_ptr + sizeof(void *));
964-
965960
arena arena;
966-
type_param *params = type_param::from_fn_shape(subtydesc->shape,
967-
closure_dp, arena);
968-
969-
closure_dp += sizeof(void *);
970-
T sub(*static_cast<T *>(this), subtydesc->shape, params,
971-
subtydesc->shape_tables, closure_dp);
961+
type_param *params =
962+
type_param::from_fn_shape(pair.env, arena);
963+
const type_desc *closure_td = pair.env->td;
964+
ptr closure_dp((uintptr_t)pair.env);
965+
T sub(*static_cast<T *>(this), closure_td->shape, params,
966+
closure_td->shape_tables, closure_dp);
972967
sub.align = true;
973968
sub.walk();
974969
}

src/rt/rust_task.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ rust_task::~rust_task()
293293
struct spawn_args {
294294
rust_task *task;
295295
spawn_fn f;
296-
rust_boxed_closure *envptr;
296+
rust_opaque_closure *envptr;
297297
void *argptr;
298298
};
299299

@@ -347,12 +347,13 @@ void task_start_wrapper(spawn_args *a)
347347
failed = true;
348348
}
349349

350-
rust_boxed_closure* boxed_env = (rust_boxed_closure*)a->envptr;
351-
if(boxed_env) {
350+
rust_opaque_closure* env = a->envptr;
351+
if(env) {
352352
// free the environment.
353-
const type_desc *td = boxed_env->closure.td;
354-
td->drop_glue(NULL, NULL, td->first_param, &boxed_env->closure);
355-
upcall_shared_free(boxed_env);
353+
const type_desc *td = env->td;
354+
LOG(task, task, "Freeing env %p with td %p", env, td);
355+
td->drop_glue(NULL, NULL, td->first_param, env);
356+
upcall_shared_free(env);
356357
}
357358

358359
// The cleanup work needs lots of stack
@@ -364,7 +365,7 @@ void task_start_wrapper(spawn_args *a)
364365

365366
void
366367
rust_task::start(spawn_fn spawnee_fn,
367-
rust_boxed_closure *envptr,
368+
rust_opaque_closure *envptr,
368369
void *argptr)
369370
{
370371
LOG(this, task, "starting task from fn 0x%" PRIxPTR

src/rt/rust_task.h

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,6 @@ struct chan_handle {
2121
rust_port_id port;
2222
};
2323

24-
struct rust_closure {
25-
const type_desc *td;
26-
// ... see trans_closure.rs for full description ...
27-
};
28-
29-
struct rust_boxed_closure {
30-
intptr_t ref_count;
31-
rust_closure closure;
32-
};
33-
34-
typedef void (*CDECL spawn_fn)(void*, rust_boxed_closure*, void *);
35-
3624
struct rust_box;
3725

3826
struct stk_seg {
@@ -145,7 +133,7 @@ rust_task : public kernel_owned<rust_task>, rust_cond
145133
~rust_task();
146134

147135
void start(spawn_fn spawnee_fn,
148-
rust_boxed_closure *env,
136+
rust_opaque_closure *env,
149137
void *args);
150138
void start();
151139
bool running();

src/rt/rust_upcall.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "rust_scheduler.h"
1313
#include "rust_unwind.h"
1414
#include "rust_upcall.h"
15+
#include "rust_util.h"
1516
#include <stdint.h>
1617

1718

src/rt/rust_util.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,6 @@ make_str(rust_kernel* kernel, char* c, size_t strlen, const char* name) {
210210
// indent-tabs-mode: nil
211211
// c-basic-offset: 4
212212
// buffer-file-coding-system: utf-8-unix
213-
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
214213
// End:
215214
//
216215

src/rt/test/rust_test_runtime.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ rust_domain_test::run() {
3939
return true;
4040
}
4141

42-
void task_entry(void *, rust_boxed_closure *, void *) {
42+
void task_entry(void *, rust_opaque_closure *, void *) {
4343
printf("task entry\n");
4444
}
4545

src/test/stdtest/task.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ fn test_join_chan_fail() {
5353

5454
#[test]
5555
fn spawn_polymorphic() {
56-
fn foo<send T>(x: T) { log(error, x); }
56+
fn foo<T:send>(x: T) { log(error, x); }
5757
task::spawn {|| foo(true);};
5858
task::spawn {|| foo(42);};
5959
}

0 commit comments

Comments
 (0)