Skip to content
Silica edited this page Sep 11, 2014 · 2 revisions

バイトコード

VMが実行するコードのこともバイトコードと呼ぶが
ここでは外部ファイル等に保存する為にシリアライズされたものを指す

利用する為の関数

PSLVMのメンバ関数である
バイトコードの書き込み、読み込みを行う

error writeCompiledCode(const string &filename)
error writeCompiledCode(std::FILE *fp)
error writeCompiledCode(variable::buffer &buf)
error loadCompiledCode(const string &filename)
error loadCompiledCode(std::FILE *fp, unsigned long size)
error loadCompiledCode(variable::buffer &buf)
error loadCompiledCode(void *buf, unsigned long size)

###PSL::string

error writeCompiledCode(const string &filename)
error loadCompiledCode(const string &filename)

ファイル名を渡すだけで使用出来る

内部的には渡されたファイル名をfopenし、次のstd::FILE*版を呼び出す

std::FILE*

error writeCompiledCode(std::FILE *fp)
error loadCompiledCode(std::FILE *fp, unsigned long size)

ファイルポインタを渡して使用する
seekすることなく、現在の位置から読み込み/書き込みを行う
事前に自分でファイルをオープンし、必要に応じてseekしてから呼び出すことになるだろう

ファイルを判別する為のマジックナンバーの書き込み/チェックを行う
内部的にはその後buffer版を呼び出す

variable::buffer

error writeCompiledCode(variable::buffer &buf)
//error loadCompiledCode(variable::buffer &buf) // 使用するべきではない

variable::bufferはシリアライズされたコードを格納する為の内部クラスである
コンストラクタは引数なし
unsigned char *get()で先頭のポインタを取り出す
size_t size()でサイズを取得する
手動での読み込み時にこれを利用するべきではない

void*

error loadCompiledCode(void *buf, unsigned long size)

バッファからの読み込みはこちらを使う

ファイル判別の為のマジックナンバーの処理はFILE*版が行う為
その内部で呼び出されるbuffer版は何も行わない
渡すポインタの内容がシリアライズされたPSLのバイトコードであることは使用者が保証しなければならない

説明を分かり易くする為にmallocを使用しているが
そこは各自どうするか考えて欲しい

using namespace PSL;
int size;
int check = 0xdeadbeef;

{
	PSLVM vm;
	vm.loadScript("text.psl");
	variable::buffer buf;
	vm.writeCompiledCode(buf);
	FILE *fp = fopen("binary.psl", "wb");
	size = buf.size();
	fwrite(&check, 1, sizeof(check), fp);	// ヘッダを書き込む
	fwrite(buf.get(), 1, size, fp);
	fclose(fp);
}

//////

{
	FILE *fp = fopen("binary.psl", "rb");
	fread(&check, 1, sizeof(check), fp);
	if (check != 0xdeadbeef)	// ヘッダをチェックする
		return 1;
	void *buf = malloc(size);
	fread(buf, 1, size, fp);

	PSLVM vm;
	vm.loadCompiledCode(buf, size);
	vm.run();

	free(buf);
	fclose(fp);
}

暗号化などの処理が必要であれば
fwriteする前、freadした後、に処理すればよい

既知の問題

メンバ変数を持たずメンバ関数のみを持つスクリプトクラスを保存しようとするとうまくいかないことが知られている
今のところは何らかのダミーメンバを持たせるなどして対応すること

Clone this wiki locally