Kite Programming Language

Interesting LLVM "bug" found

Written by Mooneer Salem on Monday 16th of January, 2012 in General

Today I added parser and codegen support for the return keyword. As in other languages, its designed for the developer to exit a method early. Unfortunately, it didnt work right away:

$ ./kite
method x()
    return 1;

System.exceptions.NotImplemented: Could not find method print that takes 0 argument(s).
    in (main program) + 0x79

Investigating further, I noticed that it was generating the following LLVM intermediate code:

; ModuleID = '__root_module'

@0 = internal constant [5 x i8] c"x__o\00"
@1 = internal constant [6 x i8] c"print\00"

define i32* @__static_init____o(i32* %this) {
  %0 = alloca i32*
  store i32* %this, i32** %0
  %1 = call i32* @kite_method_alloc(i32* bitcast (i32* (i32*)* @x__o to i32*), i32 1)
  %2 = load i32** %0
  %3 = call i32** @kite_dynamic_object_get_property(i32* %2, i8* getelementptr inbounds ([5 x i8]* @0, i32 0, i32 0), i1 true)
  store i32* %1, i32** %3
  %4 = load i32** %0
  %5 = call i32* @x__o(i32* %4)
  %6 = call i32* @kite_find_funccall(i32* %5, i8* getelementptr inbounds ([6 x i8]* @1, i32 0, i32 0), i32 1)
  %7 = bitcast i32* %6 to i32* (i32*)*
  %8 = call i32* %7(i32* %5)
  ret i32* %8

define i32* @x__o(i32* %this) {
  %0 = alloca i32*
  store i32* %this, i32** %0
  %1 = call i32* @System__integer__obj__i(i32 1)
  ret i32* %1
  ret i32* %1

declare i32* @System__integer__obj__i(i32)

declare i32* @kite_method_alloc(i32*, i32)

declare i32** @kite_dynamic_object_get_property(i32*, i8*, i1)

declare i32* @kite_find_funccall(i32*, i8*, i32)

Note the part in bold. Two ret statements are being outputthe one from return, and the normal one thats generated at the end of every method. Normally LLVM would eventually generate machine code that simply skips over the second ret statement. Or so youd think.

What I noticed is that System__integer__obj__i() would do the correct thing and return a valid System::object pointer, while kite_find_funccall() would get a totally different pointer. Even though according to the above, the return value from obj__i() gets fed directly into kite_find_funccall(). I confirmed this time and time again in gdb.

The fix? Using the same code suppression logic that I implemented for break/continue to suppress the last ret. Now it works as intended:

$ ./kite
method x()
    return 1;


EDIT: this was on LLVM 2.9. I have yet to try 3.0 to see if this issues fixed there. If not, a bug report might be pending in the future.

EDIT 2: Link to LLVM bug report. Was able to duplicate the problem in 3.0 as well.

On a tangent

Written by Mooneer Salem on Thursday 29th of December, 2011 in Usage

harry:kite-llvm mooneer$ ./kite
class X [
    method z() [
    method y() [
        (make System.exceptions.NotImplemented())|throw;

v = make X();
System.exceptions.NotImplemented: Exception thrown
    in method X|y + 0xcc
    in (main program) + 0xfd

harry:kite-llvm mooneer$

Notice anything different? Hint: the exception trace looks a lot nicer. :)

Long overdue update!

Written by Mooneer Salem on Saturday 11th of June, 2011 in General

Hi everyone! I know I havent updated in a while, but Ive had life go on since my last update. I was able to get back to working on the LLVM port of Kite, though, so I implemented a few things:

  1. I moved kitellvm development to a Git repository. This is mostly an experiment to see how it goes. I like it so far, though.
  2. Implemented basic exceptions in kitellvm (no stack trace yet):
    harry:kite-llvm mooneer$ ./kite
        (make this.System.exceptions.exception())|throw; 
    Exception thrown
    harry:kite-llvm mooneer$ 
  3. Implemented an ikt port:
    harry:kite-llvm mooneer$ ./ikt
    Interactive Kite console
    ikt> "hello world"|print;
    hello world
    ---> hello world
    ikt> ^D
    harry:kite-llvm mooneer$  
  4. Class definition and instantiation support:
    harry:kite-llvm mooneer$ ./kite
    class X
        method __init__() [ this.elite = 1337; ];
    (make X()).elite|print;
    harry:kite-llvm mooneer$  

Anyway, more updates soon :)

Boost Spirit experimentation

Written by Mooneer Salem on Saturday 25th of December, 2010 in General with 3 comments

Ive been playing with Boost Spirit as an alternative to Bison/Flex lately for Kite. So far, its actually pretty nice in terms of syntax; you only need to use C++ to describe your language. Ive already found a few disadvantages, as shown below:

harry:kite-llvm mooneer$ time sh 
Compiling src/apps/kite.cpp...
Compiling src/codegen/llvm_compile_state.cpp...
Compiling src/codegen/llvm_node_codegen.cpp...
Compiling src/codegen/syntax_tree_node_printer.cpp...
Compiling src/codegen/syntax_tree_printer.cpp...
Compiling src/parser/parser.cpp...

real    0m34.831s
user    0m32.598s
sys 0m2.048s
harry:kite-llvm mooneer$ ls -lh
total 12240
-rwxr-xr-x@ 1 mooneer  staff   238B Dec 25 00:42
-rwxr-xr-x  1 mooneer  staff   4.0M Dec 25 15:02 kite
-rw-r--r--  1 mooneer  staff   9.2K Dec 25 15:01 kite.o
-rw-r--r--  1 mooneer  staff    10K Dec 25 15:01 llvm_compile_state.o
-rw-r--r--  1 mooneer  staff    72K Dec 25 15:01 llvm_node_codegen.o
-rw-r--r--  1 mooneer  staff   1.8M Dec 25 15:02 parser.o
drwxr-xr-x  6 mooneer  staff   204B Dec 23 21:34 src
-rw-r--r--  1 mooneer  staff   5.7K Dec 25 15:01 syntax_tree_node_printer.o
-rw-r--r--  1 mooneer  staff   9.6K Dec 25 15:01 syntax_tree_printer.o
harry:kite-llvm mooneer$

(tl;dr: very large binaries, even with g++ Os, and very long compile times.) Ive only implemented the math operations so far for the above test.

Anyway, Ill put up the code when I have a bit more to show. :)

1.0.4 released

Written by Mooneer Salem on Tuesday 23rd of November, 2010 in Releases with 2 comments

Kite 1.0.4 has been released.

New in this release:

  • Internal data structures modified for performance and memory efficiency.
  • Added preliminary multiple inheritance support.


Issue tracker URL (for bug reports):
Getting help: