SpiderMonkey (MozillaのECMAScriptエンジン)の利用とDelphi

| コメント(0) | トラックバック(0)

昔のHDDからデータをあさっていたときに過去の遺物を見つけたので次に使うかもしれないときのためにメモ。 Delphiで書いたSpiderMonkeyのサンプルなんてほかに誰が必要としているんだか。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, jsapi;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;


var
  Form1: TForm1;

  global_class: JSClass = (
    name: 'global';
    flags: 0;
    addProperty: JS_PropertyStub;
    delProperty: JS_PropertyStub;
    getProperty: JS_PropertyStub;
    setProperty: JS_PropertyStub;
    enumerate: JS_EnumerateStub;
    resolve: JS_ResolveStub;
    convert: JS_ConvertStub;
    finalize: JS_FinalizeStub
  );
  rt: JSRuntime;
  cx: JSContext;
  global: JSObject;

implementation

{$R *.dfm}

function alertFunc(cx: JSContext; obj: JSObject; argc: JSUintn; argv: PJSValArray; out rval: jsval): JSBool; cdecl;
var
  str: JSString;
  msg: String;
  i: Integer;
  v: jsval;
begin
  for i:=0 to argc-1 do
  begin
    v := argv^[i];
    str := JS_ValueToString(cx, v);
    if i<>0 then
      msg := msg + ' ';
    msg := msg + JS_GetStringBytes(str);
  end;

  ShowMessage(msg);

  Result := True;
end;

var
  funcs: array[0..1] of JSFunctionSpec = (
  (
    name: 'alert';
    call: alertFunc;
  ),
  (
  )
  );

procedure TForm1.FormCreate(Sender: TObject);
begin
  rt := JS_NewRuntime($100000);
  cx := JS_NewContext(rt, $1000);
  global := JS_NewObject(cx, global_class, nil, nil);
  JS_InitStandardClasses(cx, global);
  JS_DefineFunctions(cx, global, PJSFunctionSpecArray(@funcs));
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  //
end;

procedure TForm1.FormShow(Sender: TObject);
var
  rval: jsval;
const
  //script = 'function fact(n){if(n<=1)return 1;else return fact(n-1)*n;} fact(5);';
  script = 'alert("hoge"); alert(1,2,3)';
begin
  JS_EvaluateScript(cx, global, script, length(script), 'filename', 1, rval);
end;

end.

jsapiユニットはjsapi.h等に書かれている関数プロトタイプと構造体の一部を記述したもの。 JS_NewRuntime関数でスクリプト実行環境の初期化をする。引数はメモリ使用量。 JS_NewContext関数はたぶんスレッドの初期化だと思う。 引数はJS_NewRuntimeで作った実行環境とスタックフレームのサイズ。 スタックフレームのサイズが小さいと深いネストでエラーになりやすい。ていうかなった。 JS_NewObjectでクラスの実体を作成し、JS_InitStandardClass関数でクラスとスレッドを関連付ける。 どうもSpiderMonkeyの実装ではグローバル関数やグローバル変数というものは存在せず、グローバルクラス内のメソッドやメンバ変数として扱われるようだ。 で、JS_DefineFunctionsでは実際にグローバルクラスにメソッドを追加している。 今回はalertという関数を追加した。 関数の内容と記述方法はソース見たほうが早いので説明は省略する。 コードの実行はJS_EvaluateScriptで行う。 関数宣言などコードの即時実行を伴わないものは、JS_CompileScriptが使えそうな気がする。

ちなみに終了処理はしていない。 横着な実装だ。

メモ終わり。

トラックバック(0)

トラックバックURL: http://nesitive.net/mt/tbping/168

コメントする

アーカイブ

ウェブページ

Powered by Movable Type 4.21-ja

このブログ記事について

このページは、が2008年6月15日 16:17に書いたブログ記事です。

ひとつ前のブログ記事は「Mozilla開発環境構築のメモ」です。

次のブログ記事は「iCalendar覚書 4章1節」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。