The Haxe Magic

You are viewing an old version of this entry, click here to see latest version.

This page is reserved for experienced users who want to know about Haxe underground Magic. Use these resources with care; they may change between versions.

Sometimes low-level libraries need to access platform-specific magic functions. You need to be inside an untyped block in order to use them. In general, you should only use these magic functions if you're writing a low-level library. Most of the time, you should be able to stick to the Haxe standard library.

Some of this information is also available in order to help you better understand how Haxe works on different platforms, for people interested in such funny things.

Initialization Magic

On all platforms, all types are first registered. Then the Boot.__init() method is called that triggers some platform-specific initialization code.

Then, all static function __init__ method body code is generated. This can contain some initialization code for specific classes when they are included in the project. Note that try/catch() exception blocks cannot be used inside __init__ methods and that static variables have not yet been initialized; these functions should only be used to perform very low level initializations.

After that, we can start initializing class static variables. In the end, the main method is called if specified on the commandline.

Boot Magic

The Boot class of each platform stores some platform-specific initialization code (method __init) and platform-specific subtyping checks (method __instanceof). This second method is used for try..catch blocks since we need to dynamically check the exception type when filtering it. The Std.is method is a crossplatform wrapper for this method.

Flash Magic

The following magic identifiers are available :

  • __new__(cl,p1,p2,p3...) , makes a new operation on the class with constructor parameters. It's useful since you can have any expression in place of cl.
  • __keys__(o) will build an Array containing all enumerable properties of the object o (using some kind of optimized ActionScript for...in)
  • __arguments__ is a special identifier to access the arguments special local variable of Flash.
  • __typeof__(o) is the same as ActionScript's typeof(o), and __instanceof__(o,cl) is the same as ActionScript's o instanceof cl. Both are used to implement Boot.__instanceof

For Flash Player running AVM2 code (the "ActionScript 3" target platform):

  • "__global__", gives access to the object that contains all the runtime classes and other properties defined by Flash Player, like the "trace" function and more. See the "Top Level" package in "ActionScript 3.0 Language and Components Reference" at Adobe LiveDocs, for more information.

Neko Magic

Neko has what are called builtins, which are documented here. You can access all Neko builtins by replacing the $ character by the __dollar__ prefix. It will be compiled as the corresponding call.

    var o : {} = untyped __dollar__new(null);

If you want to extend Haxe with C libraries, you can read the Neko C FFI Documentation and view the haxe/std/neko/Socket.hx source for an example of interfacing a Neko Library with Haxe.

In Neko, Arrays and Strings are not objects. This means that the neko basic array and the neko basic string are wrapped within object classes (sources are neko/NekoArray__.hx and neko/NekoString__.hx; these classes replace Array and String by copying them - see neko/Boot.hx).

The neko basic string is stored in the __s field of a String.
The neko basic array is stored in the __a field of an Array but can be bigger than the actual array. You can use the __neko() method to retrieve a copy of the neko array correctly resized.

So, this means that in the interface Haxe code, you want to do this:

static var _set_text = neko.Lib.load("systools","clipboard_set_text",1);
static public function setText( text : String ) : Void {
    // we access the neko-string directly
    _set_text(untyped text.__s);        
}

static var _get_text = neko.Lib.load("systools","clipboard_get_text",0);
static public function getText() : String {
    // we need to convert the neko-string to a Haxe string like this:
    return new String(_get_text());
}

For more information about this, you can also have a look at the implementations of
neko.Lib.nekoToHaxe and neko.Lib.haxeToNeko that do some conversions
between Haxe and Neko values.

Every class has two additional static fields, __construct__ and new. MyClass.new(p1,p2,p3) is the equivalent of Haxe new MyClass(p1,p2,p3). The __construct__ method stores the class constructor code which performs some initializations.

If a class has a method named __compare that takes a single argument and returns an Int, that function will be used by Reflect.compare when comparing two objects that are both of that type.

JavaScript Magic

The __js__ construct enables you to directly embed Javascript code into your Haxe code. Use with care !

var s = untyped __js__("Navigator.plugin[\"Shockwave Flash\"]");

Php Magic

There are three magic identifiers in php:

  • __php__ construct enables you to directly embed Php code into your Haxe code.
  • __call__("function", arg, arg, arg...) calls a php function with the desired number of arguments and returns whatever the php function returns.
  • "__var__(global, paramname)" has been introduced to easily get the values from global vars.
var value:String = "test";
untyped __php__("echo '<pre>'; print_r($value); echo '</pre>'; ");

// returns a NativeArray with values [1,2,3]
var value = untyped __call__("array", 1,2,3); 

// To get the value of $_SERVER['REQUEST_METHOD'] you can write the following
// (note that the dollar sign is omitted)
var value : String = untyped __var__('_SERVER', 'REQUEST_METHOD')  
version #6332, modified 2009-07-15 12:32:56 by amn