XREA.COM Logo XREA.COM Ad

管理人の雑記

1管理人 ★:06/04/30 20:55 ID:???
雑記サイト移転に伴い、AutoHotkey関係はこっちに書くことに。
124管理人 ★:2009/03/31(火) 08:44:17
「AutoHotkeyを廃れさせるページだったところ」にて、メモリの直接操作とネイティブコードの呼び出し機能に特化したJavaScript 1.8処理系を公開。
http://lukewarm.me.land.to/

WSHとAutoHotkeyを気分によって使い分けるのに嫌気がさしたので作ることに。

Firefoxで使われているJSAPIなる物を使う。
JSAPIだけをビルドする方法が分からず、何故かFirefox全体をビルドする羽目に。
しかも、出来上がったDLLがMSVCR90.DLLに依存していて、テスト用の環境で動作しない。
Firefox3.1betaに同梱されていたDLLに差し替えたら起動出来た。

とりあえず、DLL関数の呼び出しとコールバック関数の生成、メモリの確保・読み書き用の関数を作成。
一部AutoHotkeyのソースを参考にした。
とりあえず、EnumWindows関数を呼び出してコールバックを受け付け、可視ウィンドウのタイトルを出力するという処理が動作するようになった。
JavaScriptは動的に関数を生成出来るので、いちいちラッパー関数を定義したりしなくても、普通の関数と同じ感覚で呼び出せるのが便利だ。

しかし、Unicode対応でないAPIで日本語を扱うと文字化けする。
どうやら、JSAPIの内部文字コード(UTF-16)からANSI文字列への変換時に、Shift_JISではなくlatin-1として変換されている模様。
修正箇所が多くて面倒くさいが、WideCharToMultiByteで変換するようにすれば解決するだろうか。
125管理人 ★:2009/04/01(水) 00:30:56
間違えて一日早く公開してしまったが、上記はエイプリルフールのネタなので本気にしないように。
126管理人 ★:2009/04/05(日) 21:11:42
とりあえずいくつかのバグ修正と文字列変換のマルチバイト対応化、JSAPIの構造体ポインタを取得する機能の追加、非コンソール版の作成を行っておいた。
コマンドライン引数の取得やテキストの出力など、何から何まで自分で定義しなくてはならないが、使おうと思えば使えるはずである。
127管理人 ★:2009/04/12(日) 17:56:35
実行速度の比較。

AutoHotkeyが1.0.48で大幅に高速化されたというので、SpiderMonkeyと比べてみた。

1から60万までを文字列として連結するという処理の所要時間を計測したところ、
AutoHotkey1.0.47は5秒台、
AutoHotkey1.0.48は2秒台、
無調整のSpiderMonkeyは6秒台、
JITコンパイルを有効にしてGC自動実行を抑止したSpiderMonkeyが4秒台だった。
1.0.48は確かにかなり高速化されている。

しかし、A_Indexを使わずに別のカウンタ変数を使うなどの変更を行うと、すぐに4秒以上かかるようになってしまった。
また、SpiderMonkeyでは、文字列として連結せずに配列にpush()するようにすると0.4秒程度になるなど、方法によっては桁違いに高速になる。
128管理人 ★:2009/05/04(月) 04:59:34
>>124をマルチスレッドに対応させるなどした。

SpiderMonkeyをマルチスレッド対応させる上で主に注意すべきなのが、GCのタイミングであるらしい。
あるスレッドが何かに使うためにオブジェクトを生成して、他から参照されている状態にする前に、他のスレッドでGCが実行されてしまうと、使うはずだったオブジェクトが解放されてしまう恐れがある。
そこで、リクエストという仕組みで、スレッドがJSAPIの処理中であることを通知して、GCが発生しないようにしておく必要があるらしい。
GCが必要になると、他の全てのスレッドのリクエストが完了/中断されてGC可能状態になるまで待ち合わせてから、GCが実行されるらしい。
オブジェクトなどへのアクセスは、排他制御が行われるので、複数スレッド間で共有しても問題無いらしいが、共有オブジェクトへのアクセスが多発すると、待ち合わせが多発して効率は落ちるようだ。

大体の仕組みが分かったので、まず既存のコードにJS_[Begin/End]Request()などの処理を追加した。

次に、マルチスレッドでスクリプトを実行できるようにする。
とりあえず、別途作成したJSAPIコンテキストを使い、新規スレッドで指定のスクリプトを実行するという関数を用意してみた。
また、関数をネイティブコード側から呼べるようエクスポートする関数に、不特定多数のスレッドから呼ばれても大丈夫なようにする機能を追加。新規コンテキストを生成するコストが大きいため、従来方式と選択可能にした。
前者はグローバルオブジェクトも新規作成するが、後者は元のコンテキストのグローバルオブジェクトをそのまま利用する。

とりあえず、以前の1から60万までを文字列として連結する処理を2つのスレッドで実行させてみたところ、異様に遅くなった。
両方のバージョンとも速度は大差ないので、問題なのはGCの待ち合わせのようだ。
文字列やオブジェクトをあまり生成しないであろう素数探索処理を並列実行させたところ、シングルスレッドの時とほとんど同じ速度で実行された。(マルチコア環境なので)

コンテキスト作成版と関数エクスポート版での速度差はあまり見られない。
グローバルオブジェクトを共有すると、文字列やオブジェクトの操作時にも共有部分へのアクセスが発生して遅くなるかと思ったが、それほど問題にはならないようだ。
関数エクスポート版では、グローバル変数や関数が生成されたスコープでの変数にも普通にアクセスできるので、利便性が高い。

実際にマルチスレッド処理が必要になるのは、処理時間のかかるAPIの実行中に他の処理を行わせたい場合等だろうから、GCによる効率の低下はそれほど気にする必要はないだろう。
どうしてもそのような処理を並列実行させたい場合は、プロセス自体を並列化させればいい。
129unnamed.ahk:2009/05/11(月) 12:56:46
.NETFrameworkで作成されたアプリケーションのコンボボックスの選択値を取得する方法を知っている方がみえましたら教えてください。
ControlGet関数でChoiceを使用しても値を取得できません。
よろしくお願いします。
130管理人 ★:2009/05/11(月) 14:32:11
スレ違い
131管理人 ★:2009/12/12(土) 02:39:52
「File.exists」か「File.exist」か
迷って、検索して以下のページを見つけた
tp://piro.sakura.ne.jp/latest/blosxom/topics/2008-10-08_naming.htm

が、結局文字数の少なさを優先して、「has」「is」以外は原型にすることにした。
132管理人 ★:2009/12/23(水) 08:27:08
>>124を久しぶりに更新。
ネイティブコード関数を呼び出したときに、GetLastError()の値を取得して例外を投げる機能を追加した。
どうやら、ラッパ関数の中で使われているJSAPI呼び出しでエラーコードがリセットされてしまうらしく、
GetLastError()をラップしても役に立たないため。

それと、>>131は、exist以外の例が思い浮かばないので、sをケチるのはやめてexistsにした。
133管理人 ★:2009/12/27(日) 12:07:20
>>124を更に更新。
指定アドレスの64ビット整数を読み書きする機能を追加した。
符号無しであれば既存の機能だけでも無理矢理何とかなりそうだが、
符号付きの64ビット整数の負の値を読み書きするのが面倒くさそうだったので。
134管理人 ★:2010/01/01(金) 08:22:57
去年、延々と人知れず作っていたスクリプトを公開してみる。
>>124をまともに使えるようにするためのライブラリである。
ng.exeのディレクトリにlibディレクトリを置いて、ng.jsに
__NG__EvalFile(__NG__HostPath().replace(/([^\\]+)$/,"\\lib\\Base.ng"));
と書き、その下にプログラムを記述すれば試せる。
コマンドラインで与えられたスクリプトを読み込んで実行する部分とかは、そのうち実装する。

prototype.jsのように、独自のクラス機構を中核としたライブラリになっている。
インスタンスメソッドの他にクラスメソッドを登録でき、ミックスイン的なものによる多重継承のような感じの機能も搭載するなど、色々とややこしくなってしまった。

ドキュメント的な物はまだ無いが、スクリプトの後ろの方を見れば、前の方で定義された機能がどんな感じのものかくらいはわかるかも知れない。


投稿ファイル名: lib.zip
http://lukewarm.s101.xrea.com/bbs/file/1146398137_134.zip
サイズ: 18348 bytes
135管理人 ★:2010/01/30(土) 06:19:45
>>134にスクリプトファイルへの関連付け機能や、それなりのドキュメントなどを追加して、そこそこ実用的な感じにした。
以降は下記のスレで。
http://lukewarm.s151.xrea.com/test/read.cgi/b/1264431038/
136管理人 ★:2010/02/05(金) 00:02:10
http://lukewarm.me.land.to/を更新。
スクリプトが最後に評価した値をプロセスの終了コードにするように。
関数のインポート・エクスポートで、文字列系の型を廃止。
GetLastError()の値を例外として投げる場合、関数の返値をプロパティとして得られるようにした。
101KB
名前: E-mail:
ファイル:
0ch BBS 2005-10-08