COOKIES! This blog uses cookies!
I am completely out of control of cookies here, otherwise I would have disabled them (it is controlled by the platform).
If you don't like cookies and being tracked please leave this blog immediately.

Tuesday, 26 April 2016

Call Rust from NodeJS via cross-platform C ABI with RuNo bridge

The RuNo bridge is a command line tool which generates C++ code for NodeJS addon from Rust code or from JSON definition (with JSON definition it should work with any C ABI compatible library, of course when implemented functionality is enough).

I've implemeted this tool after my last research on calling Rust from Node JS.

The parser of RuNo bridge does not do magical deep analysis of code, it just detects the following signatures in your code:

#[no_mangle]

pub extern "C" fn ...


it does not require any C++ knowledge from developer if you use primitives mentioned above and your Rust ABI interface complies with simple requirements:

  • All your ABI functoins should be listed in one Rust file;
  • Your library should use crate libc;
  • Each ABI function should be preceeded with #[no_mangle];
  • Each ABI function should be prefixed with pub extern "C";
  • ABI Functions should only take params of c_int,c_float,c_double or *c_char (as a C string with EOF);
  • ABI Functions should return either one of c_int,c_float,c_double or *c_char (as a C string with EOF)
It is tested on Windows, Mac OS and Ubuntu, however it has some limitations developer should know:


The package itself does not need Rust or C++ with node-gyp, it just emits a C++ source file.

However in order to build the source code, rust and C++ compiler should be compatible with NodeJS version installed. It is particularly important on Windows, where Rust target should be MSVC not GNU. For example, if one using 32 bit NodeJS on Windows this one should use target i686-pc-windows-msvc, if 64 bit Node then Rust should be configured with x86_64-pc-windows-msvc compile target. The same about C++: Everything is mostrly smooth on platforms with GCC, and a bit painful with MS Visual C++, please refer to node-gyp installation instructions for details.

You can find simple usage examples on the github: https://github.com/andruhon/runo-bridge-example

I will appreciate any comments or contribution.

Friday, 26 February 2016

Call Rust from NodeJS via cross-platform C ABI

Rust language is quite elegant and looks like a decent replacement to C. There are already many useful packages in Crates available. It is quite good for developing libraries.

Let’s try to develop a Rust addon for NodeJS. It is possible to use node-ffi to call Rust from NodeJS, however FFI is very slow to init [results]. Node/V8 itself is written in C++ and it is possible to build custom C++ extensions and link the Rust library via the C ABI almost at no performance cost !

You can go directly to more complex example on github, if you can’t wait:
One critical moment to note: Rust and VC++ compilers should be of the same architecture as target NodeJS. Say if one using 32 bit NodeJS on windows one should use target i686-pc-windows-msvc, if 64bt Node then Rust should be configured with x86_64-pc-windows-msvc compile target. For linux x86_64-linux-gnu or i686-linux-gnu appropriately.

C++
#include <node.h>

using namespace v8;

extern "C" {
   extern int32_t add_in_rust(int32_t input, int32_t input);
}

void add_in_rust_wrapper(const FunctionCallbackInfo<Value>& args) {
   Isolate* isolate = Isolate::GetCurrent();
   HandleScope scope(isolate);
   int32_t value1 = args[0]->NumberValue();
   int32_t value2 = args[1]->NumberValue();
   args.GetReturnValue().Set(Number::New(isolate, add_in_rust(value1, value2)));
}

void init(Handle<Object> exports) {
   NODE_SET_METHOD(exports, "function_in_rust", add_in_rust_wrapper);
}

NODE_MODULE(addon, init)

Rust
#[no_mangle]
pub extern "C" fn fibonacci(v1: i32, v2: i32) -> i32 {
    v1 + v2
}
I used 32 bit int here, to simplify the example, however it is possible to accept and return `c_int` with crate libc, like that:
extern crate libc;
use libc::c_int;
//use `c_int` as platform int primitive, and ordinary `int` in the C++ addon.


Have a look at my examples set, to find something more useful than just an int:

https://github.com/andruhon/rust-in-node-examples , which generally contains following things:
  • int to int function
  • string to string function
  • numeric array to numeric array function
  • void to struct as an object
  • struct as object to bool
  • callbacks and mutable state

Other options:

https://github.com/rustbridge/neon/ - it is possible to do quite a lot with Neon, however it is more difficult than FFI because in Rust you have to be aware of underlying V8 types and perform manipulations with them. Neon also has platform compatibility issues and a bit overengineered on my opinion.

https://github.com/andruhon/runo-bridge - the command line tool: you feed Rust souce file with `no_mangle extern "C"` functions, or interface definition as a JSON and it will generate some C++ boilerplate code for addon. It just a prototype, which accepts/returns only `void`, `int`, `bool` and `*char`(C string) at a moment. I’ll keep improving it.


A few more articles on integrating Rust with NodeJS coming soon...

Tuesday, 26 January 2016

OpenJDK finally ported to iOS

Someone Johan has recently "run an application using Gluon Charm (Material Design UI controls) on top
of JavaFX (OpenJFX 9) on top of Java on my iPad mini, so this is a real-world complete stack."

MobileJDK is still under heavy development, however it is a good result! Port to is achieved with Zero interpreter due to the fact that Apple does not allow dynamic code generation on iOS.

Thursday, 14 January 2016

Tox - open source replacement for proprietary IM protocols (such as skype)

Tox is an open source instant messaging protocol supporting text, sending files,
video chats and so on.
qTox, µTox, Antox, Toxic, Antidote and others
are open source clients for this protocol.

Available on Linux, Windows, Mac OS, Android, iOS
and anywhere you ready to port it
https://tox.chat/

Unlike Skype and ICQ Tox using decentralized DHT network for p2p communication.
User ID (hash) looks like
0ECA261D206B8D3899A8B0B751BF37206E3CCD73ACE2C4C3B79A9CB9505B301C642D14F43AD7


Tox FAQ:
https://wiki.tox.chat/users/faq
Here's a list of Tox bootstrap nodes for DHT network:
https://nodes.tox.chat/

There's also so called ToxDNS for shorter and human readable contact names.
It is possible to use 3rd party DNS or to establish own one:
https://wiki.tox.chat/users/toxdns
(it is considered to be less safe than hash, however if you control own DNS it should not be a problem)

Link to the Tox Core repo:
https://github.com/irungentoo/toxcore (crossplatform C)

Tuesday, 24 November 2015

Decrypting and encrypting messages with gpg in linux (ubuntu)

Encrypting and decrypting files with gpg tool is quite easy:
>gpg --recipient Ben --encrypt test.txt
>gpg --decrypt test.txt.gpg

But if you don't want to create a file and just need to encrypt or decrypt a message quickly?

This workflow will work

Encrypt with your gpg key for some known recipient:
>gpg --armor --encrypt --recipient bend
It might prompt you to type a password for your key at this stage.
Now type your message in and here goes the tick: press CTRL+D, which means the end of a input!
After that it will print your encrypted message into standard output.
Shortcut for the command above:
>gpg --aer bend

Encrypt symmetrically with some passphrase:
>gpg --armor --symmetric
It will prompt you to type a passphrase for symmetric encryption
Now type your message in and press CTRL+D
Shortcut:
>gpg -ac

Decrypt some pgp message:
>gpg --decrypt
Paste your pgp message, for example:
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1

jA0EAwMC1c4w0+3hgT9gySDDFx7lNx0Jwf3aGOwQ8yQc6KKWjnew6LkdtEg3mhOS
bQ==
=7kxT
-----END PGP MESSAGE-----
Type your passphrase (for example 123 for this symmetric message) or a password to your gpg key if it is encrypted for you as a recipient.
And again press CTRL+D to see decrypted message.

Monday, 19 October 2015

Practical generic types Contravariant and Covariant subtyping in Scala

I only found one good and simple explanation of generics Contravariance in Julien Richard-Foy’s blog:
http://julien.richard-foy.fr/blog/2013/02/21/be-friend-with-covariance-and-contravariance/

However it was not clear enough for me to memorize all these details, so I decided to develop the idea in a bit different key.

Let’s define some classification of animals:


Covariance
The easy example of covariance is a group of animals of the same kind (flock, heard, whatever...)
So the group of cows is also a group of ungulate, which is group of mammals, whch is a also group of animals:
Cow -> Ungulate -> Mammal -> Animal
Group[Cow] -> Group[Ungulate] -> Group[Mammals] -> Group[Animals]

This is covariance where Cow is a subclass of Animal, the Group[of Cow] is a (subtype of) Group[of Animal]

Contravariance
Imagine that there’s a law describing Veterinary licensing. The law defines the hierarchy of animal classes as above.
The imaginable law states that a Veterinarian with a license of some class is allowed to treat animals of subclasses of this class of animals, therefore:

LicensedVet[for Cows] can only treat Cows
LicensedVet[for Cattle] can only treat Sheep and Cows
LicensedVet[for Mammals] can only treat Dogs, Cats, Sheep and Cows
LicensedVet[for Animals] can treat anyone from this hierarchy

Cow -> Cattle -> Mammal -> Animal
LicensedVet[Cow] <- LicensedVet[Ungulate] <- LicensedVet[Mammal] <- LicensedVet[Animals]

This is contravariance here: Cow is a subclass of Animal, but LicensedVeterinarian[for cows] is not a (subtype of)  LicensedVeterinarian[for all Animals], however the LicensedVeterinarian[for Animals] is a (kind of subtype of) LicensedVeterinarian[for Cows].

This is a practical example of contravariance “from the real life” with kind of practical application.

Ok, let’s do some coding (in Scala):
class Animal(val name: String) {
  override def toString = this.getClass.getSimpleName+": "+name
}
class Mammal(name: String) extends Animal(name)
class Dog(name: String) extends Mammal(name)
class Cat(name: String) extends Mammal(name)

class Cattle(name: String) extends Mammal(name)
class Sheep(name: String) extends Cattle(name)
class Cow(name: String) extends Cattle(name)

class Bird(name: String) extends Animal(name)
class Goose(name: String) extends Bird(name)
class Chicken(name: String) extends Bird(name)

class GroupOfAnimals[A](val list: List[A]) {
  def getOne = list.head
  def getByName(name: String) = list.find({
      case p: Animal if p.name == name => true      case _ => false    }
  )
}

class LicensedVeterinarian[A] {
  def treat(a: A) = {
    print("Treat animal ")
    print(a)
  }
}

val dorothySheep = new Sheep("Dorothy")
val murkaCow = new Cow("Murka")
val gavCat = new Dog("Gav")
val unnamedHen = new Chicken("Hen")

val flockOfSheep = new GroupOfAnimals[Sheep](List(dorothySheep))
val someCattle = new GroupOfAnimals[Cattle](List(murkaCow, dorothySheep))

val jamesHerriot = new LicensedVeterinarian[Animal]
val bobbySmith =  new LicensedVeterinarian[Cattle]

flockOfSheep.getOne //Sheep: Dorothy
someCattle.getOne //Cow: Murka
someCattle.getByName("Murka") //Some(Cow: Murka)

//mr. Herriot can treat anyone
jamesHerriot.treat(dorothySheep)
jamesHerriot.treat(gavCat)
jamesHerriot.treat(unnamedHen)
//Bobby licensed only for Cattle
bobbySmith.treat(dorothySheep)
//bobbySmith.treat(gavCat) //type mismatch, expected: Cattle, actual: Cat
//bobbySmith.treat(unnamedHen) //expected: Cattle, actual: Chicken

Everything seems to work as expected, what for do we need all this covariance and contravariance things?

Imagine that vet can treat a group of animals:
class LicensedVeterinarian[A] {
  def treat(a: A) = {
    print("Treat animal ")
    print(a)
  }
  def treatGroupOfAnimals(g: GroupOfAnimals[A]) = {
    print("Treat animals ")
    print(g)
  }
}
jamesHerriot.treatGroupOfAnimals(someCattle)

If we try to compile the code with James Herriot doing treatGroupOfAnimals compiler will sipt something like:
type mismatch, expected: GroupOfAnimal[Animal], actual: GroupOfAnimal[Cattle]

What? A flock of cattle is not a group of animals? It happens because parametrized types are non-variant by default, so we must define whether it Covariant or Contravariant, otherwise it is considered to be non-variant.

Group of animals is covariant to animals, as mentioned above. So, if we redefine group of animals as follows, James Herriot will be able to treat a group of animals:
class GroupOfAnimals[+A](val list: List[A]) {
  def getOne = list.head
  def getByName(name: String) = list.find({
      case p: Animal if p.name == name => true      case _ => false    }
  )
}
jamesHerriot.treatGroupOfAnimals(someCattle) //now works as expected

Ok. What’s the use for contravariance? Let’s imagine that we have a farm:
object Farm {
  // This one will not work without covariance of GroupOfAnimals
  def areAnimalsOk(group: GroupOfAnimals[Mammal]): Boolean = {
    // Dunno am not a vet, they're always lookin fine
    true
  }
  def inviteVetForCattle(veterinarian: LicensedVeterinarian[Cattle]): Unit = {
    println("Inviting veterinarian for cattle")
  }
  def inviteVetForDog(veterinarian: LicensedVeterinarian[Dog]): Unit = {
    println("Inviting veterinarian for dog")
  }
  def inviteVetForBirds(veterinarian: LicensedVeterinarian[Bird]): Unit = {
    println("Inviting veterinarian for birds")
  }
}
Farm.areAnimalsOk(flockOfSheep) //True: They are always OK
Farm.inviteVetForCattle(bobbySmith)
// ^ This one is OK, Bobby is veterinarian for Cattle
Farm.inviteVetForCattle(jamesHerriot)
//expected:LicensedVeterinarian[Cattle],actual:LicensedVeterinarian[Animal]
Weird! Bobby can be invited to treat Cattle, but James Herriot cannot. As we said above, licensed veterinarians are contravariant to animals, so let’s try make them contravariant:
class LicensedVeterinarian[-A] {
  def treat(a: A) = {
    print("Treat animal ")
    print(a)
  }
  def treatGroupOfAnimals(g: GroupOfAnimals[A]) = {
    print("Treat animals ")
    print(g)
  }
}
Farm.inviteVetForCattle(jamesHerriot)

Phew… With contravariance option we can invite James Herriot. Our farm is safe now.

The final code:
class Animal(val name: String) {
  override def toString = this.getClass.getSimpleName+": "+name
}
class Mammal(name: String) extends Animal(name)
class Dog(name: String) extends Mammal(name)
class Cat(name: String) extends Mammal(name)

class Cattle(name: String) extends Mammal(name)
class Sheep(name: String) extends Cattle(name)
class Cow(name: String) extends Cattle(name)

class Bird(name: String) extends Animal(name)
class Goose(name: String) extends Bird(name)
class Chicken(name: String) extends Bird(name)

class GroupOfAnimals[+A](val list: List[A]) {
  def getOne = list.head
  def getByName(name: String) = list.find({
      case p: Animal if p.name == name => true      case _ => false    }
  )
}

class LicensedVeterinarian[-A] {
  def treat(a: A) = {
    print("Treat animal ")
    print(a)
  }
  def treatGroupOfAnimals(g: GroupOfAnimals[A]) = {
    print("Treat animals ")
    print(g)
  }
}

val dorothySheep = new Sheep("Dorothy")
val murkaCow = new Cow("Murka")
val gavCat = new Dog("Gav")
val unnamedHen = new Chicken("Hen")

val flockOfSheep = new GroupOfAnimals[Sheep](List(dorothySheep))
val someCattle = new GroupOfAnimals[Cattle](List(murkaCow, dorothySheep))

val jamesHerriot = new LicensedVeterinarian[Animal]
val bobbySmith =  new LicensedVeterinarian[Cattle]

flockOfSheep.getOne //Sheep: Dorothy
someCattle.getOne //Cow: Murka
someCattle.getByName("Murka") //Some(Cow: Murka)

//mr. Herriot can treat anyone
jamesHerriot.treat(dorothySheep)
jamesHerriot.treat(gavCat)
jamesHerriot.treat(unnamedHen)
//Bobby licensed only for Cattle
bobbySmith.treat(dorothySheep)
//bobbySmith.treat(gavCat) //type mismatch, expected: Cattle, actual: Cat
//bobbySmith.treat(unnamedHen) //expected: Cattle, actual: Chicken
jamesHerriot.treatGroupOfAnimals(someCattle)

object Farm {
  // This one will not work without covariance of GroupOfAnimals
  def areAnimalsOk(group: GroupOfAnimals[Mammal]): Boolean = {
    // Dunno am not a vet, they're always lookin fine
    true
  }
  def inviteVetForCattle(veterinarian: LicensedVeterinarian[Cattle]): Unit = {
    println("Inviting veterinarian for cattle")
  }
  def inviteVetForDog(veterinarian: LicensedVeterinarian[Dog]): Unit = {
    println("Inviting veterinarian for dog")
  }
  def inviteVetForBirds(veterinarian: LicensedVeterinarian[Bird]): Unit = {
    println("Inviting veterinarian for birds")
  }
}

Farm.areAnimalsOk(flockOfSheep)
Farm.inviteVetForCattle(bobbySmith)
Farm.inviteVetForCattle(jamesHerriot) 
Farm.inviteVetForDog(jamesHerriot)
Farm.inviteVetForBirds(jamesHerriot)
//Bobby is only licensed for cattle, not for birds or dogs:
//Farm.inviteVetForDog(bobbySmith) // Nope, type mismatch
//Farm.inviteVetForBirds(bobbySmith // Nope, type mismatch



Friday, 2 October 2015

Sequence of cases in scala

 There's not much said about sequences of cases (sequence of cases) in the "Programming in Scala: second edition". Googling returns a bit different stuff. Essentially they are just more concise way to define match cases and they not only work with Option, but with any other types as well. The code below can describe usage of sequences of cases:

var capitals = Map("France"->"Paris", "Japan"->"Tokyo", "Russia"->"Moscow")

/* sequence of cases */
val withDefaultSequenceOfCases: Option[String] => String = {
  case Some(x) => x // pattern match to extract string from Some
  case None => "?"
}// withDefaultSequenceOfCases: Option[Int] => Int = <function1>

/* match representation of sequence of cases */
def withDefaultMatch(s: Option[String]): String = s match {
  case Some(x) => x
  case None => "?"
}// withDefaultMatch: Option[String] => String = <function1>

capitals get "Russia" //res0: Option[String] = Some(Moscow)
capitals get "Sumatra" //Option[String] = None
capitals("Russia") //String = Moscow
withDefaultSequenceOfCases(Some("Test")) //String = Test
withDefaultSequenceOfCases(capitals get "Japan") //String = Tokyo
withDefaultMatch(capitals get "France") //String = Paris
withDefaultSequenceOfCases(capitals get "Somewhere") //String = ?
withDefaultMatch(capitals get "Pacific") //String = ?

/* sequence of cases is not necessarily Option */
abstract class Expr
case class Number(num: Double) extends Expr
case class UnOp(operator: String, arg: Expr) extends Expr

val renderUnary: Expr => String = {
  case UnOp(op, arg:Number) => op+""+arg.num
  case UnOp(op, arg) => op+""+arg
  case _ => "non unary operator"
}

renderUnary(UnOp("-",Number(1))) //String = -1.0
renderUnary(UnOp("+",Number(2))) //String = +2.0
renderUnary(Number(1)) //String = not unary operator