Skip to content

Commit

Permalink
Use a faked-up function as a key, because functions aren't identical …
Browse files Browse the repository at this point in the history
…cross-crate in Windows.
  • Loading branch information
paulstansifer committed Aug 24, 2012
1 parent 0f996f7 commit aa024ac
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 10 deletions.
12 changes: 10 additions & 2 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,24 @@ fn deserialize_span<D>(_d: D) -> span {
#[auto_serialize]
type spanned<T> = {node: T, span: span};


/* can't import macros yet, so this is copied from token.rs. See its comment
* there. */
macro_rules! interner_key (
() => (unsafe::transmute::<(uint, uint), &fn(+@@token::ident_interner)>(
(-3 as uint, 0u)))
)

fn serialize_ident<S: serializer>(s: S, i: ident) {
let intr = match unsafe{task::local_data_get(parse::token::interner_key)}{
let intr = match unsafe{task::local_data_get(interner_key!())}{
none => fail ~"serialization: TLS interner not set up",
some(intr) => intr
};

s.emit_str(*(*intr).get(i));
}
fn deserialize_ident<D: deserializer>(d: D) -> ident {
let intr = match unsafe{task::local_data_get(parse::token::interner_key)}{
let intr = match unsafe{task::local_data_get(interner_key!())}{
none => fail ~"deserialization: TLS interner not set up",
some(intr) => intr
};
Expand Down
14 changes: 10 additions & 4 deletions src/libsyntax/parse/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,14 @@ mod special_idents {
type ident_interner = util::interner::interner<@~str>;

/** Key for thread-local data for sneaking interner information to the
* serializer/deserializer. It sounds like a hack because it is one. */
fn interner_key(+_x: @@ident_interner) { }
* serializer/deserializer. It sounds like a hack because it is one.
* Bonus ultra-hack: functions as keys don't work across crates,
* so we have to use a unique number. See taskgroup_key! in task.rs
* for another case of this. */
macro_rules! interner_key (
() => (unsafe::transmute::<(uint, uint), &fn(+@@token::ident_interner)>(
(-3 as uint, 0u)))
)

fn mk_ident_interner() -> ident_interner {
/* the indices here must correspond to the numbers in special_idents */
Expand All @@ -343,8 +349,8 @@ fn mk_ident_interner() -> ident_interner {
|x,y| str::eq(*x, *y), init_vec);

/* having multiple interners will just confuse the serializer */
unsafe{ assert task::local_data_get(interner_key) == none };
unsafe{ task::local_data_set(interner_key, @rv) };
unsafe{ assert task::local_data_get(interner_key!()) == none };
unsafe{ task::local_data_set(interner_key!(), @rv) };
rv
}

Expand Down
14 changes: 10 additions & 4 deletions src/rustdoc/extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,24 @@ import doc::item_utils;

export from_srv, extract, to_str, interner;


/* can't import macros yet, so this is copied from token.rs. See its comment
* there. */
macro_rules! interner_key (
() => (unsafe::transmute::<(uint, uint),
&fn(+@@syntax::parse::token::ident_interner)>((-3 as uint, 0u)))
)

// Hack; rather than thread an interner through everywhere, rely on
// thread-local data
fn to_str(id: ast::ident) -> ~str {
let intr = unsafe{ task::local_data_get(
syntax::parse::token::interner_key) };
let intr = unsafe{ task::local_data_get(interner_key!()) };

return *(*intr.get()).get(id);
}

fn interner() -> syntax::parse::token::ident_interner {
return *(unsafe{ task::local_data_get(
syntax::parse::token::interner_key) }).get();
return *(unsafe{ task::local_data_get(interner_key!()) }).get();
}

fn from_srv(
Expand Down

0 comments on commit aa024ac

Please sign in to comment.