emcc-jsx の proof-of-concept #upcamp

emscriptenでJSにコンパイルできるものの、JSからのインターフェイスは使いやすいとは言いがたいし、ましてやJSXから呼び出すとなると本来型のあるCの関数を呼び出すのにccall()経由では静的型チェックの恩恵をうけられない。そこでJSXのラッパを自動生成することで、emccでコンパイルするだけでJSXのモジュールとして使えるようにできないだろうかと考えた。

簡単な emcc-jsx を書いてみたところ、以下のCコードからJSXのラッパを生成することができた。これならJSXからCコードを利用することも比較的簡単にできる*1

#include <stdio.h>

double add(double a, double b) {
    return a + b;
}

int addInt(int a, int b) {
    return a + b;
}

void myPuts(const char* s) {
    puts(s);
}

JSX:

// emscripten JS API
native class _C {
  static function ccall(name : string, returnType : string, argsType : string[], args : variant) : variant;
} = "require('./add.js')";

// from C file
class EMS {
  static function add (a : number, b : number) : number {
    return _C.ccall("add", "number", ["number","number"], [a,b]) as number;
  }
  static function addInt (a : number, b : number) : number {
    return _C.ccall("addInt", "number", ["number","number"], [a,b]) as number;
  }
  static function myPuts (s : string) : void {
    _C.ccall("myPuts", "void", ["string"], [s]);
  }
}

ただ、いまのところemscriptenのコード生成器はプラガブルではないので、emscripten/src/jsifier.js に直接JSXコード生成器を埋め込むことになり、利用しやすいとは言いがたい。emscriptenのコードジェネレータをプラガブルにすれば、emcc-jsxも現実的になるかもしれない。

*1:ただし構造体を利用するのは難しい