fix how we walk functions to match new closure fmt
This commit is contained in:
parent
8e89df69de
commit
8506241f3a
52
mk/target.mk
52
mk/target.mk
@ -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)))))
|
||||
|
@ -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])),
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "rust_internal.h"
|
||||
#include "rust_util.h"
|
||||
#include <cstdio>
|
||||
|
||||
struct
|
||||
|
@ -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();
|
||||
|
@ -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:
|
||||
//
|
||||
|
||||
|
@ -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:
|
||||
//
|
||||
|
@ -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:
|
||||
//
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "rust_scheduler.h"
|
||||
#include "rust_unwind.h"
|
||||
#include "rust_upcall.h"
|
||||
#include "rust_util.h"
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
@ -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:
|
||||
//
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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);};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user