Skip to content

Commit f5c35c8

Browse files
committed
---
yaml --- r: 80871 b: refs/heads/try c: 1afaf0b h: refs/heads/master i: 80869: 24a86f1 80867: f2bdc6d 80863: 6ff3c8f v: v3
1 parent e7c5136 commit f5c35c8

File tree

20 files changed

+643
-155
lines changed

20 files changed

+643
-155
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 4c6bf4872012c010f84dc7fa2cdfe87522533f89
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: cbd1eefbd350797b783df119fed7956d7e1c74ad
5-
refs/heads/try: bb4d4d7eb9e7a3abe3dc2fd26ad62408d83ed036
5+
refs/heads/try: 1afaf0b308618c7c33fb13684105e98671b82c4b
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/libextra/json.rs

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -135,21 +135,18 @@ impl serialize::Encoder for Encoder {
135135
_id: uint,
136136
cnt: uint,
137137
f: &fn(&mut Encoder)) {
138-
// enums are encoded as strings or objects
138+
// enums are encoded as strings or vectors:
139139
// Bunny => "Bunny"
140-
// Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]}
140+
// Kangaroo(34,"William") => ["Kangaroo",[34,"William"]]
141+
141142
if cnt == 0 {
142143
self.wr.write_str(escape_str(name));
143144
} else {
144-
self.wr.write_char('{');
145-
self.wr.write_str("\"variant\"");
146-
self.wr.write_char(':');
145+
self.wr.write_char('[');
147146
self.wr.write_str(escape_str(name));
148147
self.wr.write_char(',');
149-
self.wr.write_str("\"fields\"");
150-
self.wr.write_str(":[");
151148
f(self);
152-
self.wr.write_str("]}");
149+
self.wr.write_char(']');
153150
}
154151
}
155152

@@ -950,20 +947,14 @@ impl serialize::Decoder for Decoder {
950947
debug!("read_enum_variant(names=%?)", names);
951948
let name = match self.stack.pop() {
952949
String(s) => s,
953-
Object(o) => {
954-
let n = match o.find(&~"variant").expect("invalidly encoded json") {
955-
&String(ref s) => s.clone(),
956-
_ => fail!("invalidly encoded json"),
957-
};
958-
match o.find(&~"fields").expect("invalidly encoded json") {
959-
&List(ref l) => {
960-
for field in l.rev_iter() {
961-
self.stack.push(field.clone());
962-
}
963-
},
964-
_ => fail!("invalidly encoded json")
950+
List(list) => {
951+
for v in list.move_rev_iter() {
952+
self.stack.push(v);
953+
}
954+
match self.stack.pop() {
955+
String(s) => s,
956+
value => fail!("invalid variant name: %?", value),
965957
}
966-
n
967958
}
968959
ref json => fail!("invalid variant: %?", *json),
969960
};
@@ -1526,7 +1517,7 @@ mod tests {
15261517
let mut encoder = Encoder(wr);
15271518
animal.encode(&mut encoder);
15281519
},
1529-
~"{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"
1520+
~"[\"Frog\",\"Henry\",349]"
15301521
);
15311522
assert_eq!(
15321523
do io::with_str_writer |wr| {
@@ -1930,14 +1921,14 @@ mod tests {
19301921
assert_eq!(value, Dog);
19311922

19321923
let mut decoder =
1933-
Decoder(from_str("{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}").unwrap());
1924+
Decoder(from_str("[\"Frog\",\"Henry\",349]").unwrap());
19341925
let value: Animal = Decodable::decode(&mut decoder);
19351926
assert_eq!(value, Frog(~"Henry", 349));
19361927
}
19371928
19381929
#[test]
19391930
fn test_decode_map() {
1940-
let s = ~"{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\"fields\":[\"Henry\", 349]}}";
1931+
let s = ~"{\"a\": \"Dog\", \"b\": [\"Frog\", \"Henry\", 349]}";
19411932
let mut decoder = Decoder(from_str(s).unwrap());
19421933
let mut map: TreeMap<~str, Animal> = Decodable::decode(&mut decoder);
19431934

branches/try/src/librustc/middle/trans/base.rs

Lines changed: 109 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ impl<'self> Drop for StatRecorder<'self> {
174174
}
175175
}
176176

177+
// only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
177178
pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type) -> ValueRef {
178179
let llfn: ValueRef = do name.with_c_str |buf| {
179180
unsafe {
@@ -185,18 +186,12 @@ pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type)
185186
return llfn;
186187
}
187188

189+
// only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
188190
pub fn decl_cdecl_fn(llmod: ModuleRef, name: &str, ty: Type) -> ValueRef {
189191
return decl_fn(llmod, name, lib::llvm::CCallConv, ty);
190192
}
191193

192-
// Only use this if you are going to actually define the function. It's
193-
// not valid to simply declare a function as internal.
194-
pub fn decl_internal_cdecl_fn(llmod: ModuleRef, name: &str, ty: Type) -> ValueRef {
195-
let llfn = decl_cdecl_fn(llmod, name, ty);
196-
lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
197-
return llfn;
198-
}
199-
194+
// only use this for foreign function ABIs and glue, use `get_extern_rust_fn` for Rust functions
200195
pub fn get_extern_fn(externs: &mut ExternMap, llmod: ModuleRef, name: &str,
201196
cc: lib::llvm::CallConv, ty: Type) -> ValueRef {
202197
match externs.find_equiv(&name) {
@@ -205,7 +200,73 @@ pub fn get_extern_fn(externs: &mut ExternMap, llmod: ModuleRef, name: &str,
205200
}
206201
let f = decl_fn(llmod, name, cc, ty);
207202
externs.insert(name.to_owned(), f);
208-
return f;
203+
f
204+
}
205+
206+
pub fn get_extern_rust_fn(ccx: &mut CrateContext, inputs: &[ty::t], output: ty::t,
207+
name: &str) -> ValueRef {
208+
match ccx.externs.find_equiv(&name) {
209+
Some(n) => return *n,
210+
None => ()
211+
}
212+
let f = decl_rust_fn(ccx, inputs, output, name);
213+
ccx.externs.insert(name.to_owned(), f);
214+
f
215+
}
216+
217+
pub fn decl_rust_fn(ccx: &mut CrateContext, inputs: &[ty::t], output: ty::t,
218+
name: &str) -> ValueRef {
219+
let llfty = type_of_rust_fn(ccx, inputs, output);
220+
let llfn = decl_cdecl_fn(ccx.llmod, name, llfty);
221+
222+
match ty::get(output).sty {
223+
// `~` pointer return values never alias because ownership is transferred
224+
ty::ty_uniq(*) |
225+
ty::ty_evec(_, ty::vstore_uniq) => {
226+
unsafe {
227+
llvm::LLVMAddReturnAttribute(llfn, lib::llvm::NoAliasAttribute as c_uint);
228+
}
229+
}
230+
_ => ()
231+
}
232+
233+
let uses_outptr = type_of::return_uses_outptr(ccx.tcx, output);
234+
let offset = if uses_outptr { 2 } else { 1 };
235+
236+
for (i, &arg_ty) in inputs.iter().enumerate() {
237+
let llarg = unsafe { llvm::LLVMGetParam(llfn, (offset + i) as c_uint) };
238+
match ty::get(arg_ty).sty {
239+
// `~` pointer parameters never alias because ownership is transferred
240+
ty::ty_uniq(*) |
241+
ty::ty_evec(_, ty::vstore_uniq) |
242+
ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) => {
243+
unsafe {
244+
llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
245+
}
246+
}
247+
_ => ()
248+
}
249+
}
250+
251+
// The out pointer will never alias with any other pointers, as the object only exists at a
252+
// language level after the call. It can also be tagged with SRet to indicate that it is
253+
// guaranteed to point to a usable block of memory for the type.
254+
if uses_outptr {
255+
unsafe {
256+
let outptr = llvm::LLVMGetParam(llfn, 0);
257+
llvm::LLVMAddAttribute(outptr, lib::llvm::StructRetAttribute as c_uint);
258+
llvm::LLVMAddAttribute(outptr, lib::llvm::NoAliasAttribute as c_uint);
259+
}
260+
}
261+
262+
llfn
263+
}
264+
265+
pub fn decl_internal_rust_fn(ccx: &mut CrateContext, inputs: &[ty::t], output: ty::t,
266+
name: &str) -> ValueRef {
267+
let llfn = decl_rust_fn(ccx, inputs, output, name);
268+
lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
269+
llfn
209270
}
210271

211272
pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef,
@@ -809,33 +870,30 @@ pub fn null_env_ptr(ccx: &CrateContext) -> ValueRef {
809870
C_null(Type::opaque_box(ccx).ptr_to())
810871
}
811872
812-
pub fn trans_external_path(ccx: &mut CrateContext, did: ast::DefId, t: ty::t)
813-
-> ValueRef {
873+
pub fn trans_external_path(ccx: &mut CrateContext, did: ast::DefId, t: ty::t) -> ValueRef {
814874
let name = csearch::get_symbol(ccx.sess.cstore, did);
815875
match ty::get(t).sty {
816876
ty::ty_bare_fn(ref fn_ty) => {
817-
// Currently llvm_calling_convention triggers unimpl/bug on
818-
// Rust/RustIntrinsic, so those two are handled specially here.
819-
let cconv = match fn_ty.abis.for_arch(ccx.sess.targ_cfg.arch) {
820-
Some(Rust) | Some(RustIntrinsic) => lib::llvm::CCallConv,
877+
match fn_ty.abis.for_arch(ccx.sess.targ_cfg.arch) {
878+
Some(Rust) | Some(RustIntrinsic) => {
879+
get_extern_rust_fn(ccx, fn_ty.sig.inputs, fn_ty.sig.output, name)
880+
}
821881
Some(*) | None => {
822882
let c = foreign::llvm_calling_convention(ccx, fn_ty.abis);
823-
c.unwrap_or(lib::llvm::CCallConv)
883+
let cconv = c.unwrap_or(lib::llvm::CCallConv);
884+
let llty = type_of_fn_from_ty(ccx, t);
885+
get_extern_fn(&mut ccx.externs, ccx.llmod, name, cconv, llty)
824886
}
825-
};
826-
let llty = type_of_fn_from_ty(ccx, t);
827-
return get_extern_fn(&mut ccx.externs, ccx.llmod, name, cconv, llty);
887+
}
828888
}
829-
ty::ty_closure(_) => {
830-
let llty = type_of_fn_from_ty(ccx, t);
831-
return get_extern_fn(&mut ccx.externs, ccx.llmod, name,
832-
lib::llvm::CCallConv, llty);
889+
ty::ty_closure(ref f) => {
890+
get_extern_rust_fn(ccx, f.sig.inputs, f.sig.output, name)
833891
}
834892
_ => {
835893
let llty = type_of(ccx, t);
836-
return get_extern_const(&mut ccx.externs, ccx.llmod, name, llty);
894+
get_extern_const(&mut ccx.externs, ccx.llmod, name, llty)
837895
}
838-
};
896+
}
839897
}
840898
841899
pub fn invoke(bcx: @mut Block, llfn: ValueRef, llargs: ~[ValueRef],
@@ -868,7 +926,8 @@ pub fn invoke(bcx: @mut Block, llfn: ValueRef, llargs: ~[ValueRef],
868926
llfn,
869927
llargs,
870928
normal_bcx.llbb,
871-
get_landing_pad(bcx));
929+
get_landing_pad(bcx),
930+
attributes);
872931
return (llresult, normal_bcx);
873932
} else {
874933
unsafe {
@@ -1707,8 +1766,7 @@ pub fn new_fn_ctxt(ccx: @mut CrateContext,
17071766
// field of the fn_ctxt with
17081767
pub fn create_llargs_for_fn_args(cx: @mut FunctionContext,
17091768
self_arg: self_arg,
1710-
args: &[ast::arg],
1711-
arg_tys: &[ty::t])
1769+
args: &[ast::arg])
17121770
-> ~[ValueRef] {
17131771
let _icx = push_ctxt("create_llargs_for_fn_args");
17141772

@@ -1726,23 +1784,7 @@ pub fn create_llargs_for_fn_args(cx: @mut FunctionContext,
17261784
// Return an array containing the ValueRefs that we get from
17271785
// llvm::LLVMGetParam for each argument.
17281786
do vec::from_fn(args.len()) |i| {
1729-
let arg_n = cx.arg_pos(i);
1730-
let arg_ty = arg_tys[i];
1731-
let llarg = unsafe {llvm::LLVMGetParam(cx.llfn, arg_n as c_uint) };
1732-
1733-
match ty::get(arg_ty).sty {
1734-
// `~` pointer parameters never alias because ownership is transferred
1735-
ty::ty_uniq(*) |
1736-
ty::ty_evec(_, ty::vstore_uniq) |
1737-
ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) => {
1738-
unsafe {
1739-
llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
1740-
}
1741-
}
1742-
_ => ()
1743-
}
1744-
1745-
llarg
1787+
unsafe { llvm::LLVMGetParam(cx.llfn, cx.arg_pos(i) as c_uint) }
17461788
}
17471789
}
17481790

@@ -1896,8 +1938,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
18961938

18971939
// Set up arguments to the function.
18981940
let arg_tys = ty::ty_fn_args(node_id_type(bcx, id));
1899-
let raw_llargs = create_llargs_for_fn_args(fcx, self_arg,
1900-
decl.inputs, arg_tys);
1941+
let raw_llargs = create_llargs_for_fn_args(fcx, self_arg, decl.inputs);
19011942

19021943
// Set the fixed stack segment flag if necessary.
19031944
if attr::contains_name(attributes, "fixed_stack_segment") {
@@ -1961,18 +2002,6 @@ pub fn trans_fn(ccx: @mut CrateContext,
19612002
param_substs.repr(ccx.tcx));
19622003
let _icx = push_ctxt("trans_fn");
19632004
let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id));
1964-
1965-
match ty::get(output_type).sty {
1966-
// `~` pointer return values never alias because ownership is transferred
1967-
ty::ty_uniq(*) |
1968-
ty::ty_evec(_, ty::vstore_uniq) => {
1969-
unsafe {
1970-
llvm::LLVMAddReturnAttribute(llfndecl, lib::llvm::NoAliasAttribute as c_uint);
1971-
}
1972-
}
1973-
_ => ()
1974-
}
1975-
19762005
trans_closure(ccx,
19772006
path.clone(),
19782007
decl,
@@ -2120,7 +2149,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
21202149

21212150
let arg_tys = ty::ty_fn_args(ctor_ty);
21222151

2123-
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args, arg_tys);
2152+
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args);
21242153

21252154
let bcx = fcx.entry_bcx.unwrap();
21262155

@@ -2298,10 +2327,28 @@ pub fn register_fn(ccx: @mut CrateContext,
22982327
node_id: ast::NodeId,
22992328
node_type: ty::t)
23002329
-> ValueRef {
2301-
let llfty = type_of_fn_from_ty(ccx, node_type);
2302-
register_fn_llvmty(ccx, sp, sym, node_id, lib::llvm::CCallConv, llfty)
2330+
let f = match ty::get(node_type).sty {
2331+
ty::ty_bare_fn(ref f) => {
2332+
assert!(f.abis.is_rust() || f.abis.is_intrinsic());
2333+
f
2334+
}
2335+
_ => fail!("expected bare rust fn or an intrinsic")
2336+
};
2337+
2338+
let llfn = decl_rust_fn(ccx, f.sig.inputs, f.sig.output, sym);
2339+
ccx.item_symbols.insert(node_id, sym);
2340+
2341+
// FIXME #4404 android JNI hacks
2342+
let is_entry = is_entry_fn(&ccx.sess, node_id) && (!*ccx.sess.building_library ||
2343+
(*ccx.sess.building_library &&
2344+
ccx.sess.targ_cfg.os == session::OsAndroid));
2345+
if is_entry {
2346+
create_entry_wrapper(ccx, sp, llfn);
2347+
}
2348+
llfn
23032349
}
23042350

2351+
// only use this for foreign function ABIs and glue, use `register_fn` for Rust functions
23052352
pub fn register_fn_llvmty(ccx: @mut CrateContext,
23062353
sp: Span,
23072354
sym: ~str,

branches/try/src/librustc/middle/trans/build.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ pub fn Invoke(cx: @mut Block,
109109
Fn: ValueRef,
110110
Args: &[ValueRef],
111111
Then: BasicBlockRef,
112-
Catch: BasicBlockRef)
112+
Catch: BasicBlockRef,
113+
attributes: &[(uint, lib::llvm::Attribute)])
113114
-> ValueRef {
114115
if cx.unreachable {
115116
return C_null(Type::i8());
@@ -119,15 +120,7 @@ pub fn Invoke(cx: @mut Block,
119120
debug!("Invoke(%s with arguments (%s))",
120121
cx.val_to_str(Fn),
121122
Args.map(|a| cx.val_to_str(*a)).connect(", "));
122-
B(cx).invoke(Fn, Args, Then, Catch)
123-
}
124-
125-
pub fn FastInvoke(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef],
126-
Then: BasicBlockRef, Catch: BasicBlockRef) {
127-
if cx.unreachable { return; }
128-
check_not_terminated(cx);
129-
terminate(cx, "FastInvoke");
130-
B(cx).fast_invoke(Fn, Args, Then, Catch);
123+
B(cx).invoke(Fn, Args, Then, Catch, attributes)
131124
}
132125

133126
pub fn Unreachable(cx: @mut Block) {

0 commit comments

Comments
 (0)