Skip to content

Commit b95c72d

Browse files
authored
Merge pull request rust-lang#76 from OlegTheCat/fix-example
Fix detection of extern functions defined in Rust
2 parents 63a9cf2 + d51e410 commit b95c72d

File tree

1 file changed

+21
-15
lines changed

1 file changed

+21
-15
lines changed

examples/kaleidoscope/main.rs

+21-15
Original file line numberDiff line numberDiff line change
@@ -286,11 +286,11 @@ pub struct Prototype {
286286
pub prec: usize
287287
}
288288

289-
/// Defines a user-defined function.
289+
/// Defines a user-defined or external function.
290290
#[derive(Debug)]
291291
pub struct Function {
292292
pub prototype: Prototype,
293-
pub body: Expr,
293+
pub body: Option<Expr>,
294294
pub is_anon: bool
295295
}
296296

@@ -502,7 +502,7 @@ impl<'a> Parser<'a> {
502502
// Return new function
503503
Ok(Function {
504504
prototype: proto,
505-
body: body,
505+
body: Some(body),
506506
is_anon: false
507507
})
508508
}
@@ -515,10 +515,9 @@ impl<'a> Parser<'a> {
515515
// Parse signature of extern function
516516
let proto = self.parse_prototype()?;
517517

518-
// Return signature of extern function
519518
Ok(Function {
520519
prototype: proto,
521-
body: Expr::Number(std::f64::NAN),
520+
body: None,
522521
is_anon: false
523522
})
524523
}
@@ -820,8 +819,9 @@ impl<'a> Parser<'a> {
820819
args: vec![],
821820
is_op: false,
822821
prec: 0
822+
823823
},
824-
body: expr,
824+
body: Some(expr),
825825
is_anon: true
826826
})
827827
},
@@ -1114,6 +1114,12 @@ impl<'a> Compiler<'a> {
11141114
fn compile_fn(&mut self) -> Result<FunctionValue, &'static str> {
11151115
let proto = &self.function.prototype;
11161116
let function = self.compile_prototype(proto)?;
1117+
1118+
// got external function, returning only compiled prototype
1119+
if self.function.body.is_none() {
1120+
return Ok(function);
1121+
}
1122+
11171123
let entry = self.context.append_basic_block(&function, "entry");
11181124

11191125
self.builder.position_at_end(&entry);
@@ -1134,7 +1140,7 @@ impl<'a> Compiler<'a> {
11341140
}
11351141

11361142
// compile body
1137-
let body = self.compile_expr(&self.function.body)?;
1143+
let body = self.compile_expr(self.function.body.as_ref().unwrap())?;
11381144

11391145
self.builder.build_return(Some(&body));
11401146

@@ -1183,24 +1189,24 @@ macro_rules! print_flush {
11831189
};
11841190
}
11851191

1186-
// Greg <6A>: 2017-10-03
1187-
// The two following functions are supposed to be found by the JIT
1188-
// using the 'extern' keyword, but it currently does not work on my machine.
1189-
// I tried using add_symbol, add_global_mapping, and simple extern declaration,
1190-
// but nothing worked.
1191-
// However, extern functions such as cos(x) and sin(x) can be imported without any problem.
1192-
// Other lines related to this program can be found further down.
1193-
1192+
#[no_mangle]
11941193
pub extern fn putchard(x: f64) -> f64 {
11951194
print_flush!("{}", x as u8 as char);
11961195
x
11971196
}
11981197

1198+
#[no_mangle]
11991199
pub extern fn printd(x: f64) -> f64 {
12001200
println!("{}", x);
12011201
x
1202+
12021203
}
12031204

1205+
// Adding the functions above to a global array,
1206+
// so Rust compiler won't remove them.
1207+
#[used]
1208+
static EXTERNAL_FNS: [extern fn(f64) -> f64; 2] = [putchard, printd];
1209+
12041210
/// Entry point of the program; acts as a REPL.
12051211
pub fn main() {
12061212
// use self::inkwell::support::add_symbol;

0 commit comments

Comments
 (0)