スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Emscripten: LLVMのbitcodeをJavaScriptにコンパイル

Emscriptenという、興味深いプロジェクトを見つけた。C/C++のコードをコンパルしてできたLLVMのbitcodeをJavaScriptに変換するらしい。 実際に、Cで書かれたLuaのインタプリタをコンパイルしたがある。

C/C++のコードをウェブで使うのには、GoogleのNative ClientやAdobeのAlchemyがあるけど、どっちもブラウザのプラグインだ。EmscriptenはコードをJavaScriptに変換してしまうので、プラグインを入れなくても動作する。ただしスピードの問題はあるだろうが。

類似のプロジェクトにはllvm-js-backendというのがあるそうだ。Emscriptenとは実装の方針が違うために直接のコード共有はできないけど、テストとかでお互い協力するらしい。

スポンサーサイト

テーマ : プログラミング | ジャンル : コンピュータ

JavaScriptで、Hoge instanceof Hoge が成り立つオブジェクトを作る

MozillaのJavaScriptエンジンはStopIterationというオブジェクトを持っている。

try {
  throw StopIteration;
} catch (e if e instanceof StopIteration) {
}

興味深いのは、このStopIterationというオブジェクトについて、StopIteration instanceof StopIteration === trueが成り立つことだ。このような性質を持つオブジェクトを自分で作り出すことはできるのだろうか?

できる。__proto__があれば。

// Firefox、Safari、Chrome、Operaで動作を確認
var f = function(){};
f.__proto__ = f.prototype;
f instanceof f; // ⇒ true

ただし、このfとStopIterationとでは、typeofした時の値(typeof StopIterationはobject)と、呼べるかどうかが異なる。

テーマ : プログラミング | ジャンル : コンピュータ

ブラウザ間のDOM CSSの差異を吸収する

最近、CSS3の2D Transformsを使ってみた。当初はWebKit専用(-webkit-付き)で書いてたんだが、JavaScriptから制御しようと思うとWebKitCSSMatrixがWebKitにしかないので、Firefoxなどの他のブラウザではJavaScriptが動かなくなる。CSS宣言なら単純に無視されるだけなので、これは好ましくない。調べてみると、Mozillaも2D Transformsを実装してるらしい。ならそれを使えばいいじゃん、となるのだが、コードで分岐するのは面倒だ。そこで、こんな感じのコードを書いた。

if (navigator.userAgent.indexOf("Gecko") != -1) {
  CSSStyleDeclaration.prototype.__defineGetter__("transform",function() {
    return this.MozTransform;
  });
  CSSStyleDeclaration.prototype.__defineSetter__("transform",function(x) {
    this.MozTransform = x.toString();
  });
  CSSMatrix = function() {
    /*略*/
  };
  CSSMatrix.prototype = {
    /*略*/
  };
}
if (navigator.userAgent.indexOf("WebKit") != -1) {
  CSSStyleDeclaration.prototype.__defineGetter__("transform",function() {
    return this.webkitTransform;
  });
  CSSStyleDeclaration.prototype.__defineSetter__("transform",function(x) {
    this.webkitTransform = x;
  });
  CSSMatrix = WebKitCSSMatrix;
}

このコードを読み込んでおけば、JavaScriptからの操作は、2D Transformsのドラフトにあるような方法でできる。 ただ、CSSに書くプロパティ名はどうしようもない。

一応完全なコードも以下に載せておく。

続きを読む

テーマ : プログラミング | ジャンル : コンピュータ

JavaScriptで配列を走査するためのオススメの方法: Array.prototype.forEach

今さらだが、Array.prototype.forEachが便利だ。いいところ:

  • タイプ量
    for (var i = 0; i < arr.length; ++i) {
      // 好きな処理
    }
    arr.forEach(function(value,i) {
      // 好きな処理
    });
    比べてみると、Array.prototype.forEachを使うほうが短い。
  • 変数が使い回されない(重要)
    for (var i = 0; i < arr.length; ++i) {
      arr[i].addEventListener("click",function(){
        alert(i);
      },false);
    }
    とか
    for (var i = 0; i < arr.length; ++i) {
      for (var i = 0; i < arr2.length; ++i) {
        // 処理
      }
    }
    が意図通り動かなくて悩んだ人も(俺だけかもしれないけど)多いはず。Array.prototype.forEachを使えばその問題がない。

もちろんfor文を使ったほうが速いんだけど、速度が第一でない限りこっちを使うべきだと思う。

テーマ : プログラミング | ジャンル : コンピュータ

拡張された JavaScript を通常の JavaScript に変換する

今やっているのは、先週書いたJavaScript の(主にMozillaによる)独自拡張のまとめにあるような構文を、通常の構文に書き直す、トランスレータの製作。そのため、今年の初め(もう2ヶ月たったのか!)に書いたように、JavaScriptのパーサを作ってる。

作ってると書いたけど、実はパーサはほぼ完成した。ASTをJavaScriptのコードとして書き出す部分も書いたので、あとはASTを調理する部分を書けばいい。パース→ASTを変換→書き出し、という流れになる。

じゃあ先週書いた構文は具体的にどう変換すればいいのか?

定数

Safari、Chrome、Operaなどでも使えるので変換の必要なし。

条件付きcatch節

一度全てキャッチしてから分岐すればいい。

try {
  throw 123;
} catch (ex if ex == 123) {
  alert(ex); // 123
}
try {
  throw 123;
} catch (ex) {
  if (ex == 123) {
    alert(ex); // 123
  } else {
    throw ex;
  }
}

続きを読む

テーマ : プログラミング | ジャンル : コンピュータ

プロフィール

minoki

Author:minoki
好きなプログラミング言語:
Haskell,Lua
GitHubアカウント
Twitter

最新記事
月別アーカイブ
カテゴリ
検索フォーム
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。