Skip to content

Commit 562f82d

Browse files
committed
---
yaml --- r: 145175 b: refs/heads/try2 c: 66ecff2 h: refs/heads/master i: 145173: 1d7e620 145171: 4ddb94c 145167: f5e89a0 v: v3
1 parent 2b54278 commit 562f82d

File tree

18 files changed

+511
-268
lines changed

18 files changed

+511
-268
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: 4c49a3d8cd00489e62ab7398d05285361039ef13
8+
refs/heads/try2: 66ecff2b136dccabae98d2413632ff5177313205
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libextra/json.rs

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

@@ -947,14 +950,20 @@ impl serialize::Decoder for Decoder {
947950
debug!("read_enum_variant(names=%?)", names);
948951
let name = match self.stack.pop() {
949952
String(s) => s,
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),
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")
957965
}
966+
n
958967
}
959968
ref json => fail!("invalid variant: %?", *json),
960969
};
@@ -1517,7 +1526,7 @@ mod tests {
15171526
let mut encoder = Encoder(wr);
15181527
animal.encode(&mut encoder);
15191528
},
1520-
~"[\"Frog\",\"Henry\",349]"
1529+
~"{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"
15211530
);
15221531
assert_eq!(
15231532
do io::with_str_writer |wr| {
@@ -1921,14 +1930,14 @@ mod tests {
19211930
assert_eq!(value, Dog);
19221931

19231932
let mut decoder =
1924-
Decoder(from_str("[\"Frog\",\"Henry\",349]").unwrap());
1933+
Decoder(from_str("{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}").unwrap());
19251934
let value: Animal = Decodable::decode(&mut decoder);
19261935
assert_eq!(value, Frog(~"Henry", 349));
19271936
}
19281937
19291938
#[test]
19301939
fn test_decode_map() {
1931-
let s = ~"{\"a\": \"Dog\", \"b\": [\"Frog\", \"Henry\", 349]}";
1940+
let s = ~"{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\"fields\":[\"Henry\", 349]}}";
19321941
let mut decoder = Decoder(from_str(s).unwrap());
19331942
let mut map: TreeMap<~str, Animal> = Decodable::decode(&mut decoder);
19341943

branches/try2/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/try2/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)