fix how we walk functions to match new closure fmt
This commit is contained in:
parent
8e89df69de
commit
8506241f3a
15 changed files with 104 additions and 67 deletions
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: $$@)
|
@$$(call E, compile_and_link: $$@)
|
||||||
$$(STAGE$(1)_T_$(2)_H_$(3)) --lib -o $$@ $$< && touch $$@
|
$$(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): \
|
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_RUSTLLVM): \
|
||||||
rustllvm/$(2)/$$(CFG_RUSTLLVM)
|
rustllvm/$(2)/$$(CFG_RUSTLLVM)
|
||||||
@$$(call E, cp: $$@)
|
@$$(call E, cp: $$@)
|
||||||
|
@ -62,10 +57,49 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC): \
|
||||||
|
|
||||||
endef
|
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:
|
# In principle, each host can build each target:
|
||||||
$(foreach source,$(CFG_TARGET_TRIPLES), \
|
$(foreach source,$(CFG_TARGET_TRIPLES), \
|
||||||
$(foreach target,$(CFG_TARGET_TRIPLES), \
|
$(foreach target,$(CFG_TARGET_TRIPLES), \
|
||||||
$(eval $(call TARGET_STAGE_N,0,$(source),$(target))) \
|
$(eval $(call TARGET_STAGE_N,0,$(target),$(source))) \
|
||||||
$(eval $(call TARGET_STAGE_N,1,$(source),$(target))) \
|
$(eval $(call TARGET_STAGE_N,1,$(target),$(source))) \
|
||||||
$(eval $(call TARGET_STAGE_N,2,$(source),$(target))) \
|
$(eval $(call TARGET_STAGE_N,2,$(target),$(source))) \
|
||||||
$(eval $(call TARGET_STAGE_N,3,$(source),$(target)))))
|
$(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 {
|
-> @block_ctxt {
|
||||||
// Easy cases:
|
// Easy cases:
|
||||||
alt ck {
|
alt ck {
|
||||||
ty::closure_block. { ret bcx; }
|
ty::closure_block. {
|
||||||
ty::closure_shared. { ret incr_refcnt_of_boxed(bcx, Load(bcx, cboxptr)); }
|
ret bcx;
|
||||||
|
}
|
||||||
|
ty::closure_shared. {
|
||||||
|
ret incr_refcnt_of_boxed(bcx, Load(bcx, cboxptr));
|
||||||
|
}
|
||||||
ty::closure_send. { /* hard case: */ }
|
ty::closure_send. { /* hard case: */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,7 +862,8 @@ fn trans_bind_thunk(cx: @local_ctxt,
|
||||||
// Copy in the type parameters.
|
// Copy in the type parameters.
|
||||||
check type_is_tup_like(l_bcx, cboxptr_ty);
|
check type_is_tup_like(l_bcx, cboxptr_ty);
|
||||||
let {bcx: l_bcx, val: param_record} =
|
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;
|
let off = 0;
|
||||||
for param in param_bounds {
|
for param in param_bounds {
|
||||||
let dsc = Load(l_bcx, GEPi(l_bcx, param_record, [0, off])),
|
let dsc = Load(l_bcx, GEPi(l_bcx, param_record, [0, off])),
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "rust_internal.h"
|
#include "rust_internal.h"
|
||||||
|
#include "rust_util.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "rust_internal.h"
|
#include "rust_internal.h"
|
||||||
#include "rust_scheduler.h"
|
#include "rust_scheduler.h"
|
||||||
#include "rust_task.h"
|
#include "rust_task.h"
|
||||||
|
#include "rust_util.h"
|
||||||
|
|
||||||
#if !defined(__WIN32__)
|
#if !defined(__WIN32__)
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -420,11 +421,6 @@ rust_get_task() {
|
||||||
return rust_scheduler::get_task();
|
return rust_scheduler::get_task();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fn_env_pair {
|
|
||||||
spawn_fn f;
|
|
||||||
rust_boxed_closure *env;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" CDECL void
|
extern "C" CDECL void
|
||||||
start_task(rust_task_id id, fn_env_pair *f) {
|
start_task(rust_task_id id, fn_env_pair *f) {
|
||||||
rust_task *task = rust_scheduler::get_task();
|
rust_task *task = rust_scheduler::get_task();
|
||||||
|
|
|
@ -241,8 +241,6 @@ struct rust_timer {
|
||||||
~rust_timer();
|
~rust_timer();
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "rust_util.h"
|
|
||||||
|
|
||||||
typedef void CDECL (glue_fn)(void *, void *,
|
typedef void CDECL (glue_fn)(void *, void *,
|
||||||
const type_desc **, void *);
|
const type_desc **, void *);
|
||||||
typedef void CDECL (cmp_glue_fn)(void *, void *,
|
typedef void CDECL (cmp_glue_fn)(void *, void *,
|
||||||
|
@ -254,6 +252,30 @@ struct rust_shape_tables {
|
||||||
uint8_t *resources;
|
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 {
|
struct type_desc {
|
||||||
// First part of type_desc is known to compiler.
|
// First part of type_desc is known to compiler.
|
||||||
// first_param = &descs[1] if dynamic, null if static.
|
// 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
|
// indent-tabs-mode: nil
|
||||||
// c-basic-offset: 4
|
// c-basic-offset: 4
|
||||||
// buffer-file-coding-system: utf-8-unix
|
// buffer-file-coding-system: utf-8-unix
|
||||||
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
|
||||||
// End:
|
// End:
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "rust_internal.h"
|
#include "rust_internal.h"
|
||||||
|
#include "rust_util.h"
|
||||||
|
|
||||||
#define KLOG_(...) \
|
#define KLOG_(...) \
|
||||||
KLOG(this, kern, __VA_ARGS__)
|
KLOG(this, kern, __VA_ARGS__)
|
||||||
|
@ -216,6 +217,5 @@ rust_kernel::win32_require(LPCTSTR fn, BOOL ok) {
|
||||||
// indent-tabs-mode: nil
|
// indent-tabs-mode: nil
|
||||||
// c-basic-offset: 4
|
// c-basic-offset: 4
|
||||||
// buffer-file-coding-system: utf-8-unix
|
// buffer-file-coding-system: utf-8-unix
|
||||||
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
|
||||||
// End:
|
// End:
|
||||||
//
|
//
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "rust_internal.h"
|
#include "rust_internal.h"
|
||||||
|
#include "rust_util.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
@ -414,6 +415,5 @@ rust_scheduler::get_task() {
|
||||||
// indent-tabs-mode: nil
|
// indent-tabs-mode: nil
|
||||||
// c-basic-offset: 4
|
// c-basic-offset: 4
|
||||||
// buffer-file-coding-system: utf-8-unix
|
// buffer-file-coding-system: utf-8-unix
|
||||||
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
|
||||||
// End:
|
// 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,
|
// Constructs type parameters from a function shape. This is a bit messy,
|
||||||
// because it requires that the function shape have a specific format.
|
// because it requires that the function shape have a specific format.
|
||||||
type_param *
|
type_param *
|
||||||
type_param::from_fn_shape(const uint8_t *sp, ptr dp, arena &arena) {
|
type_param::from_fn_shape(rust_opaque_closure *env, arena &arena) {
|
||||||
const type_desc *tydesc = bump_dp<const type_desc *>(dp);
|
unsigned n_tydescs = env->td->n_obj_params & 0x7fffffff;
|
||||||
const type_desc **tydescs = (const type_desc **)dp;
|
return make(env->captured_tds, n_tydescs, arena);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs type parameters from an object shape. This is also a bit messy,
|
// Constructs type parameters from an object shape. This is also a bit messy,
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "rust_internal.h"
|
#include "rust_internal.h"
|
||||||
|
#include "rust_util.h"
|
||||||
|
|
||||||
// ISAAC pollutes our namespace.
|
// ISAAC pollutes our namespace.
|
||||||
#undef align
|
#undef align
|
||||||
|
@ -300,7 +301,7 @@ public:
|
||||||
const type_param *params; // subparameters
|
const type_param *params; // subparameters
|
||||||
|
|
||||||
// Constructs type parameters from a function shape.
|
// 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.
|
// Creates type parameters from an object shape description.
|
||||||
static type_param *from_obj_shape(const uint8_t *sp, ptr dp,
|
static type_param *from_obj_shape(const uint8_t *sp, ptr dp,
|
||||||
arena &arena);
|
arena &arena);
|
||||||
|
@ -952,23 +953,17 @@ data<T,U>::walk_tag(tag_info &tinfo) {
|
||||||
template<typename T,typename U>
|
template<typename T,typename U>
|
||||||
void
|
void
|
||||||
data<T,U>::walk_fn_contents(ptr &dp) {
|
data<T,U>::walk_fn_contents(ptr &dp) {
|
||||||
dp += sizeof(void *); // Skip over the code pointer.
|
fn_env_pair pair = bump_dp<fn_env_pair>(dp);
|
||||||
|
if (!pair.env)
|
||||||
uint8_t *box_ptr = bump_dp<uint8_t *>(dp);
|
|
||||||
if (!box_ptr)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
type_desc *subtydesc =
|
|
||||||
*reinterpret_cast<type_desc **>(box_ptr + sizeof(void *));
|
|
||||||
ptr closure_dp(box_ptr + sizeof(void *));
|
|
||||||
|
|
||||||
arena arena;
|
arena arena;
|
||||||
type_param *params = type_param::from_fn_shape(subtydesc->shape,
|
type_param *params =
|
||||||
closure_dp, arena);
|
type_param::from_fn_shape(pair.env, arena);
|
||||||
|
const type_desc *closure_td = pair.env->td;
|
||||||
closure_dp += sizeof(void *);
|
ptr closure_dp((uintptr_t)pair.env);
|
||||||
T sub(*static_cast<T *>(this), subtydesc->shape, params,
|
T sub(*static_cast<T *>(this), closure_td->shape, params,
|
||||||
subtydesc->shape_tables, closure_dp);
|
closure_td->shape_tables, closure_dp);
|
||||||
sub.align = true;
|
sub.align = true;
|
||||||
sub.walk();
|
sub.walk();
|
||||||
}
|
}
|
||||||
|
|
|
@ -293,7 +293,7 @@ rust_task::~rust_task()
|
||||||
struct spawn_args {
|
struct spawn_args {
|
||||||
rust_task *task;
|
rust_task *task;
|
||||||
spawn_fn f;
|
spawn_fn f;
|
||||||
rust_boxed_closure *envptr;
|
rust_opaque_closure *envptr;
|
||||||
void *argptr;
|
void *argptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -347,12 +347,13 @@ void task_start_wrapper(spawn_args *a)
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
rust_boxed_closure* boxed_env = (rust_boxed_closure*)a->envptr;
|
rust_opaque_closure* env = a->envptr;
|
||||||
if(boxed_env) {
|
if(env) {
|
||||||
// free the environment.
|
// free the environment.
|
||||||
const type_desc *td = boxed_env->closure.td;
|
const type_desc *td = env->td;
|
||||||
td->drop_glue(NULL, NULL, td->first_param, &boxed_env->closure);
|
LOG(task, task, "Freeing env %p with td %p", env, td);
|
||||||
upcall_shared_free(boxed_env);
|
td->drop_glue(NULL, NULL, td->first_param, env);
|
||||||
|
upcall_shared_free(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The cleanup work needs lots of stack
|
// The cleanup work needs lots of stack
|
||||||
|
@ -364,7 +365,7 @@ void task_start_wrapper(spawn_args *a)
|
||||||
|
|
||||||
void
|
void
|
||||||
rust_task::start(spawn_fn spawnee_fn,
|
rust_task::start(spawn_fn spawnee_fn,
|
||||||
rust_boxed_closure *envptr,
|
rust_opaque_closure *envptr,
|
||||||
void *argptr)
|
void *argptr)
|
||||||
{
|
{
|
||||||
LOG(this, task, "starting task from fn 0x%" PRIxPTR
|
LOG(this, task, "starting task from fn 0x%" PRIxPTR
|
||||||
|
|
|
@ -21,18 +21,6 @@ struct chan_handle {
|
||||||
rust_port_id port;
|
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 rust_box;
|
||||||
|
|
||||||
struct stk_seg {
|
struct stk_seg {
|
||||||
|
@ -145,7 +133,7 @@ rust_task : public kernel_owned<rust_task>, rust_cond
|
||||||
~rust_task();
|
~rust_task();
|
||||||
|
|
||||||
void start(spawn_fn spawnee_fn,
|
void start(spawn_fn spawnee_fn,
|
||||||
rust_boxed_closure *env,
|
rust_opaque_closure *env,
|
||||||
void *args);
|
void *args);
|
||||||
void start();
|
void start();
|
||||||
bool running();
|
bool running();
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "rust_scheduler.h"
|
#include "rust_scheduler.h"
|
||||||
#include "rust_unwind.h"
|
#include "rust_unwind.h"
|
||||||
#include "rust_upcall.h"
|
#include "rust_upcall.h"
|
||||||
|
#include "rust_util.h"
|
||||||
#include <stdint.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
|
// indent-tabs-mode: nil
|
||||||
// c-basic-offset: 4
|
// c-basic-offset: 4
|
||||||
// buffer-file-coding-system: utf-8-unix
|
// buffer-file-coding-system: utf-8-unix
|
||||||
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
|
||||||
// End:
|
// End:
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ rust_domain_test::run() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void task_entry(void *, rust_boxed_closure *, void *) {
|
void task_entry(void *, rust_opaque_closure *, void *) {
|
||||||
printf("task entry\n");
|
printf("task entry\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ fn test_join_chan_fail() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn spawn_polymorphic() {
|
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(true);};
|
||||||
task::spawn {|| foo(42);};
|
task::spawn {|| foo(42);};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue