Thursday, February 19, 2015

Java Frontend with Giws


The Java Frontend has been updated to work with the Giws JNI wrapper generator, this lets you create Java objects and call their methods from C++, and also from Rusthon when using the C++ backend. Giws supports all of Java's primitive types like numbers, strings, and arrays; one problem is class constructors see this git hub issue.

The new syntax is documented in the wiki, here. Java source that you embed in the markdown is compiled with javac, xml source in the markdown that is marked with @giws will run giws and generate the c++ wrappers. In rusthon code using import jvm will link the final exe to libjvm.so and also create an instance of the JavaVM.

Jython Hello World

source code: giws_jython.md

See the source code in giws_jython.md to see the xml wrapper code the exposes Jython's PythonInterpreter, this simple example only wraps the exec method.

rusthon input

import jvm
jvm.load( 'jython.jar' )
jvm.namespace('org.python.util')

def main():
 interp = jvm( PythonInterpreter() )
 script = "print 'hello world'"
 interp.__exec__(cstr(script))

c++ output

using namespace org_python_util;
int main() {
 auto interp = std::make_shared(__javavm__);
 auto script = std::string("print 'hello world'");
 interp->exec(cstr(script));
 return 0;
}

Similar projects that allow Java to be used in CPython: Py4J, and Jpype.

Tuesday, February 17, 2015

C++11 Weak Pointers


C++11 introduces std::shared_ptr and std::weak_ptr to manage shared memory with reference counting and weak references. Weak references are used by children in a tree structure to reference their parent, and break the reference cycle. Methods of the child class need to take extra care with the parent pointer (the weak pointer), to promote it to a shared pointer, and only use it if the pointer is still alive.

Rusthon detects when you have a reference cycle between two classes and automatically uses weak references to break the cycle. The parent class must contain a list of child objects, then when the parent is set on the child it becomes a weak pointer. For more info, check out the wiki page.

rusthon input

The line below par = self.parent promotes the weak pointer to a reference counted shared pointer that could also be null if the parent has been deleted, so you need to check if it is None before it can be used. The last line c1.bar() will crash with a segmentation fault because it is used after the parent has been deleted, and the bar function is not checking if self.parent is not None.

class Parent:
 def __init__(self, children:[]Child ):
  self.children = children

class Child:
 def __init__(self, parent:Parent ):
  self.parent = parent

 def foo(self) ->int:
  par = self.parent
  if par is not None:
   return 1
  else:
   print('parent is gone..')

 def bar(self):
  print self.parent.children

def make_child(p:Parent) -> Child:
 c = Child(p)
 p.children.push_back(c)
 return c


def main():
 children = []Child()
 p = Parent( children )
 c1 = make_child(p)
 c2 = make_child(p)
 print c1.foo()
 c1.bar()
 del p
 print c1.foo()
 #uncomment to segfault##c1.bar()

c++11 output

class Parent {
  public:
 std::string __class__;
 std::shared_ptr<std::vector< std::shared_ptr<Child> >>  children;
 void __init__(std::shared_ptr<std::vector<std::shared_ptr<Child>>> children);
 Parent() {__class__ = std::string("Parent");}
 std::string getclassname() {return this->__class__;}
};
class Child {
  public:
 std::string __class__;
 std::weak_ptr<Parent>  parent;
 void __init__(std::shared_ptr<Parent> parent);
 int foo();
 void bar();
 Child() {__class__ = std::string("Child");}
 std::string getclassname() {return this->__class__;}
};

 void Parent::__init__(std::shared_ptr<std::vector<std::shared_ptr<Child>>> children) {
  this->children = children;
 }

 void Child::__init__(std::shared_ptr<Parent> parent) {
  this->parent = parent;
 }


 int Child::foo() {
  auto par = this->parent.lock();
  if (( par ) != nullptr) {
   return 1;
  } else {
   std::cout << std::string("parent is gone..") << std::endl;
  }
 }

 void Child::bar() {
  std::cout << this->parent.lock()->children << std::endl;
 }

std::shared_ptr<Child> make_child(std::shared_ptr<Parent> p) {
 Child  _ref_c = Child{};_ref_c.__init__(p);
 std::shared_ptr<Child> c = std::make_shared<Child>(_ref_c);
 p->children->push_back(c);
 return c;
}

int main() {

 std::vector<std::shared_ptr<Child>> _ref_children = {};
 std::shared_ptr<std::vector<std::shared_ptr<Child>>> children = std::make_shared<std::vector<std::shared_ptr<Child>>>(_ref_children);
 Parent  _ref_p = Parent{};_ref_p.__init__(children);
 std::shared_ptr<Parent> p = std::make_shared<Parent>(_ref_p);
 auto c1 = make_child(p);
 auto c2 = make_child(p);
 std::cout << c1->foo() << std::endl;
 c1->bar();
 p.reset();
 std::cout << c1->foo() << std::endl;
 return 0;
}

Thursday, February 12, 2015

Java Frontend


https://github.com/rusthon/java2python

Mixing languages, generated bindings, it makes development hard. Calling a Java function from C++ or Python through an FFI, converting types and objects, things quickly break apart. An alternative way to integrate with Java is with a frontend that converts it into another language, and completely bypass the JVM and Java compiler.

Java was supposed to run everywhere, but there is no official support for it on iOS, and you need to use a transpiler of some kind like Tom's j2objc to convert it to Objective-C. Rusthon's Java frontend can be used in a similar way, by converting Java into Rusthon syntax, and then translating that with the C++ backend, you have portable C++ that could be then compiled on iOS.

source code hello_java.md


Java Input

hand written java code example program with two class methods, foo takes a string.
public class HelloWorld {
    public static void test() {
        System.out.println("Hello, World test");
    }

    public static void foo(String msg) {
        System.out.println(msg);
    }

}

Rusthon Output

output from java2python in rusthon syntax.

class HelloWorld(object):
    @classmethod
    def test(cls:object):
        print("Hello, World test")

    @classmethod
    def foo(cls:object, msg:string):
        print(msg)

C++ Output

final translation to c++11
class HelloWorld {
  public:
 std::string __class__;
 static void test();
 static void foo(std::string msg);
 HelloWorld() {__class__ = std::string("HelloWorld");}
 virtual std::string getclassname() {return this->__class__;}
};
 void HelloWorld::test() {
  std::cout << std::string("Hello, World test") << std::endl;
 }

 void HelloWorld::foo(std::string msg) {
  std::cout << msg << std::endl;
 }