4

MacOSXユニバーサルバイナリアプリでLua5.0を数年間使用しています。Luaスクリプトはluacを使用してコンパイルされ、コンパイルされたスクリプトはアプリにバンドルされています。それらはTigerとLeopard、IntelまたはPPCで適切に機能しました。

当時のライブラリの問題を回避するために、XcodeプロジェクトにLua srcツリーを追加し、問題なくそのままコンパイルしました。

Luaのより新しいバージョンに更新する時が来たので、ソースツリーを5.1.4のものに置き換えました。make macosxを使用してluacを再構築しました(マシンはIntelでLeopardを実行しています)。

コンパイルされていないスクリプトは、いつものようにTigerとLeopard、IntelとPPCで正しく機能します。

ただし、コンパイルされたスクリプトはPPCマシンにロードできなくなりました。

そこで、「ansi」フラグを使用してluacを再構築し、スクリプトを再コンパイルしました。同じエラー。同様に、「generic」のビルドフラグは喜びを生み出しませんでした。

誰かが私が次に何ができるかについてアドバイスできますか?

4

6 に答える 6

13

Luaのコンパイル済みスクリプトは、短いヘッダーの後にダンプされた生のバイトコードとほぼ同じです。ヘッダーには、バイトコードのコンパイルに使用されるプラットフォームのプロパティの一部が記載されていますが、ローダーは、現在のプラットフォームが同じプロパティを持っていることを確認するだけです。

残念ながら、これは、まったく同じバージョンのLuaでコンパイルされた場合でも、別のプラットフォームでコンパイルされたバイトコードをロードするときに問題を引き起こします。もちろん、異なるバージョンのLuaでコンパイルされたスクリプトが機能することは期待できません。また、Luaのバージョン番号がバイトコードヘッダーに含まれているため、それらをロードする試みはコアによってキャッチされます。

簡単な答えは、スクリプトをコンパイルしないことです。Luaがスクリプト自体をコンパイルする場合、アプリケーションのさまざまなビルドでLuaコア間で発生する可能性のあるバージョンの不一致についてのみ心配する必要があり、それを処理するのは難しくありません。

コンパイルされたバイトコードの完全な相互互換性を実際にサポートすることは簡単ではありません。その電子メールで、MikePallは次の問題を特定しました。

  1. エンディアン:必要に応じて出力を交換します。

  2. sizeof(size_t)、巨大な文字列定数に影響します:ダウングレード時にオーバーフローをチェックします。

  3. sizeof(int)、影響MAXARG_BxおよびMAXARG_sBx:ダウングレード時にオーバーフローをチェックします。

  4. typeof(lua_Number):Cでは簡単ですが、ホストとターゲットが同じFP標準に従っている場合に限ります。アップグレード時の精度の低下(まれなケース)。にダウングレードするときに、整数以外の数値について警告し int32ます。

メーリングリストでこの問題について私が見たすべての議論から、コンパイルされていないLuaスクリプトを出荷することだけを検討したくないと仮定すると、2つの実行可能なアプローチがわかります。

1つ目は、コンパイルされたスクリプトがロードされるときにバイト順序を修正することです。これは、コア自体を再コンパイルせずにスクリプトファイルを読み取る低レベルの関数を置き換えることで実行できるため、予想よりも簡単であることがわかります。実際、 lua_load()に独自のチャンクリーダー関数を提供することで、純粋なLuaで実行することもできます。プラットフォームでの互換性の問題がバイトオーダーのみである限り、これは機能するはずです。

2つ目は、コア自体にパッチを適用して、すべてのプラットフォームでコンパイルされたスクリプトに共通の表現を使用することです。これは、ルイス・エンリケ・デ・フィゲイレドによって可能な限り説明されています。

....バイトオーダーまたはクロスコンパイルへの最適なルートは、サードパーティのダンプ/アンダンプのペアであると確信しています。ファイルldump.cとlundump.cは完全に置き換え可能です。それらは、明確に定義された単一のエントリポイントをエクスポートします。プリコンパイルされたチャンクの形式はまったく神聖ではありません。ldump.cとlundump.cが同意する限り、任意の形式を使用できます。(たとえば、Rici Lakeは、プリコンパイルされたチャンクのテキスト形式を作成することを検討しています。)...。

個人的には、スクリプトを事前にコンパイルしないことを真剣に検討し、プラットフォームの移植性の問題を完全に回避することをお勧めします。

編集: lhfのコメントのおかげで、バイトコードヘッダーの説明を更新しました。私はまだLuaソースのこの部分を読んでいなかったので、ヘッダーにどのような情報が存在するか、または存在しないかについて非常に断定する前に、おそらくそれをチェックする必要がありました。

lundump.cこれは、ロードされているバイトコードと比較するために、実行中のプラットフォームに一致するヘッダーのコピーを形成するフラグメントです。これは、ファイルのヘッダーと完全に一致するかどうかと単純に比較されるmemcmp()ため、不一致があると、ストックローダー(luaU_undump())がファイルを拒否します。

/*
* make header
*/
void luaU_header (char* h)
{
 int x=1;
 memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
 h+=sizeof(LUA_SIGNATURE)-1;
 *h++=(char)LUAC_VERSION;
 *h++=(char)LUAC_FORMAT;
 *h++=(char)*(char*)&x;                         /* endianness */
 *h++=(char)sizeof(int);
 *h++=(char)sizeof(size_t);
 *h++=(char)sizeof(Instruction);
 *h++=(char)sizeof(lua_Number);
 *h++=(char)(((lua_Number)0.5)==0);             /* is lua_Number integral? */
}

ご覧のとおり、ヘッダーの長さは12バイトで、署名(4バイト、 " <esc>Lua")、バージョンコードとフォーマットコード、エンディアンのフラグバイト、タイプのサイズ、、、、、、およびintであるかどうかを示すフラグが含まれています。一体型。size_tInstructionlua_Numberlua_Number

これにより、ほとんどのプラットフォームの区別を把握できますが、プラットフォームが異なる可能性のあるすべての方法を把握しようとはしません。

私はまだ上記の推奨事項を支持しています。まず、コンパイル可能なソースを出荷します。または、次に、カスタマイズldump.clundump.cて共通フォーマットを保存およびロードします。さらに、カスタムフォーマットは、ストックバイトコードフォーマットと混同しないように、ヘッダーのLUAC_FORMATバイトを再定義する必要があることに注意してください。

于 2009-06-26T08:24:12.597 に答える
3

RBerteigの投稿にコメントしたかったのですが、まだ十分な評判がないようです。LuaRPCをLua5.1.xで高速化し、埋め込みターゲットで機能させるために、ldump.cソースとlundump.cソースを変更して、両方をもう少し柔軟にしました。埋め込まれたLuaプロジェクト(eLua)には、Luaリストにあるパッチのいくつかがすでに含まれていますが、lundumpをさまざまなアーキテクチャでコンパイルされたスクリプトに少し使いやすくするために、もう少し追加しました。ホストシステムとは異なるターゲット用にビルドできるように、クロスコンパイルサポートも提供されています(以下のリンクと同じディレクトリにあるluac.cを参照してください)。

変更をチェックすることに興味がある場合は、eLuaソースリポジトリで見つけることができます: http ://svn.berlios.de/wsvn/elua/trunk/src/lua/lundump.c http://svn。 berlios.de/wsvn/elua/trunk/src/lua/lundump.h http://svn.berlios.de/wsvn/elua/trunk/src/lua/ldump.c

標準の免責事項:私は、変更が完璧である、またはあらゆる状況で機能することを主張しません。使って壊れたものを見つけたら、修理できるように聞いていただければ幸いです。

于 2009-06-27T00:23:40.840 に答える
3

異なるエンディアンをサポートするパッチを適用したバイトコードローダーを使用することをお勧めします。これを参照してください。

于 2009-06-26T13:25:08.823 に答える
0

Intelボックスでスクリプトをコンパイルしたと思います。

コンパイルされたスクリプトは非常に移植性がありません。本当にスクリプトをプリコンパイルしたい場合は、コンパイルされた各スクリプトの 2 つのバージョンを含める必要があります。1 つは Intel 用で、もう 1 つは PPC 用です。アプリは、実行中のプログラムを調べて、コンパイルされた正しいスクリプトを使用する必要があります。

于 2009-06-26T23:54:59.757 に答える