[rust-dev] Cross-compilation with plugins is effectively dead?

2015-01-10 Thread Vladimir Pouzanov
I have some concerns related to
https://github.com/rust-lang/rust/issues/18699 and I'd like to get some
advice from the team.

Support for cross-compiling code with plugins was broken for a few months
now for anything but linux. Finally it seems to be broken for linux as well
halting all our efforts.

How important is cross-compilation support for rust at all? zinc is barely
the only embedded project based on rust but we do use plugins and macros
extensively throughout the code and we can't just stop using them,
unfortunately; so for us any breakage of plugins system is a halt. We can
deal with internal libs changing syntax but fixing up compiler itself is
not that easy.

Any chance we'll see it fixed before 1.0 hits?

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Declaring the API unsafe while keeping the internal safety checks

2015-01-02 Thread Vladimir Pouzanov
Well, strictly speaking it *is* memory safety, as it all gets down to an
unsafe volatile store. Although I think I extend the 'unsafety' a bit by
considering code that can cause CPU to halt as unsafe too.

On Fri, Jan 2, 2015 at 2:11 AM, Kevin McGuire kmcg3...@gmail.com wrote:

 Yes unsafe is primarily for memory safety. However! Your idea is good. It
 would be really good if you could have something like that. I am just not
 sure what the best way to do it is. It could be done by an attribute and
 lint with the ability to toggle it off with a module level, function level,
 or scope level second attribute, lol, possibilities are endless.

 But indeed unsafe is likely only, currently, for memory safety.

 Still I like the idea! I love the idea. I read your email earlier today
 but only shortly ago I realize what you mean.
 On Jan 1, 2015 5:17 AM, Vladimir Pouzanov farcal...@gmail.com wrote:

 I had this idea for some time and I'd like to discuss it to see if it is
 something reasonable to be proposed for rust to implement or there are
 other ways around the problem.

 Let's say I have a low level function that manipulates the hardware clock
 using some platform-specific argument. Internally this function will do an
 unsafe volatile mem write to store value in the register, but this is the
 only part of the code that is unsafe compiler-wise, whatever else is in
 there in the function is safe and I want the compiler to warn me if any
 other unsafe operation happens.

 Now, given that this function is actually unsafe in terms of its realtime
 consequences (it does not do any validation of the input for speed) I want
 to mark it as unsafe fn and make a safer wrapper for end users, while
 keeping this for the little subset of users that will need the actual speed
 benefits.

 Unfortunately, marking it unsafe will now allow any other unsafe
 operation in the body of the function, when what I wanted is just to force
 users of it to be aware of unsafety via compiler validation.

 A safe {} block could have helped me in this case. But is it a good idea
 overall?

 Some pseudo-code to illustrate

 pub unsafe fn set_clock_mode(mode: uint32) {
   // ...
   // doing some required computations
   // this code must be 'safe' for the compiler
   unsafe {
 // ...
 // writing the value to mmaped register, this one is unsafe but
 validated by programmer
   }
 }

 pub fn set_clock_mode_safe(mode: uint32) - bool {
   // ...
   // validate input
   unsafe {
 // I want this call to require unsafe block
 set_clock_mode(mode);
   }
 }

 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Problems cross-compiling to ARM9

2015-01-01 Thread Vladimir Pouzanov
FWIW, we're just disabling segmented stack in zinc for now exactly because
of the same problem. I have a patch for llvm but I didn't really push it
upstream hard enough.

On Tue, Dec 30, 2014 at 11:23 AM, Valerii Hiora valerii.hi...@gmail.com
wrote:

 Hi Tomi,

  Anyone have any idea if that's a larger problem, or simply something
  nobody has written the small handcoded ASMs needed for ARMv5 or v4?
  If latter, I might be able to wrap my head around this.

   The problem you've got is related to segmented stack support. It need
 fix on 2 levels:

 - Rust - can be relatively easy fixed by providing (or patching) a
 target and marking it as a target which doesn't support segmented
 stacks, see example [1]

Once it works you can play a bit to provide a correct implementation
 in record_sp.S and morestack.S

 - LLVM - as I remember some time ago LLVM generated a function prologue
 which uses the same instruction for any ARM device, may be that was
 patched in upstream, may be not. You can also ask Vladimir Pouzanov and
 zinc.rs [2] team, AFAIK they had the similar problem too and definitely
 have a workaround.

 [1]

 https://github.com/rust-lang/rust/blob/master/src/librustc_back/target/arm_apple_ios.rs#L33
 [2]  https://zinc.rs/

 --

   Valerii


 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Programmaticaly accessing compiler warnings

2014-11-01 Thread Vladimir Pouzanov
Hi all.

Is there any way to access compiler warnings and errors other than parsing
stdout? I'd prefer a bit more structured approach.


-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] A shiny test framework

2014-07-22 Thread Vladimir Pouzanov
I've just published a tiny test framework: shiny at
https://github.com/farcaller/shiny. It's best used with hamcrest-rust.

This library exists because I find it ugly to redefine all the
initialisation code in every test case and I can't simply move it to a
function due to problems with moving [T] out.

Here's how shiny looks:

#[cfg(test)]
mod test {
  describe!(
before_each {
  let awesome = true;
}

it is awesome {
  assert!(awesome);
}

it injects before_each into all test cases {
  let still_awesome = awesome;
  assert!(still_awesome);
}
  )
}

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] A shiny test framework

2014-07-22 Thread Vladimir Pouzanov
One note on why there's no after_each:

You cannot really make sure that the epilogue is being called, so if you
need to do anything after your test case, use RAII in before_each.


On Tue, Jul 22, 2014 at 8:10 PM, Benjamin Gudehus hasteb...@gmail.com
wrote:

 Nice to see an RSpec-like test framework and Hamcrest assertions/matchers
 for Rust!


 On Tue, Jul 22, 2014 at 9:09 PM, Ilya Dmitrichenko 
 errordevelo...@gmail.com wrote:

 Dude, that's pretty much rspec ;) sweet!
 On 22 Jul 2014 20:07, Vladimir Pouzanov farcal...@gmail.com wrote:

 I've just published a tiny test framework: shiny at
 https://github.com/farcaller/shiny. It's best used with hamcrest-rust.

 This library exists because I find it ugly to redefine all the
 initialisation code in every test case and I can't simply move it to a
 function due to problems with moving [T] out.

 Here's how shiny looks:

 #[cfg(test)]
 mod test {
   describe!(
 before_each {
   let awesome = true;
 }

 it is awesome {
   assert!(awesome);
 }

 it injects before_each into all test cases {
   let still_awesome = awesome;
   assert!(still_awesome);
 }
   )
 }

 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev





-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] What do I do if I need several muts into a struct?

2014-06-16 Thread Vladimir Pouzanov
I have a problem figuring the reasonable data access pattern for my code,
here's a brief description. I have a tree structure where each node has a
path and an optional name. Path is used to locate the node in tree
hierarchy, names are stored in a flat namespace as node aliases:

lpx17xx@mcu {
  clock {
attr = value;
  }
}

os {
  thread {
entry = start;
ref = lpx17xx;
  }
}

this tree has 4 nodes, /mcu, /mcu/clock, /os and /os/thread. /mcu is also
known as lpx17xx. I use the following structure to hold root nodes:

#[deriving(Show)]
pub struct PlatformTree {
  nodes: HashMapString, GcNode,
  named: HashMapString, GcNode,
}

Everything works fine up to the point of references. References allow some
nodes to modify other nodes. So, the first pass — I parse that snippet into
PlatformTree/Nodes struct. Second pass — I walk over the tree and for each
reference I invoke some handling code, e.g. in the handler of thread node
it might add some attribute to lpx17xx node. Which is not really possible
as it's in immutable Gc box. Also, such modifications are performed through
`named` hashmap, so I can't even store muts in `nodes`, as I still can
store only immutable pointers in `named`.

How would you solve this problem?

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Flatten a tree into HashMap, how do I pass a mut around?

2014-06-15 Thread Vladimir Pouzanov
I have a tree of Nodes where each node might have a name. I'm trying to
convert the tree into a HashMap of named nodes, but my code is getting
extremely complex due to the fact that I cannot pass mut HashMap around.

let mut named_nodes = HashMap::new();
let nodes = vec!( ... );
named_nodes = self.collect_node_names(named_nodes, nodes);
println!('{}', named_nodes);

fn collect_node_names(self, map: HashMapString, Gcnode::Node,
nodes: VecGcnode::Node) - HashMapString, Gcnode::Node {
  let mut local_map: HashMapString, Gcnode::Node = HashMap::new();
  for (k,v) in map.iter() {
local_map.insert(k.clone(), *v);
  }
  for n in nodes.iter() {
for (k,v) in self.collect_node_names(local_map, n.subnodes).iter() {
  local_map.insert(k.clone(), *v);
}
match n.name {
  Some(ref name) = {
if local_map.contains_key(name) {

} else {
  local_map.insert(name.clone(), *n);
}
  },
  None = (),
}
  }
  local_map
}

this one works, but it's bloated and slow. Any hints on how to improve the
code?

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Flatten a tree into HashMap, how do I pass a mut around?

2014-06-15 Thread Vladimir Pouzanov
After a few hints on IRC I managed to simplify it to:

fn collect_node_names(self, map: mut HashMapString, Gcnode::Node,
nodes: VecGcnode::Node) - bool {
  for n in nodes.iter() {
if !self.collect_node_names(map, n.subnodes) {
  return false;
}

match n.name {
  Some(ref name) = {
if map.contains_key(name) {
  self.sess.span_diagnostic.span_err(n.name_span, format!(
  duplicate `{}` definition, name).as_slice());

  self.sess.span_diagnostic.span_warn(
  map.get(name).name_span,
  previously defined here);
  return false;
} else {
  map.insert(name.clone(), *n);
}
  },
  None = (),
}
  }
  true
}

My failure point was that I didn't realise you cannot access mut while yo
have a reference to anything you pass mut to.


On Sun, Jun 15, 2014 at 8:14 AM, Vladimir Pouzanov farcal...@gmail.com
wrote:

 I have a tree of Nodes where each node might have a name. I'm trying to
 convert the tree into a HashMap of named nodes, but my code is getting
 extremely complex due to the fact that I cannot pass mut HashMap around.

 let mut named_nodes = HashMap::new();
 let nodes = vec!( ... );
 named_nodes = self.collect_node_names(named_nodes, nodes);
 println!('{}', named_nodes);

 fn collect_node_names(self, map: HashMapString, Gcnode::Node,
 nodes: VecGcnode::Node) - HashMapString, Gcnode::Node {
   let mut local_map: HashMapString, Gcnode::Node = HashMap::new();
   for (k,v) in map.iter() {
 local_map.insert(k.clone(), *v);
   }
   for n in nodes.iter() {
 for (k,v) in self.collect_node_names(local_map, n.subnodes).iter() {
   local_map.insert(k.clone(), *v);
 }
 match n.name {
   Some(ref name) = {
 if local_map.contains_key(name) {

 } else {
   local_map.insert(name.clone(), *n);
 }
   },
   None = (),
  }
   }
   local_map
 }

 this one works, but it's bloated and slow. Any hints on how to improve the
 code?

 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Nightly docs for Dash

2014-06-14 Thread Vladimir Pouzanov
Funnily enough I did the same yesterday. I made a small extension to
https://github.com/indirect/dash-rust, my fork can be found here:
https://github.com/farcaller/dash-rust

It removes the left side navigation panel from docs and adds TOC generation.


On Sat, Jun 14, 2014 at 2:55 AM, Valerii Hiora valerii.hi...@gmail.com
wrote:

 Hi,

   Being a big fan of offline documentation I've prepared a fresh docset
 for Dash (zeal, helm-dash, any other compatible software).

   Here is the link for subscription:

 dash-feed://https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fnet.
 vhbit.rust-doc%2FRustNightly.xml

It's a beta and has a couple of known issues in it. If there would be
 enough interest - it could be also integrated with existing buildbots.

 --

   Valerii
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] how is Rust bootstrapped?

2014-06-09 Thread Vladimir Pouzanov
Rustc runs on arm just fine.


On Mon, Jun 9, 2014 at 11:32 AM, Kevin Cantu m...@kevincantu.org wrote:

 Perl and Python may still be dependencies for small things on some
 platforms, IIRC, too.

 Anyways, to get `rustc` on a new architecture, it must be one LLVM
 supports, and then you should cross-compile `rustc` onto it.  I don't
 remember for sure whether `rustc` even runs on ARM, or if people just
 cross-compile binaries for it, actually, though...


 Kevin


 On Mon, Jun 9, 2014 at 3:16 AM, Leo Testard leo.test...@gmail.com wrote:

 Hello,

 The OCaml compiler is not used anymore for years. As you said, the Rust
 build system now downloads a precompiled snapshot of the new
 implementation, which is written in Rust. Unfortunately, you won't be able
 to compile it yourself.if you don't have Rust already setup on your machine.

 For C++, I believe it's used to compile the modified LLVM Rustc uses.
 Others may confirm this.

 Leo
 --
 Envoyé de mon téléphone Android avec K-9 Mail. Excusez la brièveté.
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev



 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] How do I bootstrap rust form armhf?

2014-06-06 Thread Vladimir Pouzanov
Thanks, I managed to bootstrap my rustc already with a few hints.


On Fri, Jun 6, 2014 at 4:19 PM, Valerii Hiora valerii.hi...@gmail.com
wrote:

 I'm trying to run rustc on an arm board, but obviously there's no
 precompiled stage0 to build the compiler.
 Is there a procedure to cross-compile stage0 on other host machine where
 I do have rustc?


Disclaimer: haven't tried anything like this, but just a couple of
 hints:

- configure script checks for CFG_ENABLE_LOCAL_RUST, so it should be
 possible to use any rustc
- in src/etc there are make_snapshot.py, snapshot.py, local_stage0.sh
 which might be useful for study
- there are a couple of mentions of cfg(stage0) in sources, probably
 compiling rust for stage0 will require additionally setting --cfg stage0

 --

Valerii
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] How do I bootstrap rust form armhf?

2014-06-04 Thread Vladimir Pouzanov
I'm trying to run rustc on an arm board, but obviously there's no
precompiled stage0 to build the compiler.

Is there a procedure to cross-compile stage0 on other host machine where I
do have rustc?

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] morestack prologue contains broken machine code

2014-05-01 Thread Vladimir Pouzanov
Is there any good reason why kSplitStackAvailable is hard-coded to 256
(given that I have tasks with their whole stack on 512 bytes)? I guess,
this constant should actually be externally configurable.


On Fri, Apr 25, 2014 at 5:20 PM, Alex Crichton a...@crichton.co wrote:

 The prologue is run on every single function executed in a program, so
 I believe that in the hopes of keeping it as light as possible it
 never makes any function calls.

 I do agree though, that it's at tricky situation in that case. How
 does TLS otherwise work for that platform?

 On Fri, Apr 25, 2014 at 8:14 AM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  I have a side question related to the same code.
 
  Currently __STACK_LIMIT is constant, but I would like the preamble to
 verify
  stack overflow for multithreaded context, i.e. __STACK_LIMIT will depend
 on
  the current running thread. Is there any reason, why it's not a function?
  Any objections if I do some refactoring and make it a function? For a
 simple
  case that could be a weak symbol that returns a constant.
 
 
  On Tue, Apr 22, 2014 at 9:00 AM, Alex Crichton a...@crichton.co wrote:
 
  I agree with Corey, it's much better to send it upstream first. I'd be
  more than willing to help you out with writing tests or taking a peek
  at the patch if you want! I'm acrichto on IRC
 
  On Tue, Apr 22, 2014 at 12:43 AM, Vladimir Pouzanov 
 farcal...@gmail.com
  wrote:
   The problem is that mrc is generated unless target is thumb1, but
   cortex-m3
   is thumb2 that still doesn't support mrc:
  
  
 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html
 ,
   so an additional check to ST-TargetTriple.Data is required to verify
   it's
   not thumbv7m.
  
   Do I need to submit patch against https://github.com/rust-lang/llvmor
   send
   it to upstream?
  
  
   On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov 
 farcal...@gmail.com
   wrote:
  
   Hm, it seems to have precautions to stop mrc from materializing on
   Thumb1.
   I guess I need to take a better look into what's going wrong on my
   side.
   I'll see what I can do with that.
  
  
   On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton a...@crichton.co
   wrote:
  
   The split stack patches for ARM were recently upstreamed, and they
   were modified when being upstreamed as well. Primarily the location
 of
   the split stack is no longer at a magic address for thumb, but
 rather
   it uses the same instruction as ARM (some thumb processors do indeed
   have the coprocessor). More information is in the long thread
 starting
   at the initial attempt to upstream [1].
  
   For now you'll have to use no_split_stack because the thumb split
   stack will always use a coprocessor, but I'm sure that the upstream
   LLVM devs would be quite welcoming to tweaks to the slit-stack
 support
   (I'd also be willing to help). You can find the initial commit for
   support at rust-lang/llvm [2].
  
   [1] -
  
  
 http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html
   [2] - https://github.com/rust-lang/llvm/pull/4
  
   On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov
   farcal...@gmail.com
   wrote:
Starting recently (no more than two weeks), rustc is generating a
broken
prologue for arm. Here's the sample assembly:
   0x0f44 +0: push {r4, r5}
= 0x0f46 +2: mrc 15, 0, r4, cr13, cr0, {3}
   0x0f4a +6: mov r5, sp
   0x0f4c +8: b.n 0xa78 main+2616
   0x0f4e +10: ands r4, r0
   0x0f50 +12: cmp r4, r5
   0x0f52 +14: bcc.n 0xf66
   
   
   
 _ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34
   0x0f54 +16: movs r4, #16
   0x0f56 +18: movs r5, #0
   0x0f58 +20: push {lr}
   0x0f5a +22: bl 0x19d8 __morestack
   0x0f5e +26: ldr.w lr, [sp], #4
   0x0f62 +30: pop {r4, r5}
   0x0f64 +32: bx lr
   
The problem is at 0x0f46, where code tries to read from
coprocessor
15
register 13, which is process id register. Well, coprocessor 15
(actually,
all of the coprocessors) are missing from my target
thumbv7m-linux-eabi
(with added flavour of -Ctarget-cpu=cortex-m3, which should be
redundant
anyway), so I'm getting hardfaults in every function that rust
doesn't
inline.
   
Any ideas on what might be going wrong? I assume that this is
actually
llvm's fault, as llvm should not materialize machine code which is
not
available for target anyway.
   
Wrapping everything in #[no_split_stack] is a temporary workaround
and
surely not a long-term strategy.
   
--
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
   
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
   
  
  
  
  
   --
   Sincerely,
   Vladimir Farcaller

Re: [rust-dev] morestack prologue contains broken machine code

2014-04-30 Thread Vladimir Pouzanov
I guess I've misread how __STACK_LIMIT works, it seems that I can change
it's value on context switch so that it keeps track of the current running
task. Works flawlessly, so I'm going to proceed with my original patch now.


On Fri, Apr 25, 2014 at 6:33 PM, Vladimir Pouzanov farcal...@gmail.comwrote:

 AFAIK, it's emulated in software with __tls_get_addr. Mind that Cortex-M
 MCUs that I'm toying with aren't usually compatible with any full-blown
 OS, and all the RTOSes out there have different implementations of
 multithreading and TLS, utilising the none OS target of gcc. The best way
 to deal with this would be to specify arm-none-eabi ABI for llvm, that
 would include tls behaviour amongst other things, but that sounds like a
 very complex task.


 On Fri, Apr 25, 2014 at 5:20 PM, Alex Crichton a...@crichton.co wrote:

 The prologue is run on every single function executed in a program, so
 I believe that in the hopes of keeping it as light as possible it
 never makes any function calls.

 I do agree though, that it's at tricky situation in that case. How
 does TLS otherwise work for that platform?

 On Fri, Apr 25, 2014 at 8:14 AM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  I have a side question related to the same code.
 
  Currently __STACK_LIMIT is constant, but I would like the preamble to
 verify
  stack overflow for multithreaded context, i.e. __STACK_LIMIT will
 depend on
  the current running thread. Is there any reason, why it's not a
 function?
  Any objections if I do some refactoring and make it a function? For a
 simple
  case that could be a weak symbol that returns a constant.
 
 
  On Tue, Apr 22, 2014 at 9:00 AM, Alex Crichton a...@crichton.co
 wrote:
 
  I agree with Corey, it's much better to send it upstream first. I'd be
  more than willing to help you out with writing tests or taking a peek
  at the patch if you want! I'm acrichto on IRC
 
  On Tue, Apr 22, 2014 at 12:43 AM, Vladimir Pouzanov 
 farcal...@gmail.com
  wrote:
   The problem is that mrc is generated unless target is thumb1, but
   cortex-m3
   is thumb2 that still doesn't support mrc:
  
  
 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html
 ,
   so an additional check to ST-TargetTriple.Data is required to verify
   it's
   not thumbv7m.
  
   Do I need to submit patch against https://github.com/rust-lang/llvmor
   send
   it to upstream?
  
  
   On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov 
 farcal...@gmail.com
   wrote:
  
   Hm, it seems to have precautions to stop mrc from materializing on
   Thumb1.
   I guess I need to take a better look into what's going wrong on my
   side.
   I'll see what I can do with that.
  
  
   On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton a...@crichton.co
   wrote:
  
   The split stack patches for ARM were recently upstreamed, and they
   were modified when being upstreamed as well. Primarily the
 location of
   the split stack is no longer at a magic address for thumb, but
 rather
   it uses the same instruction as ARM (some thumb processors do
 indeed
   have the coprocessor). More information is in the long thread
 starting
   at the initial attempt to upstream [1].
  
   For now you'll have to use no_split_stack because the thumb split
   stack will always use a coprocessor, but I'm sure that the upstream
   LLVM devs would be quite welcoming to tweaks to the slit-stack
 support
   (I'd also be willing to help). You can find the initial commit for
   support at rust-lang/llvm [2].
  
   [1] -
  
  
 http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html
   [2] - https://github.com/rust-lang/llvm/pull/4
  
   On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov
   farcal...@gmail.com
   wrote:
Starting recently (no more than two weeks), rustc is generating a
broken
prologue for arm. Here's the sample assembly:
   0x0f44 +0: push {r4, r5}
= 0x0f46 +2: mrc 15, 0, r4, cr13, cr0, {3}
   0x0f4a +6: mov r5, sp
   0x0f4c +8: b.n 0xa78 main+2616
   0x0f4e +10: ands r4, r0
   0x0f50 +12: cmp r4, r5
   0x0f52 +14: bcc.n 0xf66
   
   
   
 _ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34
   0x0f54 +16: movs r4, #16
   0x0f56 +18: movs r5, #0
   0x0f58 +20: push {lr}
   0x0f5a +22: bl 0x19d8 __morestack
   0x0f5e +26: ldr.w lr, [sp], #4
   0x0f62 +30: pop {r4, r5}
   0x0f64 +32: bx lr
   
The problem is at 0x0f46, where code tries to read from
coprocessor
15
register 13, which is process id register. Well, coprocessor 15
(actually,
all of the coprocessors) are missing from my target
thumbv7m-linux-eabi
(with added flavour of -Ctarget-cpu=cortex-m3, which should be
redundant
anyway), so I'm getting hardfaults in every function that rust
doesn't
inline.
   
Any ideas on what might be going wrong

[rust-dev] Symbol visibility problem

2014-04-30 Thread Vladimir Pouzanov
I have the following setup:

  libzinc, compiles as rlib, provides all the stuff
  support, compiles as obj, provides __morestack, memset/memcpy and other
required things
  libapp, compiles as staticlib emitting obj, depends on libzinc, builds
with lto.

I link libapp.o and support.o to get the final binary.

Now, to make multitasking work, I need to move __morestack into libzinc, so
that I can access task API from the function. The problem is that publicly
visible __morestack in libzinc is not visible from libapp, which requires
it implicitly via function prologues. Other static symbols (like
__STACK_LIMIT) are not available as well.

Is there any way to promote the visibility of symbols from libzinc to
libapp in this case?

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Symbol visibility problem

2014-04-30 Thread Vladimir Pouzanov
Right, so I have a publicly reachable symbol __STACK_LIMIT inside my
libzinc rlib:

#[no_mangle]
pub static mut __STACK_LIMIT: u32 = 0;

which is present in rlib's object file:

% arm-none-eabi-nm zinc.o|grep __STACK_LIMIT
 B __STACK_LIMIT

Now, I compile my application, which is a staticlib, emiting an obj (I
could change staticlib to binary, that doesn't really change anything at
this emit level):

rustc -Z no-landing-pads -C relocation_model=static --target
thumbv7m-linux-eabi -Ctarget-cpu=cortex-m3 --opt-level 2 -Z lto --emit obj
-L ./build -o ./build/intermediate/app.o ./apps/app_sched.rs

Which implicitly links to libzinc-de5e5c68-0.0.rlib.

Given the lto nature, ./build/intermediate/app.o will contain all the
required code from libzinc (and libcore), so I proceed to linker:

arm-none-eabi-ld -Map ./build/zinc.map -o ./build/zinc.elf -T
./src/hal/lpc17xx/layout.ld ./build/intermediate/app.o
-L/opt/gcc-arm-none-eabi-4_7-2013q3/lib/gcc/arm-none-eabi/4.7.4/armv7-m
--gc-sections -lgcc

Which fails due to undefined reference to `__STACK_LIMIT', as the lto
step didn't keep the __STACK_LIMIT (which is, along with __morestack, used
implicitly).

I have the same problem with ISRs that re defined in libzinc. For now, I
make trampolines in the app code:

#[no_mangle]
#[inline(never)]
#[no_split_stack]
pub unsafe fn task_scheduler() {
  task::task_scheduler();
}

that look bad, but I don't yet know a better way to do it.

I cannot move __STACK_LIMIT or __morestack in a dedicated object file and
pass it to linker, as those depend on libzinc which isn't reaching the
linker explicitly.


On Wed, Apr 30, 2014 at 5:17 PM, Alex Crichton a...@crichton.co wrote:

 In an rlib, all publicly reachable symbols will be exported from the
 object, for example:


 mod foo { pub static BAR: int = 3; }

 That symbol is not exported because BAR is not reachable from the outside
 world.

 pub use foo::BAR;
 mod foo { pub static BAR: int = 3; }

 This time, BAR will be an exported symbol because it is publicly
 reachable (you could also make 'foo' public).

 Would that help your use case, or are you thinking of something more
 complex?

 On Wed, Apr 30, 2014 at 6:49 AM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  I have the following setup:
 
libzinc, compiles as rlib, provides all the stuff
support, compiles as obj, provides __morestack, memset/memcpy and other
  required things
libapp, compiles as staticlib emitting obj, depends on libzinc, builds
  with lto.
 
  I link libapp.o and support.o to get the final binary.
 
  Now, to make multitasking work, I need to move __morestack into libzinc,
 so
  that I can access task API from the function. The problem is that
 publicly
  visible __morestack in libzinc is not visible from libapp, which
 requires it
  implicitly via function prologues. Other static symbols (like
 __STACK_LIMIT)
  are not available as well.
 
  Is there any way to promote the visibility of symbols from libzinc to
 libapp
  in this case?
 
  --
  Sincerely,
  Vladimir Farcaller Pouzanov
  http://farcaller.net/
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev
 




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Symbol visibility problem

2014-04-30 Thread Vladimir Pouzanov
Ok, seems that I found a reasonably good solution.

The app is now an rlib, and the actual staticlib app that gets linked is
a wrapper, that sources all external crates and re-exports required symbols
like this:

#[no_split_stack]
#[no_mangle]
#[start]
pub extern fn main() {
  app::main();
}

I also had to move __STACK_LIMIT into external C file, as I couldn't define
it as external in one crate and provide it in another crate down the chain.


On Wed, Apr 30, 2014 at 5:29 PM, Vladimir Pouzanov farcal...@gmail.comwrote:

 Right, so I have a publicly reachable symbol __STACK_LIMIT inside my
 libzinc rlib:

 #[no_mangle]
 pub static mut __STACK_LIMIT: u32 = 0;

 which is present in rlib's object file:

 % arm-none-eabi-nm zinc.o|grep __STACK_LIMIT
  B __STACK_LIMIT

 Now, I compile my application, which is a staticlib, emiting an obj (I
 could change staticlib to binary, that doesn't really change anything at
 this emit level):

 rustc -Z no-landing-pads -C relocation_model=static --target
 thumbv7m-linux-eabi -Ctarget-cpu=cortex-m3 --opt-level 2 -Z lto --emit obj
 -L ./build -o ./build/intermediate/app.o ./apps/app_sched.rs

 Which implicitly links to libzinc-de5e5c68-0.0.rlib.

 Given the lto nature, ./build/intermediate/app.o will contain all the
 required code from libzinc (and libcore), so I proceed to linker:

 arm-none-eabi-ld -Map ./build/zinc.map -o ./build/zinc.elf -T
 ./src/hal/lpc17xx/layout.ld ./build/intermediate/app.o
 -L/opt/gcc-arm-none-eabi-4_7-2013q3/lib/gcc/arm-none-eabi/4.7.4/armv7-m
 --gc-sections -lgcc

 Which fails due to undefined reference to `__STACK_LIMIT', as the lto
 step didn't keep the __STACK_LIMIT (which is, along with __morestack, used
 implicitly).

 I have the same problem with ISRs that re defined in libzinc. For now, I
 make trampolines in the app code:

 #[no_mangle]
 #[inline(never)]
 #[no_split_stack]
 pub unsafe fn task_scheduler() {
   task::task_scheduler();
 }

 that look bad, but I don't yet know a better way to do it.

 I cannot move __STACK_LIMIT or __morestack in a dedicated object file and
 pass it to linker, as those depend on libzinc which isn't reaching the
 linker explicitly.


 On Wed, Apr 30, 2014 at 5:17 PM, Alex Crichton a...@crichton.co wrote:

 In an rlib, all publicly reachable symbols will be exported from the
 object, for example:


 mod foo { pub static BAR: int = 3; }

 That symbol is not exported because BAR is not reachable from the outside
 world.

 pub use foo::BAR;
 mod foo { pub static BAR: int = 3; }

 This time, BAR will be an exported symbol because it is publicly
 reachable (you could also make 'foo' public).

 Would that help your use case, or are you thinking of something more
 complex?

 On Wed, Apr 30, 2014 at 6:49 AM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  I have the following setup:
 
libzinc, compiles as rlib, provides all the stuff
support, compiles as obj, provides __morestack, memset/memcpy and
 other
  required things
libapp, compiles as staticlib emitting obj, depends on libzinc, builds
  with lto.
 
  I link libapp.o and support.o to get the final binary.
 
  Now, to make multitasking work, I need to move __morestack into
 libzinc, so
  that I can access task API from the function. The problem is that
 publicly
  visible __morestack in libzinc is not visible from libapp, which
 requires it
  implicitly via function prologues. Other static symbols (like
 __STACK_LIMIT)
  are not available as well.
 
  Is there any way to promote the visibility of symbols from libzinc to
 libapp
  in this case?
 
  --
  Sincerely,
  Vladimir Farcaller Pouzanov
  http://farcaller.net/
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev
 




 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] A small announcement for zinc, the bare metal rust stack

2014-04-25 Thread Vladimir Pouzanov
A few ideas:

 * make a static P that manages *T storage inside it. *T could be
statically pointed to heap block in ram, P will wrap the API to make it
less verbose.
 * use Cell to make internals of immutable mutable back again. This would
not work with statics, obviously, as they will land in .rodata, but we
have #[link_section] to deal with that.
 * same as above, but use extern with further linker script placement (same
way as I deal with ioregs in zinc).


On Thu, Apr 24, 2014 at 11:37 PM, Ben Gamari bgam...@gmail.com wrote:

 Ben Gamari bgam...@gmail.com writes:

  Vladimir Pouzanov farcal...@gmail.com writes:
 
 ...

  My current idea is to make dedicated pools that could hold a
 compile-time
  configurable number of objects of same size, e.g. an IncomingPacketPool
  that can hold up to 3 frames where one frame is 128 bytes long. This
 way no
  other running process can interfere with code that processes incoming
  packets and that code can offload incoming packets into the pool for
 later
  processing, but up to three, and it will act in user-defined fashion
 (drop
  packets) if the pool is full. The implementation of that would be quite
  simple, and I think that it might be possible to extend ~T ownership for
  something like that.
 
  I tried playing around (warning: code written by new Rust-er, expect
  eye damage, feedback welcome) with a simple buffer pool implementation
  this morning; unfortunately I found that Rust's restrictions on function
  application in constant expressions makes static allocation quite
  difficult (impossible?),
 
 Tonight I played around with using the macro system to work around the
 static initializer limitation. The result[1] isn't terrible, but
 it didn't take long for me to run into a mutability issue. In short, I
 was inadvertently declaring my static pool as immutable, causing it to
 end up in the data.rel.ro section, resulting in a segfault when I attempt
 to increment the reference count (held in an `Unsafe`).

 I thought the obvious way around this would be to declare the pool as
 `static mut` but
 this unfortunately makes things quite verbose as one must declare each
 point of usage as `unsafe`. Moreover, for reasons I don't quite yet
 understand it seems that some data is still being placed in a read-only
 section and therefore the crash reappears. Regardless, it seems that
 mutable statics might be another sticking point in embedded contexts
 where static allocation is often desirable.

 Anyone have any clever ideas for dealing with this?

 Cheers,

 - Ben


 [1] https://gist.github.com/bgamari/033379d82f179eac8688




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] morestack prologue contains broken machine code

2014-04-25 Thread Vladimir Pouzanov
I have a side question related to the same code.

Currently __STACK_LIMIT is constant, but I would like the preamble to
verify stack overflow for multithreaded context, i.e. __STACK_LIMIT will
depend on the current running thread. Is there any reason, why it's not a
function? Any objections if I do some refactoring and make it a function?
For a simple case that could be a weak symbol that returns a constant.


On Tue, Apr 22, 2014 at 9:00 AM, Alex Crichton a...@crichton.co wrote:

 I agree with Corey, it's much better to send it upstream first. I'd be
 more than willing to help you out with writing tests or taking a peek
 at the patch if you want! I'm acrichto on IRC

 On Tue, Apr 22, 2014 at 12:43 AM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  The problem is that mrc is generated unless target is thumb1, but
 cortex-m3
  is thumb2 that still doesn't support mrc:
 
 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html
 ,
  so an additional check to ST-TargetTriple.Data is required to verify
 it's
  not thumbv7m.
 
  Do I need to submit patch against https://github.com/rust-lang/llvm or
 send
  it to upstream?
 
 
  On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov farcal...@gmail.com
  wrote:
 
  Hm, it seems to have precautions to stop mrc from materializing on
 Thumb1.
  I guess I need to take a better look into what's going wrong on my side.
  I'll see what I can do with that.
 
 
  On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton a...@crichton.co
 wrote:
 
  The split stack patches for ARM were recently upstreamed, and they
  were modified when being upstreamed as well. Primarily the location of
  the split stack is no longer at a magic address for thumb, but rather
  it uses the same instruction as ARM (some thumb processors do indeed
  have the coprocessor). More information is in the long thread starting
  at the initial attempt to upstream [1].
 
  For now you'll have to use no_split_stack because the thumb split
  stack will always use a coprocessor, but I'm sure that the upstream
  LLVM devs would be quite welcoming to tweaks to the slit-stack support
  (I'd also be willing to help). You can find the initial commit for
  support at rust-lang/llvm [2].
 
  [1] -
 
 http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html
  [2] - https://github.com/rust-lang/llvm/pull/4
 
  On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov 
 farcal...@gmail.com
  wrote:
   Starting recently (no more than two weeks), rustc is generating a
   broken
   prologue for arm. Here's the sample assembly:
  0x0f44 +0: push {r4, r5}
   = 0x0f46 +2: mrc 15, 0, r4, cr13, cr0, {3}
  0x0f4a +6: mov r5, sp
  0x0f4c +8: b.n 0xa78 main+2616
  0x0f4e +10: ands r4, r0
  0x0f50 +12: cmp r4, r5
  0x0f52 +14: bcc.n 0xf66
  
  
 _ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34
  0x0f54 +16: movs r4, #16
  0x0f56 +18: movs r5, #0
  0x0f58 +20: push {lr}
  0x0f5a +22: bl 0x19d8 __morestack
  0x0f5e +26: ldr.w lr, [sp], #4
  0x0f62 +30: pop {r4, r5}
  0x0f64 +32: bx lr
  
   The problem is at 0x0f46, where code tries to read from
 coprocessor
   15
   register 13, which is process id register. Well, coprocessor 15
   (actually,
   all of the coprocessors) are missing from my target
 thumbv7m-linux-eabi
   (with added flavour of -Ctarget-cpu=cortex-m3, which should be
   redundant
   anyway), so I'm getting hardfaults in every function that rust
 doesn't
   inline.
  
   Any ideas on what might be going wrong? I assume that this is
 actually
   llvm's fault, as llvm should not materialize machine code which is
 not
   available for target anyway.
  
   Wrapping everything in #[no_split_stack] is a temporary workaround
 and
   surely not a long-term strategy.
  
   --
   Sincerely,
   Vladimir Farcaller Pouzanov
   http://farcaller.net/
  
   ___
   Rust-dev mailing list
   Rust-dev@mozilla.org
   https://mail.mozilla.org/listinfo/rust-dev
  
 
 
 
 
  --
  Sincerely,
  Vladimir Farcaller Pouzanov
  http://farcaller.net/
 
 
 
 
  --
  Sincerely,
  Vladimir Farcaller Pouzanov
  http://farcaller.net/




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] morestack prologue contains broken machine code

2014-04-25 Thread Vladimir Pouzanov
AFAIK, it's emulated in software with __tls_get_addr. Mind that Cortex-M
MCUs that I'm toying with aren't usually compatible with any full-blown
OS, and all the RTOSes out there have different implementations of
multithreading and TLS, utilising the none OS target of gcc. The best way
to deal with this would be to specify arm-none-eabi ABI for llvm, that
would include tls behaviour amongst other things, but that sounds like a
very complex task.


On Fri, Apr 25, 2014 at 5:20 PM, Alex Crichton a...@crichton.co wrote:

 The prologue is run on every single function executed in a program, so
 I believe that in the hopes of keeping it as light as possible it
 never makes any function calls.

 I do agree though, that it's at tricky situation in that case. How
 does TLS otherwise work for that platform?

 On Fri, Apr 25, 2014 at 8:14 AM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  I have a side question related to the same code.
 
  Currently __STACK_LIMIT is constant, but I would like the preamble to
 verify
  stack overflow for multithreaded context, i.e. __STACK_LIMIT will depend
 on
  the current running thread. Is there any reason, why it's not a function?
  Any objections if I do some refactoring and make it a function? For a
 simple
  case that could be a weak symbol that returns a constant.
 
 
  On Tue, Apr 22, 2014 at 9:00 AM, Alex Crichton a...@crichton.co wrote:
 
  I agree with Corey, it's much better to send it upstream first. I'd be
  more than willing to help you out with writing tests or taking a peek
  at the patch if you want! I'm acrichto on IRC
 
  On Tue, Apr 22, 2014 at 12:43 AM, Vladimir Pouzanov 
 farcal...@gmail.com
  wrote:
   The problem is that mrc is generated unless target is thumb1, but
   cortex-m3
   is thumb2 that still doesn't support mrc:
  
  
 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html
 ,
   so an additional check to ST-TargetTriple.Data is required to verify
   it's
   not thumbv7m.
  
   Do I need to submit patch against https://github.com/rust-lang/llvmor
   send
   it to upstream?
  
  
   On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov 
 farcal...@gmail.com
   wrote:
  
   Hm, it seems to have precautions to stop mrc from materializing on
   Thumb1.
   I guess I need to take a better look into what's going wrong on my
   side.
   I'll see what I can do with that.
  
  
   On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton a...@crichton.co
   wrote:
  
   The split stack patches for ARM were recently upstreamed, and they
   were modified when being upstreamed as well. Primarily the location
 of
   the split stack is no longer at a magic address for thumb, but
 rather
   it uses the same instruction as ARM (some thumb processors do indeed
   have the coprocessor). More information is in the long thread
 starting
   at the initial attempt to upstream [1].
  
   For now you'll have to use no_split_stack because the thumb split
   stack will always use a coprocessor, but I'm sure that the upstream
   LLVM devs would be quite welcoming to tweaks to the slit-stack
 support
   (I'd also be willing to help). You can find the initial commit for
   support at rust-lang/llvm [2].
  
   [1] -
  
  
 http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html
   [2] - https://github.com/rust-lang/llvm/pull/4
  
   On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov
   farcal...@gmail.com
   wrote:
Starting recently (no more than two weeks), rustc is generating a
broken
prologue for arm. Here's the sample assembly:
   0x0f44 +0: push {r4, r5}
= 0x0f46 +2: mrc 15, 0, r4, cr13, cr0, {3}
   0x0f4a +6: mov r5, sp
   0x0f4c +8: b.n 0xa78 main+2616
   0x0f4e +10: ands r4, r0
   0x0f50 +12: cmp r4, r5
   0x0f52 +14: bcc.n 0xf66
   
   
   
 _ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34
   0x0f54 +16: movs r4, #16
   0x0f56 +18: movs r5, #0
   0x0f58 +20: push {lr}
   0x0f5a +22: bl 0x19d8 __morestack
   0x0f5e +26: ldr.w lr, [sp], #4
   0x0f62 +30: pop {r4, r5}
   0x0f64 +32: bx lr
   
The problem is at 0x0f46, where code tries to read from
coprocessor
15
register 13, which is process id register. Well, coprocessor 15
(actually,
all of the coprocessors) are missing from my target
thumbv7m-linux-eabi
(with added flavour of -Ctarget-cpu=cortex-m3, which should be
redundant
anyway), so I'm getting hardfaults in every function that rust
doesn't
inline.
   
Any ideas on what might be going wrong? I assume that this is
actually
llvm's fault, as llvm should not materialize machine code which is
not
available for target anyway.
   
Wrapping everything in #[no_split_stack] is a temporary workaround
and
surely not a long-term strategy.
   
--
Sincerely,
Vladimir

Re: [rust-dev] A small announcement for zinc, the bare metal rust stack

2014-04-24 Thread Vladimir Pouzanov
On Thu, Apr 24, 2014 at 9:01 AM, Ben Gamari bgam...@gmail.com wrote:

 Unfortunately this replaces the ugly possibility of unpredictable
 crashes with the slightly less ugly possiblity of unpredictable
 deadlocks if we run out of stack in the middle of execution. Perhaps
 threads could be annotated with their maximum expected stack size,
 allowing stack chunks to be allocated at spawn-time.


It wouldn't be allowed to grow, it's exactly that — maximum expected stack
size, task either fits in there or dies.


-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] A small announcement for zinc, the bare metal rust stack

2014-04-23 Thread Vladimir Pouzanov
Luckily enough, I had the concept for zinc even before I started coding in
rust :-) And yes, there are lots of different oxides in rust world.


On Wed, Apr 23, 2014 at 3:58 AM, Thad Guidry thadgui...@gmail.com wrote:

 Actually...I do not. :)


 On Tue, Apr 22, 2014 at 9:05 PM, Chris Morgan m...@chrismorgan.info wrote:

 On Wed, Apr 23, 2014 at 10:35 AM, Thad Guidry thadgui...@gmail.com
 wrote:
  I would have named it ... oxide instead of zinc ;-) ... rust = iron
 oxide
 Do you know how many projects written in Rust have already been named
 “oxide”?




 --
 -Thad
 +ThadGuidry https://www.google.com/+ThadGuidry
 Thad on LinkedIn http://www.linkedin.com/in/thadguidry/

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] A small announcement for zinc, the bare metal rust stack

2014-04-23 Thread Vladimir Pouzanov
There is a number of options on the memory side of things. I feel that
stack usage could be estimated a bit more simply with rust and it's
__morestack support, so that it would be possible to run a few threads with
preemptive scheduling (__morestack also guarantees that no memory
corruption would occur due to stack overflow).

I'm totally against unmanaged heap support and ~T on embedded, that just
doesn't work. It's a very big burden to support that reasonably in existing
C/C++ RTOSes out there, so I don't want to spend lots of time trying to
solve the same problems. Still, heap is really useful in some cases (as
I've figured out while working on 802.15.4 stack for zinc).

My current idea is to make dedicated pools that could hold a compile-time
configurable number of objects of same size, e.g. an IncomingPacketPool
that can hold up to 3 frames where one frame is 128 bytes long. This way no
other running process can interfere with code that processes incoming
packets and that code can offload incoming packets into the pool for later
processing, but up to three, and it will act in user-defined fashion (drop
packets) if the pool is full. The implementation of that would be quite
simple, and I think that it might be possible to extend ~T ownership for
something like that.


On Wed, Apr 23, 2014 at 3:47 PM, Ben Gamari bgam...@gmail.com wrote:

 Vladimir Pouzanov farcal...@gmail.com writes:

  This is the project I've been tinkering with for a good number of
  weekends zinc, the bare metal stack for rust is available at
  https://github.com/hackndev/zinc.
 
  I've just finished a major refactoring work for LPC1768 code, so
  STM32F4 is kind of broken yet, and LPC1114 is totally dropped, but
  I'll fix that soon.
 
  The current code supports GPIO operations, UART and SSP in SPI mode
  for NXP LPC1768, also featuring a driver for
  http://mbed.org/cookbook/mbed-application-board TFT LCD and for
  ILI9341-based TFT LCDs commonly found on ebay.
 
  My plan is to fix support for STM32F4, bring it to the level of NXP
  part and try to expand this to a small RTOS, which would be a nice
  demo of rust capabilities for embedded development.
 
  The code is licensed under Apache-2.0.
 
  There's no readme yet, but you can see the demo applications written
  with zinc here: https://github.com/hackndev/zinc/tree/master/apps.
 
 Thanks for the release! I've been looking forward to seeing this ever
 since your Reddit post a few weeks back as I too have been recently
 thinking about how Rust might be used in an embedded environment.

 Lately I've been contributing to the mchck[1] project, its associated
 library, and a project I've built on top of it[2]. One of the things
 that I feel the mchck library gets right is the ubiquitous use of
 asynchronous completion notification (e.g. [3]) instead of polling. In
 my experience asynchronous code both maps onto hardware more naturally
 and produces more composable user code. Unfortunately, C makes
 continuation passing very painful due to the broken up flow of control
 that results from the sea of callbacks and the boilerplate (e.g. passing
 and casting of `void*` pointers to structs of intermediate state)
 necessary for propagation of state between callbacks.

 As far as I can tell, there are two paths by which Rust might improve
 this situation. The most straightforward approach would be to implement
 continuation passing directly by passing around continuation
 `procs`. While this approach reduces the amount of boilerplate due to
 state propagation, it does not really resolve the broken flow of control
 due to explicit continuations.

 Another approach which addresses this latter issue is to use Rust's
 native tasks, allowing requests to peripherals to be treated as
 blocking. While this seems like this could be very convenient, I am a bit
 concerned that the memory footprint of multiple stacks and associated
 bookkeeping data structures might be asking too much of the typical
 MCU (the devices I work with typically have 16kByte of SRAM).

 This memory footprint issue is especially concerning due to Rust's[4]
 heavy dependence on stack allocation. I am very much accustomed to
 avoiding dynamic allocation at all costs on embedded platforms; I
 appreciate knowing at compile time whether my program will fit on my
 device (up to stack allocations, which in my C code are intentionally
 minimal). With the uncertainty of dynamic allocation against the stack
 and dynamic task creation, it seems one literally has no idea whether a
 program will fit without either static analysis, simulation, or trial on
 real hardware. However, it seems that one loses a great deal by
 reverting to static allocation in Rust (e.g. losing safety of ownership,
 memory model becomes burdensome), so perhaps dynamic allocation coupled
 with robust allocation analysis tools is a reasonable trade-off.

 I'd be very interested to hear what others have to say about these
 issues.

 Cheers,

  - Ben


 [1] http

Re: [rust-dev] morestack prologue contains broken machine code

2014-04-22 Thread Vladimir Pouzanov
The problem is that mrc is generated unless target is thumb1, but cortex-m3
is thumb2 that still doesn't support mrc:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html,
so an additional check to ST-TargetTriple.Data is required to verify it's
not thumbv7m.

Do I need to submit patch against https://github.com/rust-lang/llvm or send
it to upstream?


On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov farcal...@gmail.comwrote:

 Hm, it seems to have precautions to stop mrc from materializing on Thumb1.
 I guess I need to take a better look into what's going wrong on my side.
 I'll see what I can do with that.


 On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton a...@crichton.co wrote:

 The split stack patches for ARM were recently upstreamed, and they
 were modified when being upstreamed as well. Primarily the location of
 the split stack is no longer at a magic address for thumb, but rather
 it uses the same instruction as ARM (some thumb processors do indeed
 have the coprocessor). More information is in the long thread starting
 at the initial attempt to upstream [1].

 For now you'll have to use no_split_stack because the thumb split
 stack will always use a coprocessor, but I'm sure that the upstream
 LLVM devs would be quite welcoming to tweaks to the slit-stack support
 (I'd also be willing to help). You can find the initial commit for
 support at rust-lang/llvm [2].

 [1] -
 http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html
 [2] - https://github.com/rust-lang/llvm/pull/4

 On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  Starting recently (no more than two weeks), rustc is generating a broken
  prologue for arm. Here's the sample assembly:
 0x0f44 +0: push {r4, r5}
  = 0x0f46 +2: mrc 15, 0, r4, cr13, cr0, {3}
 0x0f4a +6: mov r5, sp
 0x0f4c +8: b.n 0xa78 main+2616
 0x0f4e +10: ands r4, r0
 0x0f50 +12: cmp r4, r5
 0x0f52 +14: bcc.n 0xf66
 
 _ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34
 0x0f54 +16: movs r4, #16
 0x0f56 +18: movs r5, #0
 0x0f58 +20: push {lr}
 0x0f5a +22: bl 0x19d8 __morestack
 0x0f5e +26: ldr.w lr, [sp], #4
 0x0f62 +30: pop {r4, r5}
 0x0f64 +32: bx lr
 
  The problem is at 0x0f46, where code tries to read from coprocessor
 15
  register 13, which is process id register. Well, coprocessor 15
 (actually,
  all of the coprocessors) are missing from my target thumbv7m-linux-eabi
  (with added flavour of -Ctarget-cpu=cortex-m3, which should be redundant
  anyway), so I'm getting hardfaults in every function that rust doesn't
  inline.
 
  Any ideas on what might be going wrong? I assume that this is actually
  llvm's fault, as llvm should not materialize machine code which is not
  available for target anyway.
 
  Wrapping everything in #[no_split_stack] is a temporary workaround and
  surely not a long-term strategy.
 
  --
  Sincerely,
  Vladimir Farcaller Pouzanov
  http://farcaller.net/
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev
 




 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] A small announcement for zinc, the bare metal rust stack

2014-04-22 Thread Vladimir Pouzanov
This is the project I've been tinkering with for a good number of weekends
— zinc, the bare metal stack for rust is available at
https://github.com/hackndev/zinc.

I've just finished a major refactoring work for LPC1768 code, so STM32F4 is
kind of broken yet, and LPC1114 is totally dropped, but I'll fix that soon.

The current code supports GPIO operations, UART and SSP in SPI mode for NXP
LPC1768, also featuring a driver for
http://mbed.org/cookbook/mbed-application-board TFT LCD and for
ILI9341-based TFT LCDs commonly found on ebay.

My plan is to fix support for STM32F4, bring it to the level of NXP part
and try to expand this to a small RTOS, which would be a nice demo of rust
capabilities for embedded development.

The code is licensed under Apache-2.0.

There's no readme yet, but you can see the demo applications written with
zinc here: https://github.com/hackndev/zinc/tree/master/apps.

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] morestack prologue contains broken machine code

2014-04-21 Thread Vladimir Pouzanov
Starting recently (no more than two weeks), rustc is generating a broken
prologue for arm. Here's the sample assembly:
   0x0f44 +0: push {r4, r5}
= 0x0f46 +2: mrc 15, 0, r4, cr13, cr0, {3}
   0x0f4a +6: mov r5, sp
   0x0f4c +8: b.n 0xa78 main+2616
   0x0f4e +10: ands r4, r0
   0x0f50 +12: cmp r4, r5
   0x0f52 +14: bcc.n 0xf66
_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34
   0x0f54 +16: movs r4, #16
   0x0f56 +18: movs r5, #0
   0x0f58 +20: push {lr}
   0x0f5a +22: bl 0x19d8 __morestack
   0x0f5e +26: ldr.w lr, [sp], #4
   0x0f62 +30: pop {r4, r5}
   0x0f64 +32: bx lr

The problem is at 0x0f46, where code tries to read from coprocessor 15
register 13, which is process id register. Well, coprocessor 15
(actually, all of the coprocessors) are missing from my
target thumbv7m-linux-eabi (with added flavour of -Ctarget-cpu=cortex-m3,
which should be redundant anyway), so I'm getting hardfaults in every
function that rust doesn't inline.

Any ideas on what might be going wrong? I assume that this is actually
llvm's fault, as llvm should not materialize machine code which is not
available for target anyway.

Wrapping everything in #[no_split_stack] is a temporary workaround and
surely not a long-term strategy.

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] morestack prologue contains broken machine code

2014-04-21 Thread Vladimir Pouzanov
Hm, it seems to have precautions to stop mrc from materializing on Thumb1.
I guess I need to take a better look into what's going wrong on my side.
I'll see what I can do with that.


On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton a...@crichton.co wrote:

 The split stack patches for ARM were recently upstreamed, and they
 were modified when being upstreamed as well. Primarily the location of
 the split stack is no longer at a magic address for thumb, but rather
 it uses the same instruction as ARM (some thumb processors do indeed
 have the coprocessor). More information is in the long thread starting
 at the initial attempt to upstream [1].

 For now you'll have to use no_split_stack because the thumb split
 stack will always use a coprocessor, but I'm sure that the upstream
 LLVM devs would be quite welcoming to tweaks to the slit-stack support
 (I'd also be willing to help). You can find the initial commit for
 support at rust-lang/llvm [2].

 [1] -
 http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html
 [2] - https://github.com/rust-lang/llvm/pull/4

 On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  Starting recently (no more than two weeks), rustc is generating a broken
  prologue for arm. Here's the sample assembly:
 0x0f44 +0: push {r4, r5}
  = 0x0f46 +2: mrc 15, 0, r4, cr13, cr0, {3}
 0x0f4a +6: mov r5, sp
 0x0f4c +8: b.n 0xa78 main+2616
 0x0f4e +10: ands r4, r0
 0x0f50 +12: cmp r4, r5
 0x0f52 +14: bcc.n 0xf66
 
 _ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34
 0x0f54 +16: movs r4, #16
 0x0f56 +18: movs r5, #0
 0x0f58 +20: push {lr}
 0x0f5a +22: bl 0x19d8 __morestack
 0x0f5e +26: ldr.w lr, [sp], #4
 0x0f62 +30: pop {r4, r5}
 0x0f64 +32: bx lr
 
  The problem is at 0x0f46, where code tries to read from coprocessor
 15
  register 13, which is process id register. Well, coprocessor 15
 (actually,
  all of the coprocessors) are missing from my target thumbv7m-linux-eabi
  (with added flavour of -Ctarget-cpu=cortex-m3, which should be redundant
  anyway), so I'm getting hardfaults in every function that rust doesn't
  inline.
 
  Any ideas on what might be going wrong? I assume that this is actually
  llvm's fault, as llvm should not materialize machine code which is not
  available for target anyway.
 
  Wrapping everything in #[no_split_stack] is a temporary workaround and
  surely not a long-term strategy.
 
  --
  Sincerely,
  Vladimir Farcaller Pouzanov
  http://farcaller.net/
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev
 




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] LLVM doesn't inline my static, any good reason for that?

2014-04-20 Thread Vladimir Pouzanov
I'm working on a proof-of-concept implementation for
https://github.com/rust-lang/rfcs/pull/44 [Linker placement attribute], and
I actually got code that is working, but the outcome is worse than I
expected.

Consider the following snippet:

#[unsafe_override_address]
static Tinst : T = 1000;

What it is expected to do is to create a '1000 as *T' with the semantics of
T (the reasons for that are in RFC).

My patch actually works as expected in this regard, I evaluate the expr as
uint, and store a LLVMConstIntToPtr made from that uint
in ccx.const_values. The results in the following IR:

@Tinst = internal constant %struct.T* inttoptr (i32 1000 to %struct.T*)

The problem is that llvm never inlines the constant (even
with #[address_insignificant]), so instead of making the binary smaller as
llvm can optimize integer addresses better (as it knows them) it makes the
binary bigger, as it takes 4 bytes to store address value in .rodata, and
two instructions to fetch it.

Any ideas on what I could be missing?

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] LLVM doesn't inline my static, any good reason for that?

2014-04-20 Thread Vladimir Pouzanov
Apparently I had a problem of double pointer. The solution was to use

static Tinst : 'static T = 1000;

though I have modified the code now so that T works as well.


On Sun, Apr 20, 2014 at 2:04 PM, György Andrasek jur...@gmail.com wrote:

 On Sun, Apr 20, 2014 at 10:46 AM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  The results in the following IR:
 
  @Tinst = internal constant %struct.T* inttoptr (i32 1000 to %struct.T*)
 
  The problem is that llvm never inlines the constant (even with
  #[address_insignificant]), so instead of making the binary smaller as
 llvm
  can optimize integer addresses better (as it knows them) it makes the
 binary
  bigger, as it takes 4 bytes to store address value in .rodata, and two
  instructions to fetch it.

 Does it show up in the asm after optimizations? After LTO?




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Convincing compiler that *T is safe

2014-04-14 Thread Vladimir Pouzanov
Well, the Dev as a pointer would be immutable in terms of that you can't
change its address, and all access to fields is done via getter/setter
methods using volatiles.

It seems that I cannot use transmute in a context of static though and I
can't trade runtime size over better syntax.


On Mon, Apr 14, 2014 at 10:19 AM, Huon Wilson dbau...@gmail.com wrote:

  On 14/04/14 06:12, Vladimir Pouzanov wrote:

 I have a number of I/O mapped registers that look like:

  struct Dev {
   .. // u32 fields
 }

  pub static Dev0 : *mut Dev = 0xsomeaddr as *mut Dev;

  with macro-generated getters and setters:

  pub fn $getter_name(self) - u32 {
   unsafe { volatile_load((self.$reg)) }
 }

  unfortunately, calling a getter is calling a method on *Reg, which is
 unsafe and looks like:

  unsafe { (*Dev0).SOME_REG() };

  is there any way to simplify the syntax, hopefully to simple
 Dev0.SOME_REG()? I'm ok with any unsafe tricks including transmuting it
 to Dev (that doesn't seem to be possible though), as the getter/setter
 methods are always safe in this scenario.

  --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/


 ___
 Rust-dev mailing 
 listRust-dev@mozilla.orghttps://mail.mozilla.org/listinfo/rust-dev



 The compiler cannot verify that these method calls are safe, so they
 `unsafe`'s are asserting trust me compiler, I know more than you.


 You could write a macro like `get!(Dev0, SOME_REG)` that expanded to the
 `unsafe { (*Dev0).SOME_REG() }` invocation.


 But... I don't understand why transmuting to Dev wouldn't be possible.
 I'd strongly recommend the weaker version `unsafe { *Dev0 }`, to go from
 *mut Dev to Dev0. However, this likely breaks the guarantees of , since
 the data to which they point is supposed to be immutable, but being I/O
 mapped registers it would imply that external events can change the values.
 (I guess this is where Flavio's suggestion of storing a *UnsafeDev comes
 into play, but this still leaves you dealing with an *mut pointer to get at
 the data, at the end of the day.)


 Huon

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Convincing compiler that *T is safe

2014-04-13 Thread Vladimir Pouzanov
I have a number of I/O mapped registers that look like:

struct Dev {
  .. // u32 fields
}

pub static Dev0 : *mut Dev = 0xsomeaddr as *mut Dev;

with macro-generated getters and setters:

pub fn $getter_name(self) - u32 {
  unsafe { volatile_load((self.$reg)) }
}

unfortunately, calling a getter is calling a method on *Reg, which is
unsafe and looks like:

unsafe { (*Dev0).SOME_REG() };

is there any way to simplify the syntax, hopefully to simple
Dev0.SOME_REG()? I'm ok with any unsafe tricks including transmuting it
to Dev (that doesn't seem to be possible though), as the getter/setter
methods are always safe in this scenario.

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] matching on a few bits in int

2014-04-08 Thread Vladimir Pouzanov
Awesome use of unreachable!


On Tue, Apr 8, 2014 at 4:53 PM, Peter Marheine pe...@taricorp.net wrote:

 I had a go at building a macro to do this sort of thing, and it turned
 out to be easier than I expected.

 https://gist.github.com/tari/10144385

 Use like this:
 let x = match_bitfield!(do_something(), bits 4 to 8 {
 0 = DivideBy1,
 1 = DivideBy2,
 2 = DivideBy4,
 _ = UnknownDivisor
 };

 On Fri, Apr 4, 2014 at 7:11 AM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  I've submitted an RFC for this one:
  https://github.com/rust-lang/rfcs/pull/29
 
 
  On Sat, Mar 29, 2014 at 6:14 PM, Bill Myers bill_my...@outlook.com
 wrote:
 
  I think the best solution is to add uN and sN types where N is not a
 power
  of two, which LLVM should already support.
 
  Then you can write your match like this:
  match (val  6) as u2
  {
...
  }
 
  And it will work as desired.
 
  Biggest issue is that to make it work nicely you'd need to add some way
 to
  generalize over the bit-length and integers, and that's going to require
  generics with int parameters and work to add those.
 
 
 
 
  --
  Sincerely,
  Vladimir Farcaller Pouzanov
  http://farcaller.net/
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev
 



 --
 Peter Marheine
 Don't Panic




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Porting some nesC features to rust?

2014-04-08 Thread Vladimir Pouzanov
I might have found an unsupported case.

Consider the following:

trait SPI { ... }

struct McuSPI;
impl SPI for McuSPI { ... }

struct LCD {
  spi: SPI,
  ...
}

This code results in a dynamic dispatch to SPI, as trait bounds are not
allowed in structure definitions. Is it in any way possible to use static
dispatch from LCD to SPI given the exact implementations are known at
compile time?


On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles marci...@gmail.com wrote:

 And just in case there is a confusion (as I have noticed others to
 have), it might help to see a specific example comparing static
 dispatch with dynamic.

 // This is a single function for all types implementing the LCD Trait.
 fn foo(x : LCD) { // x's type is LCD rather than the actual type of
 the object being passed in
 x.line(); // dynamic dispatch
 }

 // Like C++ templates, this generates a function for each type T that
 implements LCD.
 fn fooT : LCD(x : T) { // x's type is T rather than LCD
 x.line(); // static dispatch based on type T known at compile-time
 }

 On Wed, Apr 2, 2014 at 8:32 AM, Daniel Micay danielmi...@gmail.com
 wrote:
  On 02/04/14 06:25 AM, Vladimir Pouzanov wrote:
  If I get it right, calls to traits are resolved in runtime (so, traits
  are kind of similar to C++ virtual methods).
 
  All method calls on regular types are resolved via static dispatch,
  whether or not they come from a trait. For example, consider a generic
  function like the following:
 
  fn minT: TotalOrd(a: T, b: T) - T {
  if a  b { a } else { b }
  }
 
  This function performs a *static* call of the `lt` method defined on the
  `Ord` trait that `TotalOrd` inherits from. Generics are fully expanded
  at compile-time just as C++ templates are.
 
  Rust also allows using traits as boxed objects, but this is an entirely
  transparent choice. They're almost always used for static dispatch via
  trait bounds on generics, or simply outside of generics.
 
  What I'm proposing here is a compile-time approach.
 
  Let's say we have the following trait:
 
  pub trait LCD {
fn line(mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, color: u8);
fn rect(mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: u8);
fn fillrect(mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: i32,
  color: u8);
fn putc(mut self, value: char);
fn puts(mut self, s: str);
 
fn flush(self);
fn clear(mut self);
  }
 
  which defined a LED screen. There are two structs implementing it:
  C12832 and ILI9341 (two different lcd controllers).
 
  So I want my app to print hello world on lcd, I write the following
 code:
 
let mut lcd = lcd_c12832::C12832::new(spi);
let mut l: mut lcd::LCD = lcd as mut lcd::LCD;
l.puts(hello, world);
 
  Which results in a runtime dispatch, a slower and bigger code than the
  one I'd have without a trait.
 
  You can call methods defined on a trait without boxing the object as a
  trait object. The ability to perform dynamic dispatch via a trait object
  is totally optional. The methods can also be called directly, including
  inside a generic function by specifying the trait as a type parameter
  bound. You can simply call the `puts` method directly on the `lcd`
  object without a cast.
 
  A second problem is there is no easy way to write unified code that
  supports both the lcds based on passed in --cfg, as I can't
  apply #[cfg(lcd_c12832)] to a chunk of code in fn, and it's kind of
  problematic to return a LCD out from it given that there is no heap and
  no analog of placement new from C++.
 
  Rust supports generic functions, and you can write code supporting both
  types by making it generic. The choice between static dispatch and
  dynamic dispatch is entirely up to you in the current system.
 
  Proposed binding concept solves those two problems:
 
  #[cfg(lcd_c12832)]
  let Binding: binding {
let lcd: lcd_c12832::C12832;
let main: Main;
 
bind main.lcd = lcd;
  }
 
  at this point of time compiler can be sure about what struct is
  implementing LCD trait for main.lcd and can bind the function bodies as
  compile time, inlining them if applicable.
 
  This also might be something that is already implemented, please advice.
  The goal here is to minimise runtime code being executed and its size.
 
 
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev
 




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Porting some nesC features to rust?

2014-04-08 Thread Vladimir Pouzanov
That actually worked much better than I expected inlining everything and
getting rid of vtables (I don't have support for .data section at the
moment :-) ).

I can't say the syntax is very clear to me, but I can get used to it.
Still, one more question remains. I have a debug output concept, which
means that debug::d(str) gets delivered to either LCD or UART, whatever
is configured at runtime. I do it via static mut:

pub trait Debugger {
  fn debugs(mut self, s: str);
}

pub static mut debug_output: *mut c12332::C12332'static, 'static
spi::SPI = unsafe { init() };

pub fn d(s: str) {
  let debugger = unsafe { mut (*debug_output) as mut Debugger }; //
failed to find an implementation of trait hal::spi::SPI for 'static
hal::spi::SPI:'static
  debugger.debugs(s);
}

pub fn set_debugger(lcd: *mut c12332::C12332spi::SPI) {
  unsafe { debug_output = lcd; };
}

I don't really support UART now, but I'd still like to access my LCD via a
globally known static getter. How can I re-write that with typed struct?


On Tue, Apr 8, 2014 at 6:26 PM, Corey Richardson co...@octayn.net wrote:

 You don't use bounds in the struct, you put them in the impl. So you
 would instead say


 struct LCDS {
   spi: S,
   ...
 }


 and then:

 implS: SPI LCDS {
 ...
 }

 On Tue, Apr 8, 2014 at 1:23 PM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  I might have found an unsupported case.
 
  Consider the following:
 
  trait SPI { ... }
 
  struct McuSPI;
  impl SPI for McuSPI { ... }
 
  struct LCD {
spi: SPI,
...
  }
 
  This code results in a dynamic dispatch to SPI, as trait bounds are not
  allowed in structure definitions. Is it in any way possible to use
 static
  dispatch from LCD to SPI given the exact implementations are known at
  compile time?
 
 
  On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles marci...@gmail.com wrote:
 
  And just in case there is a confusion (as I have noticed others to
  have), it might help to see a specific example comparing static
  dispatch with dynamic.
 
  // This is a single function for all types implementing the LCD Trait.
  fn foo(x : LCD) { // x's type is LCD rather than the actual type of
  the object being passed in
  x.line(); // dynamic dispatch
  }
 
  // Like C++ templates, this generates a function for each type T that
  implements LCD.
  fn fooT : LCD(x : T) { // x's type is T rather than LCD
  x.line(); // static dispatch based on type T known at
 compile-time
  }
 
  On Wed, Apr 2, 2014 at 8:32 AM, Daniel Micay danielmi...@gmail.com
  wrote:
   On 02/04/14 06:25 AM, Vladimir Pouzanov wrote:
   If I get it right, calls to traits are resolved in runtime (so,
 traits
   are kind of similar to C++ virtual methods).
  
   All method calls on regular types are resolved via static dispatch,
   whether or not they come from a trait. For example, consider a generic
   function like the following:
  
   fn minT: TotalOrd(a: T, b: T) - T {
   if a  b { a } else { b }
   }
  
   This function performs a *static* call of the `lt` method defined on
 the
   `Ord` trait that `TotalOrd` inherits from. Generics are fully expanded
   at compile-time just as C++ templates are.
  
   Rust also allows using traits as boxed objects, but this is an
 entirely
   transparent choice. They're almost always used for static dispatch via
   trait bounds on generics, or simply outside of generics.
  
   What I'm proposing here is a compile-time approach.
  
   Let's say we have the following trait:
  
   pub trait LCD {
 fn line(mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, color:
   u8);
 fn rect(mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: u8);
 fn fillrect(mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: i32,
   color: u8);
 fn putc(mut self, value: char);
 fn puts(mut self, s: str);
  
 fn flush(self);
 fn clear(mut self);
   }
  
   which defined a LED screen. There are two structs implementing it:
   C12832 and ILI9341 (two different lcd controllers).
  
   So I want my app to print hello world on lcd, I write the following
   code:
  
 let mut lcd = lcd_c12832::C12832::new(spi);
 let mut l: mut lcd::LCD = lcd as mut lcd::LCD;
 l.puts(hello, world);
  
   Which results in a runtime dispatch, a slower and bigger code than
 the
   one I'd have without a trait.
  
   You can call methods defined on a trait without boxing the object as a
   trait object. The ability to perform dynamic dispatch via a trait
 object
   is totally optional. The methods can also be called directly,
 including
   inside a generic function by specifying the trait as a type parameter
   bound. You can simply call the `puts` method directly on the `lcd`
   object without a cast.
  
   A second problem is there is no easy way to write unified code that
   supports both the lcds based on passed in --cfg, as I can't
   apply #[cfg(lcd_c12832)] to a chunk of code in fn, and it's kind of
   problematic to return a LCD out from it given

Re: [rust-dev] Porting some nesC features to rust?

2014-04-08 Thread Vladimir Pouzanov
Yes, in the end I decided to implement .data section copy over from flash
to ram to get vtables :-)


On Tue, Apr 8, 2014 at 7:34 PM, Corey Richardson co...@octayn.net wrote:

 `'static SPI` is going to be a trait object (with dynamic dispatch).
 The error it's giving is that `SPI` (the trait object) doesn't
 implement `SPI` (the trait). You would have to explicitly implement
 `SPI` for `SPI`. I'm not really sure  how to solve this without using
 trait objects; you seem to want an inherently dynamically-dispatched
 system.

 On Tue, Apr 8, 2014 at 2:08 PM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  That actually worked much better than I expected inlining everything and
  getting rid of vtables (I don't have support for .data section at the
 moment
  :-) ).
 
  I can't say the syntax is very clear to me, but I can get used to it.
 Still,
  one more question remains. I have a debug output concept, which means
 that
  debug::d(str) gets delivered to either LCD or UART, whatever is
 configured
  at runtime. I do it via static mut:
 
  pub trait Debugger {
fn debugs(mut self, s: str);
  }
 
  pub static mut debug_output: *mut c12332::C12332'static, 'static
 spi::SPI
  = unsafe { init() };
 
  pub fn d(s: str) {
let debugger = unsafe { mut (*debug_output) as mut Debugger }; //
 failed
  to find an implementation of trait hal::spi::SPI for 'static
  hal::spi::SPI:'static
debugger.debugs(s);
  }
 
  pub fn set_debugger(lcd: *mut c12332::C12332spi::SPI) {
unsafe { debug_output = lcd; };
  }
 
  I don't really support UART now, but I'd still like to access my LCD via
 a
  globally known static getter. How can I re-write that with typed struct?
 
 
  On Tue, Apr 8, 2014 at 6:26 PM, Corey Richardson co...@octayn.net
 wrote:
 
  You don't use bounds in the struct, you put them in the impl. So you
  would instead say
 
 
  struct LCDS {
spi: S,
...
  }
 
 
  and then:
 
  implS: SPI LCDS {
  ...
  }
 
  On Tue, Apr 8, 2014 at 1:23 PM, Vladimir Pouzanov farcal...@gmail.com
  wrote:
   I might have found an unsupported case.
  
   Consider the following:
  
   trait SPI { ... }
  
   struct McuSPI;
   impl SPI for McuSPI { ... }
  
   struct LCD {
 spi: SPI,
 ...
   }
  
   This code results in a dynamic dispatch to SPI, as trait bounds are
 not
   allowed in structure definitions. Is it in any way possible to use
   static
   dispatch from LCD to SPI given the exact implementations are known at
   compile time?
  
  
   On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles marci...@gmail.com
 wrote:
  
   And just in case there is a confusion (as I have noticed others to
   have), it might help to see a specific example comparing static
   dispatch with dynamic.
  
   // This is a single function for all types implementing the LCD
 Trait.
   fn foo(x : LCD) { // x's type is LCD rather than the actual type of
   the object being passed in
   x.line(); // dynamic dispatch
   }
  
   // Like C++ templates, this generates a function for each type T that
   implements LCD.
   fn fooT : LCD(x : T) { // x's type is T rather than LCD
   x.line(); // static dispatch based on type T known at
   compile-time
   }
  
   On Wed, Apr 2, 2014 at 8:32 AM, Daniel Micay danielmi...@gmail.com
   wrote:
On 02/04/14 06:25 AM, Vladimir Pouzanov wrote:
If I get it right, calls to traits are resolved in runtime (so,
traits
are kind of similar to C++ virtual methods).
   
All method calls on regular types are resolved via static dispatch,
whether or not they come from a trait. For example, consider a
generic
function like the following:
   
fn minT: TotalOrd(a: T, b: T) - T {
if a  b { a } else { b }
}
   
This function performs a *static* call of the `lt` method defined
 on
the
`Ord` trait that `TotalOrd` inherits from. Generics are fully
expanded
at compile-time just as C++ templates are.
   
Rust also allows using traits as boxed objects, but this is an
entirely
transparent choice. They're almost always used for static dispatch
via
trait bounds on generics, or simply outside of generics.
   
What I'm proposing here is a compile-time approach.
   
Let's say we have the following trait:
   
pub trait LCD {
  fn line(mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32,
 color:
u8);
  fn rect(mut self, x0: i32, y0: i32, x1: i32, y1: i32, color:
 u8);
  fn fillrect(mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b:
 i32,
color: u8);
  fn putc(mut self, value: char);
  fn puts(mut self, s: str);
   
  fn flush(self);
  fn clear(mut self);
}
   
which defined a LED screen. There are two structs implementing it:
C12832 and ILI9341 (two different lcd controllers).
   
So I want my app to print hello world on lcd, I write the
 following
code:
   
  let mut lcd = lcd_c12832::C12832::new(spi);
  let mut l: mut lcd::LCD = lcd as mut lcd

Re: [rust-dev] Building a static array of pointers

2014-04-05 Thread Vladimir Pouzanov
Ended up specifying array size as per Simon's suggestion:

#[link_section=.isr_vector_temp]
#[no_mangle]
pub static ISRVectors: [extern unsafe fn(), ..4] = [
  _stack_base,
  main,
  isr_nmi,
  isr_hardfault,
];

Given that table size is an architecture-dependent time constant, it also
adds a tiny bit of verification that all ISRs are defined.

Also tried defining something along the lines of *[extern unsafe fn()], but
I guess size is also required in this case.

Thanks all!



On Sat, Apr 5, 2014 at 12:00 PM, Corey Richardson co...@octayn.net wrote:

 A C-style array is written `*T`, much like in C (note: I'm not saying
 `T*` and `T[]` are the same type, I know they aren't)

 On Sat, Apr 5, 2014 at 6:53 AM, Simon Sapin simon.sa...@exyr.org wrote:
  On 05/04/2014 11:39, Vladimir Pouzanov wrote:
 
  The problem is that [extern unsafe fn()] results in 8 bytes, pointer to
  the actual array and its size. Is there any way I can get a plain
  C-style array in rust?
 
 
  If the size is known as compile-time you can use:
 
  static table: [extern unsafe fn(), ..2] = [foo, bar];
 
  --
  Simon Sapin
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev



 --
 http://octayn.net/
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] matching on a few bits in int

2014-04-04 Thread Vladimir Pouzanov
I've submitted an RFC for this one:
https://github.com/rust-lang/rfcs/pull/29


On Sat, Mar 29, 2014 at 6:14 PM, Bill Myers bill_my...@outlook.com wrote:

 I think the best solution is to add uN and sN types where N is not a power
 of two, which LLVM should already support.

 Then you can write your match like this:
 match (val  6) as u2
 {
   ...
 }

 And it will work as desired.

 Biggest issue is that to make it work nicely you'd need to add some way to
 generalize over the bit-length and integers, and that's going to require
 generics with int parameters and work to add those.




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Building a static array of pointers

2014-04-04 Thread Vladimir Pouzanov
Is it possible to port the following C code to rust?

__attribute__ ((section(.isr_vector)))
void (* const isr_vector_table[])(void) = {
_stack_base,
main, // Reset
isr_nmi,  // NMI
isr_hardfault,// Hard Fault
0,// CM3 Memory Management Fault
0,// CM3 Bus Fault
0,// CM3 Usage Fault
_boot_checksum,  // NXP Checksum code
0,// Reserved
0,// Reserved
0,// Reserved
isr_svcall,   // SVCall
0,// Reserved for debug
0,// Reserved
isr_pendsv,   // PendSV
isr_systick,  // SysTick
};

here main and isr_* are rust external functions, and _stack_base is defined
as

  extern void _stack_base()

and gets loaded from linker script.

Also, is it possible to make a weak symbol in rust or somehow emulate it?
Weak symbols are used in C code to provide the following functionality:
isr_* functions are stubs with default implementation (morse out id code
with led, loop forever), but if any of those requires actual code, than it
is overrides the weak morse-blinking function symbol.

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Porting some nesC features to rust?

2014-04-02 Thread Vladimir Pouzanov
If I get it right, calls to traits are resolved in runtime (so, traits are
kind of similar to C++ virtual methods).

What I'm proposing here is a compile-time approach.

Let's say we have the following trait:

pub trait LCD {
  fn line(mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, color: u8);
  fn rect(mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: u8);
  fn fillrect(mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: i32, color:
u8);
  fn putc(mut self, value: char);
  fn puts(mut self, s: str);

  fn flush(self);
  fn clear(mut self);
}

which defined a LED screen. There are two structs implementing it: C12832
and ILI9341 (two different lcd controllers).

So I want my app to print hello world on lcd, I write the following code:

  let mut lcd = lcd_c12832::C12832::new(spi);
  let mut l: mut lcd::LCD = lcd as mut lcd::LCD;
  l.puts(hello, world);

Which results in a runtime dispatch, a slower and bigger code than the one
I'd have without a trait.

A second problem is there is no easy way to write unified code that
supports both the lcds based on passed in --cfg, as I can't
apply #[cfg(lcd_c12832)] to a chunk of code in fn, and it's kind of
problematic to return a LCD out from it given that there is no heap and no
analog of placement new from C++.

Proposed binding concept solves those two problems:

#[cfg(lcd_c12832)]
let Binding: binding {
  let lcd: lcd_c12832::C12832;
  let main: Main;

  bind main.lcd = lcd;
}

at this point of time compiler can be sure about what struct is
implementing LCD trait for main.lcd and can bind the function bodies as
compile time, inlining them if applicable.

This also might be something that is already implemented, please advice.
The goal here is to minimise runtime code being executed and its size.


On Mon, Mar 31, 2014 at 3:06 PM, Daniel Micay danielmi...@gmail.com wrote:

 I'm not really sure exactly what it being proposed here.

 Rust's generic types and functions are already entirely expanded at
 compile-time. You *can* use traits as objects for dynamic dispatch, but
 it's not how they're used in the vast majority of cases.




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] A new better way to build rust apps

2014-04-01 Thread Vladimir Pouzanov
I decided to switch away from Rakefiles (after I switched to them from
Makefiles) and make a dependency generator / build system in rust to get
20% more coolness factor.

Here's a sample config file:
https://gist.github.com/farcaller/4c08908fe526e0631989. As you can see, the
syntax is somewhat similar to rust code itself, with a few interesting bits
like ~ sigil resolving to 'build' dir and @ sigil resolving to 'src' dir,
so you can use relative paths safely (Rustfiles are all about safety, you
know). It also supports named chainable configurations, so that you can
define all the possible build options in one single file, generics (for
rules expansion) and a background daemon that looks for files being
modified in @ scope to make compilation even faster.

TL;DR: Happy April fools' day :-)

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Static_assert on a hash

2014-03-31 Thread Vladimir Pouzanov
That actually sounds like a good option, thanks!


On Sun, Mar 30, 2014 at 11:22 PM, comex com...@gmail.com wrote:

 On Sun, Mar 30, 2014 at 8:08 AM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
gpio::Pin::new(0, 15, gpio::Out, gpio::UART1_TXD); // p13 - TXD
 
  compiles, but something like
 
gpio::Pin::new(0, 15, gpio::Out, gpio::SPI_MISO); // p13 - TXD
 
  would fail, because there's no SPI_MISO defined for port 0 pin 15.

 I would have each port/pin combination be a separate function or
 object which takes an appropriate enum as an argument for the
 function, maybe fn new_port0_pin15(func: Port0Pin15Func) or set up
 objects so that port0.pin15.init(...) works.  You could use a macro
 to define these more easily.

 If you really want to write '(0, 15', you could use a macro to turn
 that into the preceding, but I wouldn't.




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Porting some nesC features to rust?

2014-03-31 Thread Vladimir Pouzanov
I'd like to propose to extend the language with some concepts from nesC,
which is a nice but quite unknown C superset outside of TinyOS world.

The concept would allow better static polymorphism and better code
optimisations and is loosely based on nesC modules/components. It might be
possible to implement the same in rust without extending the syntax and
compiler, please tell me if that's the case.

unbound struct S {
  reg: u32,
  comp: ~T,
}

defines a struct that has a u32 value and some trait. Those values could be
used in S impls as usual.

It is impossible to create an instance of S, the only way to get it is to
bind it in compile time:

let Binding: binding {
  let SImpl: S;
  let TImpl: T;

  bind SImpl.reg = 0x12345678;
  bind SImpl.comp = TImpl;
}

The result of this is that all references to reg and comp are replaced by
actual values (TImpl must obviously be an unbound struct as well), so that
the whole SImpl could be optimised away and don't use any storage bytes
other than required by constants.

Why is it useful? Embedded systems are commonly represented as a tree of
components hooked up to one another. Also, resources on embedded are used
to be expensive. This code allows to define a configuration of a system
which is completely resolved in compile time, allowing better optimisation
of the code while maintaining readable code.

Some close-to-real-life example:

unbound struct Led;
impl Led {
  pub fn set_enabled(self, enabled: bool) {
// set the led state
  }
}

trait Callable {
  fn callback(self);
}
unbound struct Timer {
  actor: ~Callable,
}
impl Timer {
  pub fn start(self) {
// init the timer, hardware will call fired() via ISR
  }
  fn fired(self) {
actor.callback();
  }
}

unbound struct Blinker {
  mut state: bool,
  led: Led,
  timer: Timer,
}
impl Callable for Blinker {
  fn callback(self) {
self.state != self.state;
led.set_enabled(self.state);
  }
}
impl Blinker {
  pub fn main(self) {
self.timer.start();
  }
}

let Binding: binding {
  let timer = Timer;
  let led = Led;
  let blinker = Blinker { state: false }; // we can also set the mut
property here. This one is static mut by nature, but available only in
Blinker impl.

  bind timer.actor = blinker;
  bind blinker.timer = timer;
  bind blinker.led = led;
}

pub fn main() {
  Binding.blinker.start();
}

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Static_assert on a hash

2014-03-30 Thread Vladimir Pouzanov
That shifts the issue even more into runtime, doesn't it?

My goal is to find a way to resolve a tuple of (u8, u8, FuncNameEnum) to
u8, where FuncNameEnum is a long enum of all possible functions. And I need
to do that in compile time.

One way I see that is to make a really long list of enums like:

PORT0_PIN0_GPIO,
PORT0_PIN0_RD1,
...

for all possible port/pin/function combinations, then I can make a macro to
match on that to port/pin/fun u8 (that are actually used to configure
registers). The only thing is that I'd like to pass port and pin in as u8
values, that makes it much more readable.

Well... Maybe it's time to do some big macro for matching all the stuff and
hope that compiler will optimise it anyway.


On Sun, Mar 30, 2014 at 10:12 AM, Simon Sapin simon.sa...@exyr.org wrote:

 On 30/03/2014 09:50, Vladimir Pouzanov wrote:

 I have a chunk of code that toggles different functions on hardware
 pins, that looks like this:

enum Function {
  GPIO = 0,
  F1 = 1,
  F2 = 2,
  F3 = 3,
}
fn set_mode(port: u8, pin: u8, fun: Function)

 What I would like to have is an enum of human-readable values instead of
 F1/F2/F3

 [...]


 let fun_idx: u8 = FUNCTIONS[port][pin][fun]



 I don’t know if you can directly access the static strings for the
 variants’ names behind this, but you can use #[deriving(Show)] to get a
 string representation of any enum value:

 For example:

 #[deriving(Show)]

 enum Function {
 GPIO = 0,
 F1 = 1,
 F2 = 2,
 F3 = 3,
 }

 fn main() {
 let f = GPIO;

 println!({:?}, f)

 let s: ~str = format!({:?}, f);
 println!({}, s)
 }

 Output:

 GPIO
 GPIO

 --
 Simon Sapin
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Static_assert on a hash

2014-03-30 Thread Vladimir Pouzanov
Ok, so I have a number of hardware pins which are defined by port+pin
numbers. Each pin can be connected to different peripheral (e.g. generic
purpose i/o, serial, analog in) which defines it's function.

So, to configure that I have a few u32 registers where each pair of bits
defines a function for a pin, so my configuration function is:

  fn set_mode(port: u8, pin: u8, fun: Function)

You pass in port, pin and it's function, and i/o is being reconfigured
appropriately.

What I have now is this enum:

enum Function {
GPIO = 0,
F1 = 1,
F2 = 2,
F3 = 3,
}

which defines pin's function (function 0 is always GPIO on all the pins,
functions 1-3 are different based on the pin).

Now, in some peripheral init code I write something like:

  gpio::Pin::new(0, 15, gpio::Out, gpio::F1); // p13 - TXD

and I know that function 1 on port 0 pin 15 is TXD for UART1. I could have
misread the docs and write F2, which would compile, but the code wouldn't
configure the UART pin but do something else, so I want the compiler to
check code for me so that

  gpio::Pin::new(0, 15, gpio::Out, gpio::UART1_TXD); // p13 - TXD

compiles, but something like

  gpio::Pin::new(0, 15, gpio::Out, gpio::SPI_MISO); // p13 - TXD

would fail, because there's no SPI_MISO defined for port 0 pin 15.


On Sun, Mar 30, 2014 at 11:41 AM, Simon Sapin simon.sa...@exyr.org wrote:

 On 30/03/2014 10:30, Vladimir Pouzanov wrote:

 That shifts the issue even more into runtime, doesn't it?

 My goal is to find a way to resolve a tuple of (u8, u8, FuncNameEnum) to
 u8, where FuncNameEnum is a long enum of all possible functions. And I
 need to do that in compile time.

 One way I see that is to make a really long list of enums like:

 PORT0_PIN0_GPIO,
 PORT0_PIN0_RD1,
 ...

 for all possible port/pin/function combinations, then I can make a macro
 to match on that to port/pin/fun u8 (that are actually used to configure
 registers). The only thing is that I'd like to pass port and pin in as
 u8 values, that makes it much more readable.

 Well... Maybe it's time to do some big macro for matching all the stuff
 and hope that compiler will optimise it anyway.


 I’m sorry, it looks like I completely misunderstood your original message.
 But then it’s still not clear to me what you’re trying to do. Could you
 explain in more details, with more context? For example, what is it you
 call a function? It seems not to be Rust function declared with the `fn`
 keyword.

 --
 Simon Sapin




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] matching on a few bits in int

2014-03-28 Thread Vladimir Pouzanov
There's one thing that I often have to deal in embedded code — doing match
on a few bits from an I/O register, which is commonly u32:

let val : u32 = ...;
match (val  0b11)  6 {
  0b00 = ...,
  0b01 = ...,
  0b10 = ...,
  _ = {}
}

You can clearly see two problems here: I need to provide a catch-all match,
even if the code guarantees a limited set of values; also I lost 0b11, and
there's no warning due to catch all.

Is it possible to make rustc aware of such cases?

What would be totally awesome is some kind of [] operator for ints, that
would extract bits, like that:

match val[6..7] { ... }

Is that something of interest to community? I would be willing to write an
RFC for that, and possibly extend the compiler.

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] matching on a few bits in int

2014-03-28 Thread Vladimir Pouzanov
Sorry, that's definitely a typo, (val  6)  0b11 makes sense, (val 
0b11)  6 does not.


On Fri, Mar 28, 2014 at 1:04 PM, Clark Gaebel cgae...@uwaterloo.ca wrote:

 I like this! Although I think that match might've been better written
 `(val  6)  0b11`, but it'd be really nice for the compiler to catch
 those type of errors!

   - Clark


 On Fri, Mar 28, 2014 at 5:54 AM, Vladimir Pouzanov farcal...@gmail.comwrote:

 There's one thing that I often have to deal in embedded code — doing
 match on a few bits from an I/O register, which is commonly u32:

 let val : u32 = ...;
 match (val  0b11)  6 {
   0b00 = ...,
   0b01 = ...,
   0b10 = ...,
   _ = {}
 }

 You can clearly see two problems here: I need to provide a catch-all
 match, even if the code guarantees a limited set of values; also I lost
 0b11, and there's no warning due to catch all.

 Is it possible to make rustc aware of such cases?

 What would be totally awesome is some kind of [] operator for ints, that
 would extract bits, like that:

 match val[6..7] { ... }

 Is that something of interest to community? I would be willing to write
 an RFC for that, and possibly extend the compiler.

 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev




 --
 Clark.

 Key ID : 0x78099922
 Fingerprint: B292 493C 51AE F3AB D016  DD04 E5E3 C36F 5534 F907




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] How do I pass -march down to llvm from rustc?

2014-03-23 Thread Vladimir Pouzanov
I'm trying to experiment with rust and some embedded code. Currently I have
to do a three-pass compilation:

rustc --target arm-linux-eabi -O --emit bc main.rs -o main.bc
llc -mtriple arm-none-eabi -march=thumb -mcpu=cortex-m0 main.bc -o main.s
arm-none-linux-gnueabi-as main.s -o main.o

First, I'm not sure how relevant is --target flag for rustc. I seems to
change target datalayout/triple in generated bc, but that should be
overriden by llc -mtriple anyway, right?

Second, I can pass -Ctarget-cpu=cortex-m0, but I cannot pass down
-march=thumb, tried this way: -Cllvm-args='--march=thumb', failed with
rustc: Unknown command line argument '--march=thumb'.

Any hints on how can I drop explicit llc and as steps here?

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] How do I pass -march down to llvm from rustc?

2014-03-23 Thread Vladimir Pouzanov
Nevermind, I lost -O somewhere in between copying and pasting command line
flags. Optimised version doesn't have any morestack references (which is
strange concept though).


On Sun, Mar 23, 2014 at 5:44 PM, Vladimir Pouzanov farcal...@gmail.comwrote:

 Figured out I can use --target thumbv6m-linux-eabi, which implies -mthumb.
 Now the problem is that if I use

 rustc --target thumbv6m-linux-eabi -O --emit obj main.rs -o main.o

 instead of three-step process I mentioned before, I get a valid object
 file for cortex-m0, but functions have big prologues and symbol table is
 much bigger:

  U STACK_LIMIT
  U _GLOBAL_OFFSET_TABLE_
  D _ZN20_rust_crate_map_main16ad67637f924a5c794v0.0E
 0008 r _ZN2hw11GPIO_PIN_NO20hb0b70c1482b61788Gaa4v0.0E
  r _ZN2hw12GPIO_DIR_REG20hb0b70c1482b61788yaa4v0.0E
 0004 r _ZN2hw12GPIO_REG_VAL20hb0b70c1482b61788Caa4v0.0E
 0078 t _ZN4main10__rust_abiE
  t _ZN4wait20h53ffb23463e08f19Maa4v0.0E
  U __aeabi_unwind_cpp_pr0
  U __morestack
 004c T main

 vs.

  D _ZN23_rust_crate_map_main.c016ad67637f924a5c794v0.0E
  T main

 in the initial version. Also, I now need to provide __morestack (no idea
 what's that about).


 On Sun, Mar 23, 2014 at 5:17 PM, Alex Crichton a...@crichton.co wrote:

 You should be able to assemble standalone objects for any triple
 through rustc itself, you'll likely have to specify a different linker
 or assembler though:

 rustc foo.rs --target arm-non-linux-gnueabi \
 -C linker=arm-non-linux-gnueabi-ld \
 -C ar=arm-non-linux-gnueabi-ar

 As you discovered, you can pass through arguments to LLVM via the -C
 llvm-args=foo command line option to rustc. If you get complaints
 that it's an unknown command line argument, it's LLVM telling you
 those complaints, not rustc.

 On Sun, Mar 23, 2014 at 8:54 AM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  I'm trying to experiment with rust and some embedded code. Currently I
 have
  to do a three-pass compilation:
 
  rustc --target arm-linux-eabi -O --emit bc main.rs -o main.bc
  llc -mtriple arm-none-eabi -march=thumb -mcpu=cortex-m0 main.bc -o
 main.s
  arm-none-linux-gnueabi-as main.s -o main.o
 
  First, I'm not sure how relevant is --target flag for rustc. I seems to
  change target datalayout/triple in generated bc, but that should be
  overriden by llc -mtriple anyway, right?
 
  Second, I can pass -Ctarget-cpu=cortex-m0, but I cannot pass down
  -march=thumb, tried this way: -Cllvm-args='--march=thumb', failed with
  rustc: Unknown command line argument '--march=thumb'.
 
  Any hints on how can I drop explicit llc and as steps here?
 
  --
  Sincerely,
  Vladimir Farcaller Pouzanov
  http://farcaller.net/
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev
 




 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] How do I pass -march down to llvm from rustc?

2014-03-23 Thread Vladimir Pouzanov
So it doesn't work in the end.

rustc --emit bc with flags set for cortex-m0 provides exact same bc with
only difference in target triple (which makes perfect sense)

However, replacing llc step with rustc --emit asm provides a different
assembler file, which requires __morestack.

Should I expect rustc to generate freestanding code given some additional
options?


On Sun, Mar 23, 2014 at 5:55 PM, Vladimir Pouzanov farcal...@gmail.comwrote:

 Nevermind, I lost -O somewhere in between copying and pasting command line
 flags. Optimised version doesn't have any morestack references (which is
 strange concept though).


 On Sun, Mar 23, 2014 at 5:44 PM, Vladimir Pouzanov farcal...@gmail.comwrote:

 Figured out I can use --target thumbv6m-linux-eabi, which implies
 -mthumb. Now the problem is that if I use

 rustc --target thumbv6m-linux-eabi -O --emit obj main.rs -o main.o

 instead of three-step process I mentioned before, I get a valid object
 file for cortex-m0, but functions have big prologues and symbol table is
 much bigger:

  U STACK_LIMIT
  U _GLOBAL_OFFSET_TABLE_
  D _ZN20_rust_crate_map_main16ad67637f924a5c794v0.0E
 0008 r _ZN2hw11GPIO_PIN_NO20hb0b70c1482b61788Gaa4v0.0E
  r _ZN2hw12GPIO_DIR_REG20hb0b70c1482b61788yaa4v0.0E
 0004 r _ZN2hw12GPIO_REG_VAL20hb0b70c1482b61788Caa4v0.0E
 0078 t _ZN4main10__rust_abiE
  t _ZN4wait20h53ffb23463e08f19Maa4v0.0E
  U __aeabi_unwind_cpp_pr0
  U __morestack
 004c T main

 vs.

  D _ZN23_rust_crate_map_main.c016ad67637f924a5c794v0.0E
  T main

 in the initial version. Also, I now need to provide __morestack (no idea
 what's that about).


 On Sun, Mar 23, 2014 at 5:17 PM, Alex Crichton a...@crichton.co wrote:

 You should be able to assemble standalone objects for any triple
 through rustc itself, you'll likely have to specify a different linker
 or assembler though:

 rustc foo.rs --target arm-non-linux-gnueabi \
 -C linker=arm-non-linux-gnueabi-ld \
 -C ar=arm-non-linux-gnueabi-ar

 As you discovered, you can pass through arguments to LLVM via the -C
 llvm-args=foo command line option to rustc. If you get complaints
 that it's an unknown command line argument, it's LLVM telling you
 those complaints, not rustc.

 On Sun, Mar 23, 2014 at 8:54 AM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  I'm trying to experiment with rust and some embedded code. Currently I
 have
  to do a three-pass compilation:
 
  rustc --target arm-linux-eabi -O --emit bc main.rs -o main.bc
  llc -mtriple arm-none-eabi -march=thumb -mcpu=cortex-m0 main.bc -o
 main.s
  arm-none-linux-gnueabi-as main.s -o main.o
 
  First, I'm not sure how relevant is --target flag for rustc. I seems to
  change target datalayout/triple in generated bc, but that should be
  overriden by llc -mtriple anyway, right?
 
  Second, I can pass -Ctarget-cpu=cortex-m0, but I cannot pass down
  -march=thumb, tried this way: -Cllvm-args='--march=thumb', failed with
  rustc: Unknown command line argument '--march=thumb'.
 
  Any hints on how can I drop explicit llc and as steps here?
 
  --
  Sincerely,
  Vladimir Farcaller Pouzanov
  http://farcaller.net/
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev
 




 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/




 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] How do I pass -march down to llvm from rustc?

2014-03-23 Thread Vladimir Pouzanov
Thanks for links to bugs.

Is there anything to read on the whole morestack thing? I thought that it's
connected to segmented stacks that are (are they?) going away.

It seems that I can use #[no_split_stack] before each and every function to
generate a valid freestanding binary. If I just could use that in header...


On Sun, Mar 23, 2014 at 6:24 PM, Corey Richardson co...@octayn.net wrote:

 No. See https://github.com/mozilla/rust/pull/8955 and
 https://github.com/mozilla/rust/issues/11871 for discussion. You can
 stub out
 morestack but that won't remove the stack size checks. It's sanest to
 just compile the IR yourself (the stack checking is a target-specific
 machine pass, which is why it shows up with --emit asm but not --emit
 bc)

 On Sun, Mar 23, 2014 at 2:09 PM, Vladimir Pouzanov farcal...@gmail.com
 wrote:
  So it doesn't work in the end.
 
  rustc --emit bc with flags set for cortex-m0 provides exact same bc with
  only difference in target triple (which makes perfect sense)
 
  However, replacing llc step with rustc --emit asm provides a different
  assembler file, which requires __morestack.
 
  Should I expect rustc to generate freestanding code given some additional
  options?
 
 
  On Sun, Mar 23, 2014 at 5:55 PM, Vladimir Pouzanov farcal...@gmail.com
  wrote:
 
  Nevermind, I lost -O somewhere in between copying and pasting command
 line
  flags. Optimised version doesn't have any morestack references (which is
  strange concept though).
 
 
  On Sun, Mar 23, 2014 at 5:44 PM, Vladimir Pouzanov farcal...@gmail.com
 
  wrote:
 
  Figured out I can use --target thumbv6m-linux-eabi, which implies
  -mthumb. Now the problem is that if I use
 
  rustc --target thumbv6m-linux-eabi -O --emit obj main.rs -o main.o
 
  instead of three-step process I mentioned before, I get a valid object
  file for cortex-m0, but functions have big prologues and symbol table
 is
  much bigger:
 
   U STACK_LIMIT
   U _GLOBAL_OFFSET_TABLE_
   D _ZN20_rust_crate_map_main16ad67637f924a5c794v0.0E
  0008 r _ZN2hw11GPIO_PIN_NO20hb0b70c1482b61788Gaa4v0.0E
   r _ZN2hw12GPIO_DIR_REG20hb0b70c1482b61788yaa4v0.0E
  0004 r _ZN2hw12GPIO_REG_VAL20hb0b70c1482b61788Caa4v0.0E
  0078 t _ZN4main10__rust_abiE
   t _ZN4wait20h53ffb23463e08f19Maa4v0.0E
   U __aeabi_unwind_cpp_pr0
   U __morestack
  004c T main
 
  vs.
 
   D _ZN23_rust_crate_map_main.c016ad67637f924a5c794v0.0E
   T main
 
  in the initial version. Also, I now need to provide __morestack (no
 idea
  what's that about).
 
 
  On Sun, Mar 23, 2014 at 5:17 PM, Alex Crichton a...@crichton.co
 wrote:
 
  You should be able to assemble standalone objects for any triple
  through rustc itself, you'll likely have to specify a different linker
  or assembler though:
 
  rustc foo.rs --target arm-non-linux-gnueabi \
  -C linker=arm-non-linux-gnueabi-ld \
  -C ar=arm-non-linux-gnueabi-ar
 
  As you discovered, you can pass through arguments to LLVM via the -C
  llvm-args=foo command line option to rustc. If you get complaints
  that it's an unknown command line argument, it's LLVM telling you
  those complaints, not rustc.
 
  On Sun, Mar 23, 2014 at 8:54 AM, Vladimir Pouzanov 
 farcal...@gmail.com
  wrote:
   I'm trying to experiment with rust and some embedded code.
 Currently I
   have
   to do a three-pass compilation:
  
   rustc --target arm-linux-eabi -O --emit bc main.rs -o main.bc
   llc -mtriple arm-none-eabi -march=thumb -mcpu=cortex-m0 main.bc -o
   main.s
   arm-none-linux-gnueabi-as main.s -o main.o
  
   First, I'm not sure how relevant is --target flag for rustc. I seems
   to
   change target datalayout/triple in generated bc, but that should be
   overriden by llc -mtriple anyway, right?
  
   Second, I can pass -Ctarget-cpu=cortex-m0, but I cannot pass down
   -march=thumb, tried this way: -Cllvm-args='--march=thumb', failed
 with
   rustc: Unknown command line argument '--march=thumb'.
  
   Any hints on how can I drop explicit llc and as steps here?
  
   --
   Sincerely,
   Vladimir Farcaller Pouzanov
   http://farcaller.net/
  
   ___
   Rust-dev mailing list
   Rust-dev@mozilla.org
   https://mail.mozilla.org/listinfo/rust-dev
  
 
 
 
 
  --
  Sincerely,
  Vladimir Farcaller Pouzanov
  http://farcaller.net/
 
 
 
 
  --
  Sincerely,
  Vladimir Farcaller Pouzanov
  http://farcaller.net/
 
 
 
 
  --
  Sincerely,
  Vladimir Farcaller Pouzanov
  http://farcaller.net/
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev
 



 --
 http://octayn.net/




-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev