<html>
<head>
<title>SPVMネイティブAPI仕様 1.0</title>
<meta charset="UTF-8">
<link rel="shortcut icon" href="/images/spvm-logo.png">
<link rel="stylesheet" type="text/css" href="/css/common.css">
<script type="text/javascript" src="/js/jquery-1.9.0.min.js"></script>
<script type="text/javascript" src="/js/google-code-prettify/prettify.js"></script>
<link type="text/css" rel="stylesheet" href="/js/google-code-prettify/prettify.css"/>
<script>
$(function(){
// google code prettifyの有効化
$("pre").addClass("prettyprint");
function init(event){
prettyPrint();
}
if(window.addEventListener)window.addEventListener("load",init,false);
else if(window.attachEvent)window.attachEvent("onload",init);
$(".to-top").click(function() {
// ページの一番上までスクロールさせます。
$('body, html').animate({scrollTop: 0}, 300, 'linear');;
});
});
</script>
</head>
<body>
<div class="header">
<div class="container">
<h1>
<a style="color:#333;text-decoration:none;" href="/"><img src="/images/spvm-logo.png">SPVMドキュメント 1.0 ベータ</a>
</h1>
</div>
</div>
<div class="container">
<div>
<a href="/">SPVMドキュメント</a> > SPVMネイティブAPI仕様
</div>
<h2 id="native-api-summary">SPVMネイティブAPI仕様</a></h2>
<p>
最終更新日 2019年7月16日
<br><b>現在この日本語の翻訳ドキュメントは、SPVMの最新のドキュメントに追随していません。</b>
<br>最新のドキュメントは<a href="https://yuki-kimoto.github.io/spvmdoc-public/">SPVM Document</a>を参照してください。
<br>SPVMは1.0のリリースに向けて、活発に試験と開発が行われています。
</p>
<p>
<b>SPVMネイティブAPI仕様</b>がこのドキュメントには記述されています。SPVMは、1.0のリリースに向けて、ベータテスト中です。SPVMネイティブAPI仕様は、警告なく変更されることがあります。
</p>
<h2 id="native-api-toc">目次</h2>
<ul class="toc">
<li><a href="#native-api-summary">SPVMネイティブAPIとは</a></li>
<li><a href="#native-api-native-sub-declaration">ネイティブサブルーチンの宣言</a></li>
<li><a href="#native-api-native-sub-definition">ネイティブサブルーチンの定義</a></li>
<li><a href="#native-api-native-sub-compile">ネイティブサブルーチンのコンパイル</a></li>
<li><a href="#native-api-native-sub-get-arg">引数の取得</a></li>
<li><a href="#native-api-native-sub-set-retval">戻り値の設定</a></li>
<li><a href="#native-api-native-call-sub">サブルーチンの呼び出し</a></li>
<li><a href="#native-api-native-sub-scope">ネイティブサブルーチンのスコープ</a></li>
<li><a href="#native-api-native-sub-exception">ネイティブサブルーチンにおける例外</a></li>
<li><a href="#native-api-use-pointer-type">ポインタ型の利用</a></li>
<li><a href="#native-api-list">ネイティブAPIの一覧</a></li>
</ul>
<h2 id="native-api-summary">SPVMネイティブAPIとは</h2>
<p>
SPVMネイティブAPIとは、SPVMのネイティブサブルーチンの中で呼び出すことのできるC言語のAPIのことです。SPVMのネイティブサブルーチンの仕様についてもここに記述されます。
</p>
<ul class="list">
<li>ネイティブサブルーチンの定義方法</li>
<li>SPVMのサブルーチンの引数をネイティブサブルーチンで受け取る</li>
<li>ネイティブサブルーチンの戻り値を、SPVMのサブルーチンの戻り値として返す</li>
<li>SPVMの配列の要素をC言語の配列として取得</li>
</ul>
<p>
作成したネイティブサブルーチンは、SPVMから呼び出すことができます。
</p>
<h2 id="native-api-native-sub-declaration">SPVMネイティブサブルーチンの宣言</h2>
<p>
SPVMネイティブサブルーチンの宣言は、サブルーチンのディスクリプタ「native」を使うことによって行います。サブルーチンのブロックを書かずに、セミコロンで終わります。以下は、Foo::Barというモジュールの中で宣言する場合の例です。
</p>
<pre>
# Foo/Bar.spvm
package Foo::Bar {
native sub sum : int ($num1 : int, $num2 : int);
}
</pre>
<h2 id="native-api-native-sub-definition">ネイティブサブルーチンの定義</h2>
<p>
ネイティブサブルーチンの定義は、ネイティブソースファイルの中で行います。ネイティブソースファイルは、SPVMのモジュールの拡張子を、対象の言語の拡張子に変えたものになります。たとえばC言語であれば「.c」に変えたものです。C++であれば、「.cpp」に変えたものです。これは、ネイティブサブルーチンの設定において、変更することができます。
</p>
<pre>
# モジュール名がFoo::Barの場合のネイティブソースファイル
Foo/Bar.c
</pre>
<p>
ネイティブソースファイルを作成するときは、合わせてネイティブ設定ファイルを作成する必要があります。ネイティブ設定ファイルは、SPVMのモジュールの拡張子を「.config」に変えたものになります。ネイティブ設定ファイルが存在しない場合は、例外が発生します。
</p>
<pre>
# モジュール名がFoo::Barの場合のネイティブ設定ファイル
Foo/Bar.config
</pre>
<p>
ネイティブ設定ファイルはPerlのソースコードです。SPVM::Builder::Configオブジェクトをソースコードの最後に記述して、返却しなければなりません。そうでない場合は、例外が発生します。
</p>
<p>
SPVMと同じC99で、C言語を書きたい場合は、以下のように記述します。
</p>
<pre>
use strict;
use warnings;
use SPVM::Builder::Config;
my $bconf = SPVM::Builder::Config->new_c99;
$bconf;
</pre>
<p>
C99以外でコンパイルしたい場合や、ライブラリを追加したい場合はSPVM::Builder::Configのドキュメントのサンプルを見てください。
</p>
<p>
ネイティブサブルーチンの定義は、ネイティブソースファイルの中で行います。この場合の例は「Foo/Bar.c」です。
</p>
<pre>
#include "spvm_native.h"
int32_t SPNATIVE__Foo__Bar__sum(SPVM_ENV* env, SPVM_VALUE* stack) {
int32_t num1 = stack[0].ival;
int32_t num2 = stakc[1].ival;
int32_t total = num1 + num2;
stack[0].ival = total;
return SPVM_SUCCESS;
}
</pre>
<p>
ネイティブソースファイルの先頭で「spvm_native.h」をインクルードしてください。このヘッダファイルには、SPVMネイティブAPIと必要な構造体が定義されています。
</p>
<p>
ネイティブサブルーチンの定義は、簡単なC言語の関数です。
</p>
<p>
ネイティブサブルーチンのCにおける関数名は「SPNATIVE__」で始まり、モジュール名の「::」を「__」に変換したものが続き、「__」が続き、サブルーチン名で終わります。SPVMにおけるサブルーチン名との対応が正しくない場合は、コンパイルエラーが発生します。
</p>
<p>
引数は二つで、第一引数は、実行環境の情報を持った「SPVM_ENV* env」で、第二引数は引数と戻り値に利用される「SPVM_VALUE* stack」です。
</p>
<p>
戻り値の型は「int32_t」です。サブルーチンが例外を発生させる場合は「SPVM_EXCEPTION」、それ以外の場合は「SPVM_SUCCESS」を返却します。
</p>
<p>
上記のサンプルでは、SPVMのint型の引数を二つ受け取り、合計を計算し、戻り値を返すということを行っています。
</p>
<h2 id="native-api-native-sub-compile">ネイティブサブルーチンのコンパイル</h2>
<p>
ネイティブサブルーチンは、Perlをコンパイルしたコンパイラで、コンパイルされて、OSに応じた、動的に読み可能な共有ライブラリにコンパイルされます。Unix/Linuxにおいては、共有ライブラリ(.so)、Windowsにおいてはダイナミックリンクライブラリ(.dll)などです。
</p>
<p>
動的に読み可能な共有ライブラリへのコンパイルは、SPVMのコンパイル時に行われます。コンパイルのときに、ビルドディレクトリが存在していなければなりません。ビルドディレクトリが存在しない場合は、例外が発生します。
</p>
<p>
ビルドディレクトリのデフォルトは、実行したPerlスクリプトが存在するディレクトリの「spvm_build」ディレクトリで、環境変数「SPVM_BUILD_DIR」で変更することができます。
</p>
<p>
PerlからSPVMネイティブサブルーチンを利用したい場合は実行したPerlスクリプトが存在するディレクトリに「spvm_build」ディレクトリ作成します。
</p>
<pre>
script.pl
spvm_build/
</pre>
<p>
中間的に生成されるオブジェクトファイルは、ビルドディレクトリの下の「work/object」の下に生成されます。オブジェクトファイル名は、SPVMのモジュールの拡張子を「.o」に変えたものになります。
</p>
<pre>
spvm_build/work/object/Foo/Bar.o
</pre>
<p>
動的に読み可能な共有ライブラリは、ビルドディレクトリの下の「work/lib」の下に生成されます。動的に読み可能な共有ライブラリのファイル名は、SPVMのモジュールの拡張子を、OSに応じた、動的に読み可能な共有ライブラリの拡張子に変えたものになります。
</p>
<pre>
# Unix/Linux
spvm_build/work/object/Foo/Bar.so
# Windows
spvm_build/work/object/Foo/Bar.dll
</pre>
<h2 id="native-api-native-sub-get-arg">引数の取得</h2>
<ul class="list">
<li><a href="#native-api-native-sub-get-arg-stack">引数とスタック</a></li>
<li><a href="#native-api-native-sub-get-arg-byte">byte型の引数の取得</a></li>
<li><a href="#native-api-native-sub-get-arg-short">short型の引数の取得</a></li>
<li><a href="#native-api-native-sub-get-arg-int">int型の引数の取得</a></li>
<li><a href="#native-api-native-sub-get-arg-long">long型の引数の取得</a></li>
<li><a href="#native-api-native-sub-get-arg-float">float型の引数の取得</a></li>
<li><a href="#native-api-native-sub-get-arg-double">double型の引数の取得</a></li>
<li><a href="#native-api-native-sub-get-arg-object">オブジェクト型の引数の取得</a></li>
<li><a href="#native-api-native-sub-get-arg-stack">引数のスタック</a></li>
<li><a href="#native-api-native-sub-get-arg-byte-ref">byteのリファレンス型の引数の取得</a></li>
<li><a href="#native-api-native-sub-get-arg-short-ref">shortのリファレンス型の引数の取得</a></li>
<li><a href="#native-api-native-sub-get-arg-int-ref">intのリファレンス型の引数の取得</a></li>
<li><a href="#native-api-native-sub-get-arg-long-ref">longのリファレンス型の引数の取得</a></li>
<li><a href="#native-api-native-sub-get-arg-float-ref">floatのリファレンス型の引数の取得</a></li>
<li><a href="#native-api-native-sub-get-arg-double-ref">doubleのリファレンス型の引数の取得</a></li>
<li><a href="#native-api-native-sub-get-arg-mulnum">複数数値型の引数の取得</a></li>
</ul>
<h3 href="#native-api-native-sub-get-arg-stack">引数とスタック</h3>
<p>
スタックとは、ネイティブサブルーチンの定義における第二引数で渡される「SPVM_VALUE* stack」のことで、この中に引数が格納されています。
</p>
<pre>
int32_t SPNATIVE__Foo__Bar__sum(SPVM_ENV* env, SPVM_VALUE* stack) {
}
</pre>
<p>
SPVM_VALUEは、SPVMの値を格納するためのC言語の共用体です。数値型、オブジェクト型、リファレンス型の値を保存できます。
</p>
<p>
「SPVM_VALUE* stack」の「SPVM_VALUE型の配列」の先頭のポインタです。SPVM側からコールされたネイティブサブルーチンの引数の値がこの配列に設定されます。
</p>
<p>
たとえば、int型の第一引数の値を取得する場合は、以下のように書きます。
</p>
<pre>
int32_t args1 = stack[0].ival;
</pre>
<p>
たとえば、long型の第二引数の値を取得する場合は、以下のように書きます。
</p>
<pre>
int64_t args2 = stack[0].lval;
</pre>
<h3 id="native-api-native-sub-get-arg-byte">byte型の引数の取得</h3>
<p>
SPVMのbyte型の引数を取得するには、bvalフィールドにアクセスします。C言語のint8_t型に代入します。
</p>
<pre>
int8_t args1 = stack[0].bval;
</pre>
<h3 id="native-api-native-sub-get-arg-short">short型の引数の取得</h3>
<p>
SPVMのshort型の引数を取得するには、svalフィールドにアクセスします。C言語のint16_t型に代入します。
</p>
<pre>
int16_t args1 = stack[0].sval;
</pre>
<h3 id="native-api-native-sub-get-arg-int">int型の引数の取得</h3>
<p>
SPVMのint型の引数を取得するには、ivalフィールドにアクセスします。C言語のint32_t型に代入します。
</p>
<pre>
int32_t args1 = stack[0].ival;
</pre>
<h3 id="native-api-native-sub-get-arg-long">long型の引数の取得</h3>
<p>
SPVMのlong型の引数を取得するには、lvalフィールドにアクセスします。C言語のint64_t型に代入します。
</p>
<pre>
int64_t args1 = stack[0].lval;
</pre>
<h3 id="native-api-native-sub-get-arg-float">float型の引数の取得</h3>
<p>
SPVMのfloat型の引数を取得するには、fvalフィールドにアクセスします。C言語のfloat型に代入します。
</p>
<pre>
float args1 = stack[0].fval;
</pre>
<h3 id="native-api-native-sub-get-arg-double">double型の引数の取得</h3>
<p>
SPVMのdouble型の引数を取得するには、dvalフィールドにアクセスします。C言語のdouble型に代入します。
</p>
<pre>
double args1 = stack[0].dval;
</pre>
<h3 id="native-api-native-sub-get-arg-object">オブジェクト型の引数の取得</h3>
<p>
SPVMのobject型の引数を取得するには、ovalフィールドにアクセスします。C言語のvoid*型に代入します。
</p>
<pre>
void* args1 = stack[0].oval;
</pre>
<h3 id="native-api-native-sub-get-arg-byte-ref">byteのリファレンス型の引数の取得</h3>
<p>
SPVMのbyteのリファレンス型の引数を取得するには、brefフィールドにアクセスします。C言語のint8_t*型に代入します。
</p>
<pre>
int8_t* args1 = stack[0].bref;
</pre>
<h3 id="native-api-native-sub-get-arg-short">shortのリファレンス型の引数の取得</h3>
<p>
SPVMのshortのリファレンス型の引数を取得するには、srefフィールドにアクセスします。C言語のint16_t*型に代入します。
</p>
<pre>
int16_t* args1 = stack[0].sref;
</pre>
<h3 id="native-api-native-sub-get-arg-int">intのリファレンス型の引数の取得</h3>
<p>
SPVMのintのリファレンス型の引数を取得するには、irefフィールドにアクセスします。C言語のint32_t*型に代入します。
</p>
<pre>
int32_t* args1 = stack[0].iref;
</pre>
<h3 id="native-api-native-sub-get-arg-long">longのリファレンス型の引数の取得</h3>
<p>
SPVMのlongのリファレンス型の引数を取得するには、lrefフィールドにアクセスします。C言語のint64_t*型に代入します。
</p>
<pre>
int64_t* args1 = stack[0].lref;
</pre>
<h3 id="native-api-native-sub-get-arg-float">floatのリファレンス型の引数の取得</h3>
<p>
SPVMのfloatのリファレンス型の引数を取得するには、frefフィールドにアクセスします。C言語のfloat*型に代入します。
</p>
<pre>
float* args1 = stack[0].fref;
</pre>
<h3 id="native-api-native-sub-get-arg-double">doubleのリファレンス型の引数の取得</h3>
<p>
SPVMのdoubleのリファレンス型の引数を取得するには、drefフィールドにアクセスします。C言語のdouble*型に代入します。
</p>
<pre>
double* args1 = stack[0].dref;
</pre>
<h3 id="native-api-native-sub-get-arg-mulnum">複数数値型の引数の取得</h3>
<p>
ネイティブサブルーチンにおいては、複数数値型の引数は、複数の引数に代入されます。
</p>
<p>
たとえば、SPVM::Complex_2d型の引数の場合は、二つの引数から取得します。フィールド名からはアクセスできないことに注意してください。
</p>
<pre>
double args_re = stack[0].dval;
double args_im = stack[1].dval;
</pre>
<h2 id="native-api-native-sub-set-retval">戻り値の設定</h2>
<ul class="list">
<li><a href="#native-api-native-sub-set-retval-stack">戻り値とスタック</a></li>
<li><a href="#native-api-native-sub-set-retval-byte">byte型の戻り値の設定</a></li>
<li><a href="#native-api-native-sub-set-retval-short">short型の戻り値の設定</a></li>
<li><a href="#native-api-native-sub-set-retval-int">int型の戻り値の設定</a></li>
<li><a href="#native-api-native-sub-set-retval-long">long型の戻り値の設定</a></li>
<li><a href="#native-api-native-sub-set-retval-float">float型の戻り値の設定</a></li>
<li><a href="#native-api-native-sub-set-retval-double">double型の戻り値の設定</a></li>
<li><a href="#native-api-native-sub-set-retval-object">オブジェクト型の戻り値の設定</a></li>
<li><a href="#native-api-native-sub-set-retval-mulnum">複数数値型の戻り値の設定</a></li>
</ul>
<h3 id="native-api-native-sub-set-retval-stack">戻り値とスタック</h3>
<p>
ネイティブサブルーチンは、C言語のreturn文によって戻り値を返すのではなく、スタックを使って戻り値を設定します。
</p>
<p>
たとえば、int型の戻り値を返す場合は、以下のように書きます。
</p>
<pre>
stack[0].ival = 3;
</pre>
<p>
たとえば、long型の第二引数の値を取得する場合は、以下のように書きます。
</p>
<pre>
stack[0].lval = 56;
</pre>
<h3 id="native-api-native-sub-set-retval-byte">byte型の戻り値の設定</h3>
<p>
SPVMのbyte型の戻り値を設定するには、bvalフィールドに代入します。C言語のint8_t型の値を代入します。
</p>
<pre>
int8_t retval;
stack[0].bval = retval;
</pre>
<h3 id="native-api-native-sub-set-retval-short">short型の戻り値の設定</h3>
<p>
SPVMのshort型の戻り値を設定するには、svalフィールドに代入します。C言語のint16_t型の値を代入します。
</p>
<pre>
int16_t retval;
stack[0].sval = retval;
</pre>
<h3 id="native-api-native-sub-set-retval-int">int型の戻り値の設定</h3>
<p>
SPVMのint型の戻り値を設定するには、ivalフィールドに代入します。C言語のint32_t型の値を代入します。
</p>
<pre>
int32_t retval;
stack[0].ival = retval;
</pre>
<h3 id="native-api-native-sub-set-retval-long">long型の戻り値の設定</h3>
<p>
SPVMのlong型の戻り値を設定するには、lvalフィールドに代入します。C言語のint64_t型の値を代入します。
</p>
<pre>
int64_t retval;
stack[0].lval = retval;
</pre>
<h3 id="native-api-native-sub-set-retval-float">float型の戻り値の設定</h3>
<p>
SPVMのfloat型の戻り値を設定するには、fvalフィールドに代入します。C言語のfloat型の値を代入します。
</p>
<pre>
float retval;
stack[0].fval = retval;
</pre>
<h3 id="native-api-native-sub-set-retval-double">double型の戻り値の設定</h3>
<p>
SPVMのdouble型の戻り値を設定するには、dvalフィールドに代入します。C言語のdouble型の値を代入します。
</p>
<pre>
double retval;
stack[0].dval = retval;
</pre>
<h3 id="native-api-native-sub-set-retval-object">オブジェクト型の戻り値の設定</h3>
<p>
SPVMのobject型の戻り値を設定するには、ovalフィールドに代入します。C言語のvoid*型の値を代入します。
</p>
<pre>
void* retval;
stack[0].oval = retval;
</pre>
<h3 id="native-api-native-sub-set-retval-mulnum">複数数値型の戻り値の設定</h3>
<p>
ネイティブサブルーチンにおいては、複数数値型の戻り値は、複数の戻り値に代入します。
</p>
<p>
たとえば、SPVM::Complex_2d型の戻り値の場合は、二つの戻り値を設定します。
</p>
<pre>
double retval_re;
double retval_im;
stack[0].dval = retval_re;
stack[1].dval = retval_im;
</pre>
<h2 id="native-api-native-call-sub">サブルーチンの呼び出し</h2>
<p>
SPVMのサブルーチンを呼び出すには、最初に、<a href="#native-api-native-sub-api-sub_id">sub_id</a>関数か、<a href="#native-api-native-sub-api-method_sub_id">method_sub_id</a>関数を使ってサブルーチンのIDを取得します
</p>
<pre>
// メソッドでないサブルーチンの場合
int32_t sub_id = env->get_sub_id(env, "Foo", "sum", "int(int,int)");
// メソッドの場合
int32_t sub_id = env->get_method_sub_id(env, object, "sum", "int(self,int,int)");
</pre>
<p>
sub_idが0より小さい場合は、サブルーチンが見つからなかったことを示します。以下のように、例外処理をしておくと安全です。
</p>
<pre>
if (sub_id < 0) {
SPVM_DIE("Can't find sub id", "Foo/Bar.c", __LINE__);
}
</pre>
<p>
SPVMのサブルーチンの引数を、サブルーチン呼び出しを行う前に、stackに設定します。
</p>
<pre>
stack[0].ival = 1;
stack[0].ival = 2;
</pre>
<p>
SPVMのサブルーチンを呼び出すには<a href="#native-api-native-sub-api-call_sub">call_sub</a>関数を使用します。
</p>
<pre>
int32_t exception_flag = env->call_sub(env, sub_id, stack);
</pre>
<p>
サブルーチンで例外が発生した場合は0以外、例外が発生しなかった場合は、0が返されます。
</p>
<p>
サブルーチンの戻り値は、スタックの最初の要素に保存されています。
</p>
<pre>
int32_t total = stack[0].ival;
</pre>
<h2 id="native-api-native-sub-scope">ネイティブサブルーチンのスコープ</h2>
<p>
ネイティブサブルーチンは、全体がスコープに囲まれています。
</p>
<p>
モータルスタックに追加されたオブジェクトは、ネイティブサブルーチンが終了すると、オブジェクトのリファレンスカウントが自動的に1減らされます。リファレンスカウントが0になった場合は、解放されます。
</p>
<p>
オブジェクトを、モータルスタックに追加するには、push_mortalを使用します。
</p>
<pre>
env->push_mortal(env, object);
</pre>
<p>
通常は「new_object」などのオブジェクトを生成するネイティブAPIは、自動的に生成されたオブジェクトをモータルスタックに追加するので、これを使う必要はありません。
</p>
<p>
スコープを作成するには「enter_scope」を使用します。戻り値は、そのスコープのIDです。
</p>
<pre>
int32_t scope_id = env->enter_scope(env);
</pre>
<p>
スコープを終了するには「leave_scope」を使用します。引数には、「enter_scope」で取得した、スコープIDを指定する必要があります。
</p>
<pre>
env->leave_scope(env, scope_id);
</pre>
<p>
オブジェクトをモータルスタックから取り除くには「remove_mortal」を使用します。引数には「enter_scope」で取得したスコープIDと取り除きたいオブジェクトを指定します。オブジェクトはモータルスタックから取り除かれ、リファレンスカウントが自動的に1減らされます。リファレンスカウントが0になった場合は、解放されます。
</p>
<pre>
env->remove_mortal(env, scope_id, object);
</pre>
<p>
モータルスタックに関する情報は、envに保存されているので、スレッドローカルなデータです。
</p>
<h2 id="native-api-native-sub-exception">ネイティブサブルーチンにおける例外</h2>
<p>
ネイティブサブルーチンにおいて、例外が発生したかどうかを示すのは、戻り値です。
</p>
<pre>
return SPVM_SUCCESS;
return SPVM_EXCEPTION;
</pre>
<p>
例外が発生しなかった場合は「SPVM_SUCCESS」を返します。これは「0」として定義されています。
<p>
<p>
例外が発生した場合は「SPVM_EXCEPTION」を返します。これは「0」以外の値として定義されています。
<p>
<p>
例外メッセージを、自分で設定したい場合は「new_string」で例外メッセージを作成して「set_exception」で設定できます。
</p>
<pre>
env->set_exception(env, env->new_string(env, "Exception occur");\
return SPVM_EXCEPTION;
</pre>
<p>
例外メッセージが設定されなかった場合は、デフォルトの例外メッセージが設定されます。
</p>
<p>
通常の場合は、これを使いやすくした「SPVM_DIE」が定義されていますので、これを使うのがよいでしょう。
</p>
<pre>
SPVM_DIE("Error. Values must be %d and %d", 3, 5, "Foo/Bar.c", __LINE__);
</pre>
<p>
SPVM_DIEは、C言語のsprintf関数と同じ使い方ができます。最後から二つ目には、このファイル名を、最後の引数には、行番号を必ず含めてください。メッセージが255バイトを超える場合は、超えた部分が切り捨てられます。
</p>
<p>
例外はenvに保存されているので、スレッドローカルなデータです。
</p>
<h2 id="native-api-use-pointer-type">ポインタ型の利用</h2>
<p>
SPVMには、ポインタ型という型が存在しますが、利用方法について解説します。
</p>
<p>
ポインタ型の定義は、SPVMのパッケージ定義で、pointer_tデスクリプタを指定します。ポインタ型は、フィールド定義を持つことはできません。この例では、C標準の「struct tm」をポインタ型として利用する方法を解説します。
</p>
<pre>
# MyTimeInfo.spvm
package MyTimeInfo : pointer_t {
# Constructor
native sub new : MyTimeInfo();
# Get second
native sub sec : int ($self : self);
# Destructor
native sub DESTROY : ($self : self);
}
</pre>
<p>
newとうコンストラクタ、secという秒の情報をとるメソッド、DESTROYというデストラクタを定義しています。これらは、ネイティブサブルーチンです。
</p>
<p>
次にC言語側での定義です。
</p>
<pre>
# MyTimeInfo.c
int32_t SPNATIVE__MyTimeInfo__new(SPVM_ENV* env, SPVM_VALUE* stack) {
// Alloc strcut tm
void* tm_ptr = env->alloc_memory_block_zero(sizeof(struct tm));
// Create strcut tm instance
void* tm_obj = env->new_pointer(env, "MyTimeInfo", tm_ptr);
stack[0].oval = tm_obj;
return SPVM_SUCCESS;
}
int32_t SPNATIVE__MyTimeInfo__sec(SPVM_ENV* env, SPVM_VALUE* stack) {
void* tm_obj = stack[0].oval;
strcut tm* tm_ptr = (struct tm*)env->get_pointer(env, tm_obj);
stack[0].ival = tm_ptr->tm_sec;
return SPVM_SUCCESS;
}
int32_t SPNATIVE__MyTimeInfo__DESTROY(SPVM_ENV* env, SPVM_VALUE* stack) {
void* tm_obj = stack[0].oval;
strcut tm* tm_ptr = (struct tm*)env->get_pointer(env, tm_obj);
env->free_memory_block(tm_ptr);
return SPVM_SUCCESS;
}
</pre>
<p>
コンストラクタnewでは、まず「struct tm」のメモリを、alloc_memory_block_zero関数で、割り当てます。これは、SPVMでメモリブロックを一つ確保する関数です。mallocでの同様のことがかのうですが、この関数は、メモリブロックのカウントを一つ増やすので、メモリリークの発見が容易になります。
</p>
<pre>
// Alloc strcut tm
void* tm_ptr = env->alloc_memory_block_zero(sizeof(struct tm));
</pre>
<p>
次に、new_pointer関数を使って、確保したメモリに、MyTimeInfoを関連付けた新しいポインタ型のオブジェクトを作成します。
</p>
<pre>
// Create strcut tm instance
void* tm_obj = env->new_pointer(env, "MyTimeInfo", tm_ptr);
</pre>
<p>
これを戻り値として返せば、コンストラクタの完成です。
</p>
<pre>
stack[0].ival = tm_ptr->tm_sec;
return SPVM_SUCCESS;
</pre>
<p>
次に、tm_secの値を取得してみましょう。secメソッドです。get_pointer関数を使うと、ポインタ型のオブジェクトから「struct tm」として割り当てられたメモリのポインタを取得することができます。
</p>
<pre>
void* tm_obj = stack[0].oval;
strcut tm* tm_ptr = (struct tm*)env->get_pointer(env, tm_obj);
stack[0].ival = tm_ptr->tm_sec;
</pre>
<p>
最後はデストラクタです。確保されたメモリは、自動的には解放されないので、必ずデストラクタを定義しましょう。
</p>
<pre>
int32_t SPNATIVE__MyTimeInfo__DESTROY(SPVM_ENV* env, SPVM_VALUE* stack) {
void* tm_obj = stack[0].oval;
strcut tm* tm_ptr = (struct tm*)env->get_pointer(env, tm_obj);
env->free_memory_block(tm_ptr);
return SPVM_SUCCESS;
}
</pre>
<p>
free_memory_block関数を実行してメモリを開放します。alloc_memory_block_zeroで確保したメモリは、必ずfree_memory_block関数で解放しましょう。メモリを開放し、メモリブロック数のカウントを一つ減らします。
</p>
<h2 id="native-api-index">ネイティブAPIのインデックス</h2>
<p>
ネイティブAPIは、名前に対応するインデックスを持っています。この番号は、ネイティブサブルーチンののバイナリ互換性を保つために、永続的に維持されます。新しいAPIの追加の場合は、末尾に追加されます。
</p>
<pre>
0 runtime_package_vars_heap_offset
1 object_header_byte_size
2 weaken_backref_head
3 object_ref_count_offset
4 object_basic_type_id_offset
5 object_type_dimension_offset
6 object_runtime_type_category_offset
7 object_flag_offset
8 object_length_offset
9 byte_object_basic_type_id
10 short_object_basic_type_id
11 int_object_basic_type_id
12 long_object_basic_type_id
13 float_object_basic_type_id
14 double_object_basic_type_id
15 runtime
16 exception_object
17 native_mortal_stack
18 native_mortal_stack_top
19 native_mortal_stack_capacity
20 get_basic_type_id
21 get_field_id
22 get_field_offset
23 get_package_var_id
24 get_sub_id
25 get_method_sub_id
26 new_object_raw
27 new_object
28 new_byte_array_raw
29 new_byte_array
30 new_short_array_raw
31 new_short_array
32 new_int_array_raw
33 new_int_array
34 new_long_array_raw
35 new_long_array
36 new_float_array_raw
37 new_float_array
38 new_double_array_raw
39 new_double_array
40 new_object_array_raw
41 new_object_array
42 new_muldim_array_raw
43 new_muldim_array
44 new_mulnum_array_raw
45 new_mulnum_array
46 new_string_raw
47 new_string
48 new_string_len_raw
49 new_string_len
50 new_pointer_raw
51 new_pointer
52 concat_raw
53 concat
54 new_stack_trace_raw
55 new_stack_trace
56 length
57 get_elems_byte
58 get_elems_short
59 get_elems_int
60 get_elems_long
61 get_elems_float
62 get_elems_double
63 get_elem_object
64 set_elem_object
65 get_field_byte
66 get_field_short
67 get_field_int
68 get_field_long
69 get_field_float
70 get_field_double
71 get_field_object
72 set_field_byte
73 set_field_short
74 set_field_int
75 set_field_long
76 set_field_float
77 set_field_double
78 set_field_object
79 get_package_var_byte
80 get_package_var_short
81 get_package_var_int
82 get_package_var_long
83 get_package_var_float
84 get_package_var_double
85 get_package_var_object
86 set_package_var_byte
87 set_package_var_short
88 set_package_var_int
89 set_package_var_long
90 set_package_var_float
91 set_package_var_double
92 set_package_var_object
93 get_pointer
94 set_pointer
95 call_sub
96 get_exception
97 set_exception
98 get_ref_count
99 inc_ref_count
100 dec_ref_count
101 enter_scope
102 push_mortal
103 leave_scope
104 remove_mortal
105 is_type
106 has_callback
107 get_object_basic_type_id
108 get_object_type_dimension
109 weaken
110 isweak
111 unweaken
112 alloc_memory_block_zero
113 free_memory_block
114 get_memory_blocks_count
115 get_type_name_raw
116 get_type_name
117 new_env
118 free_env
</pre>
<h2 id="native-api-call">ネイティブAPIの呼び出し</h2>
<p>
ネイティブAPIは、引数に渡された「SPVM_ENV* env」から呼び出すことができます。第一引数に、envを渡さなければならないことに注意してください。
</p>
<pre>
int32_t basic_type_id = env->get_basic_type_id(env, "SPVM::Int");
</pre>
<h2 id="native-api-list">ネイティブAPIの一覧</h2>
<ul class="list">
<li><a href="#native-api-native-sub-api-runtime_package_vars_heap_offset">runtime_package_vars_heap_offset</a></li>
<li><a href="#native-api-native-sub-api-object_header_byte_size">object_header_byte_size</a></li>
<li><a href="#native-api-native-sub-api-weaken_backref_head">weaken_backref_head</a></li>
<li><a href="#native-api-native-sub-api-object_ref_count_offset">object_ref_count_offset</a></li>
<li><a href="#native-api-native-sub-api-object_basic_type_id_offset">object_basic_type_id_offset</a></li>
<li><a href="#native-api-native-sub-api-object_type_dimension_offset">object_type_dimension_offset</a></li>
<li><a href="#native-api-native-sub-api-object_runtime_type_category_offset">object_runtime_type_category_offset</a></li>
<li><a href="#native-api-native-sub-api-object_flag_offset">object_flag_offset</a></li>
<li><a href="#native-api-native-sub-api-object_length_offset">object_length_offset</a></li>
<li><a href="#native-api-native-sub-api-byte_object_basic_type_id">byte_object_basic_type_id</a></li>
<li><a href="#native-api-native-sub-api-short_object_basic_type_id">short_object_basic_type_id</a></li>
<li><a href="#native-api-native-sub-api-int_object_basic_type_id">int_object_basic_type_id</a></li>
<li><a href="#native-api-native-sub-api-long_object_basic_type_id">long_object_basic_type_id</a></li>
<li><a href="#native-api-native-sub-api-float_object_basic_type_id">float_object_basic_type_id</a></li>
<li><a href="#native-api-native-sub-api-double_object_basic_type_id">double_object_basic_type_id</a></li>
<li><a href="#native-api-native-sub-api-runtime">runtime</a></li>
<li><a href="#native-api-native-sub-api-exception_object">exception_object</a></li>
<li><a href="#native-api-native-sub-api-native_mortal_stack">native_mortal_stack</a></li>
<li><a href="#native-api-native-sub-api-native_mortal_stack_top">native_mortal_stack_top</a></li>
<li><a href="#native-api-native-sub-api-native_mortal_stack_capacity">native_mortal_stack_capacity</a></li>
<li><a href="#native-api-native-sub-api-get_basic_type_id">get_basic_type_id</a></li>
<li><a href="#native-api-native-sub-api-get_field_id">get_field_id</a></li>
<li><a href="#native-api-native-sub-api-get_field_offset">get_field_offset</a></li>
<li><a href="#native-api-native-sub-api-get_package_var_id">get_package_var_id</a></li>
<li><a href="#native-api-native-sub-api-get_sub_id">get_sub_id</a></li>
<li><a href="#native-api-native-sub-api-get_method_sub_id">get_method_sub_id</a></li>
<li><a href="#native-api-native-sub-api-new_object_raw">new_object_raw</a></li>
<li><a href="#native-api-native-sub-api-new_object">new_object</a></li>
<li><a href="#native-api-native-sub-api-new_byte_array_raw">new_byte_array_raw</a></li>
<li><a href="#native-api-native-sub-api-new_byte_array">new_byte_array</a></li>
<li><a href="#native-api-native-sub-api-new_short_array_raw">new_short_array_raw</a></li>
<li><a href="#native-api-native-sub-api-new_short_array">new_short_array</a></li>
<li><a href="#native-api-native-sub-api-new_int_array_raw">new_int_array_raw</a></li>
<li><a href="#native-api-native-sub-api-new_int_array">new_int_array</a></li>
<li><a href="#native-api-native-sub-api-new_long_array_raw">new_long_array_raw</a></li>
<li><a href="#native-api-native-sub-api-new_long_array">new_long_array</a></li>
<li><a href="#native-api-native-sub-api-new_float_array_raw">new_float_array_raw</a></li>
<li><a href="#native-api-native-sub-api-new_float_array">new_float_array</a></li>
<li><a href="#native-api-native-sub-api-new_double_array_raw">new_double_array_raw</a></li>
<li><a href="#native-api-native-sub-api-new_double_array">new_double_array</a></li>
<li><a href="#native-api-native-sub-api-new_object_array_raw">new_object_array_raw</a></li>
<li><a href="#native-api-native-sub-api-new_object_array">new_object_array</a></li>
<li><a href="#native-api-native-sub-api-new_muldim_array_raw">new_muldim_array_raw</a></li>
<li><a href="#native-api-native-sub-api-new_muldim_array">new_muldim_array</a></li>
<li><a href="#native-api-native-sub-api-new_mulnum_array_raw">new_mulnum_array_raw</a></li>
<li><a href="#native-api-native-sub-api-new_mulnum_array">new_mulnum_array</a></li>
<li><a href="#native-api-native-sub-api-new_string_raw">new_string_raw</a></li>
<li><a href="#native-api-native-sub-api-new_string">new_string</a></li>
<li><a href="#native-api-native-sub-api-new_string_len_raw">new_string_len_raw</a></li>
<li><a href="#native-api-native-sub-api-new_string_len">new_string_len</a></li>
<li><a href="#native-api-native-sub-api-new_pointer_raw">new_pointer_raw</a></li>
<li><a href="#native-api-native-sub-api-new_pointer">new_pointer</a></li>
<li><a href="#native-api-native-sub-api-concat_raw">concat_raw</a></li>
<li><a href="#native-api-native-sub-api-concat">concat</a></li>
<li><a href="#native-api-native-sub-api-new_stack_trace_raw">new_stack_trace_raw</a></li>
<li><a href="#native-api-native-sub-api-new_stack_trace">new_stack_trace</a></li>
<li><a href="#native-api-native-sub-api-length">length</a></li>
<li><a href="#native-api-native-sub-api-get_elems_byte">get_elems_byte</a></li>
<li><a href="#native-api-native-sub-api-get_elems_short">get_elems_short</a></li>
<li><a href="#native-api-native-sub-api-get_elems_int">get_elems_int</a></li>
<li><a href="#native-api-native-sub-api-get_elems_long">get_elems_long</a></li>
<li><a href="#native-api-native-sub-api-get_elems_float">get_elems_float</a></li>
<li><a href="#native-api-native-sub-api-get_elems_double">get_elems_double</a></li>
<li><a href="#native-api-native-sub-api-get_elem_object">get_elem_object</a></li>
<li><a href="#native-api-native-sub-api-set_elem_object">set_elem_object</a></li>
<li><a href="#native-api-native-sub-api-get_field_byte">get_field_byte</a></li>
<li><a href="#native-api-native-sub-api-get_field_short">get_field_short</a></li>
<li><a href="#native-api-native-sub-api-get_field_int">get_field_int</a></li>
<li><a href="#native-api-native-sub-api-get_field_long">get_field_long</a></li>
<li><a href="#native-api-native-sub-api-get_field_float">get_field_float</a></li>
<li><a href="#native-api-native-sub-api-get_field_double">get_field_double</a></li>
<li><a href="#native-api-native-sub-api-get_field_object">get_field_object</a></li>
<li><a href="#native-api-native-sub-api-set_field_byte">set_field_byte</a></li>
<li><a href="#native-api-native-sub-api-set_field_short">set_field_short</a></li>
<li><a href="#native-api-native-sub-api-set_field_int">set_field_int</a></li>
<li><a href="#native-api-native-sub-api-set_field_long">set_field_long</a></li>
<li><a href="#native-api-native-sub-api-set_field_float">set_field_float</a></li>
<li><a href="#native-api-native-sub-api-set_field_double">set_field_double</a></li>
<li><a href="#native-api-native-sub-api-set_field_object">set_field_object</a></li>
<li><a href="#native-api-native-sub-api-get_package_var_byte">get_package_var_byte</a></li>
<li><a href="#native-api-native-sub-api-get_package_var_short">get_package_var_short</a></li>
<li><a href="#native-api-native-sub-api-get_package_var_int">get_package_var_int</a></li>
<li><a href="#native-api-native-sub-api-get_package_var_long">get_package_var_long</a></li>
<li><a href="#native-api-native-sub-api-get_package_var_float">get_package_var_float</a></li>
<li><a href="#native-api-native-sub-api-get_package_var_double">get_package_var_double</a></li>
<li><a href="#native-api-native-sub-api-get_package_var_object">get_package_var_object</a></li>
<li><a href="#native-api-native-sub-api-set_package_var_byte">set_package_var_byte</a></li>
<li><a href="#native-api-native-sub-api-set_package_var_short">set_package_var_short</a></li>
<li><a href="#native-api-native-sub-api-set_package_var_int">set_package_var_int</a></li>
<li><a href="#native-api-native-sub-api-set_package_var_long">set_package_var_long</a></li>
<li><a href="#native-api-native-sub-api-set_package_var_float">set_package_var_float</a></li>
<li><a href="#native-api-native-sub-api-set_package_var_double">set_package_var_double</a></li>
<li><a href="#native-api-native-sub-api-set_package_var_object">set_package_var_object</a></li>
<li><a href="#native-api-native-sub-api-get_pointer">get_pointer</a></li>
<li><a href="#native-api-native-sub-api-set_pointer">set_pointer</a></li>
<li><a href="#native-api-native-sub-api-call_sub">call_sub</a></li>
<li><a href="#native-api-native-sub-api-get_exception">get_exception</a></li>
<li><a href="#native-api-native-sub-api-set_exception">set_exception</a></li>
<li><a href="#native-api-native-sub-api-get_ref_count">get_ref_count</a></li>
<li><a href="#native-api-native-sub-api-inc_ref_count">inc_ref_count</a></li>
<li><a href="#native-api-native-sub-api-dec_ref_count">dec_ref_count</a></li>
<li><a href="#native-api-native-sub-api-enter_scope">enter_scope</a></li>
<li><a href="#native-api-native-sub-api-push_mortal">push_mortal</a></li>
<li><a href="#native-api-native-sub-api-leave_scope">leave_scope</a></li>
<li><a href="#native-api-native-sub-api-remove_mortal">remove_mortal</a></li>
<li><a href="#native-api-native-sub-api-is_type">is_type</a></li>
<li><a href="#native-api-native-sub-api-has_callback">has_callback</a></li>
<li><a href="#native-api-native-sub-api-get_object_basic_type_id">get_object_basic_type_id</a></li>
<li><a href="#native-api-native-sub-api-get_object_type_dimension">get_object_type_dimension</a></li>
<li><a href="#native-api-native-sub-api-weaken">weaken</a></li>
<li><a href="#native-api-native-sub-api-isweak">isweak</a></li>
<li><a href="#native-api-native-sub-api-unweaken">unweaken</a></li>
<li><a href="#native-api-native-sub-api-alloc_memory_block_zero">alloc_memory_block_zero</a></li>
<li><a href="#native-api-native-sub-api-free_memory_block">free_memory_block</a></li>
<li><a href="#native-api-native-sub-api-get_memory_blocks_count">get_memory_blocks_count</a></li>
<li><a href="#native-api-native-sub-api-get_type_name_raw">get_type_name_raw</a></li>
<li><a href="#native-api-native-sub-api-get_type_name">get_type_name</a></li>
<li><a href="#native-api-native-sub-api-new_env">new_env</a></li>
<li><a href="#native-api-native-sub-api-free_env">free_env</a></li>
</ul>
<h3 id="native-api-native-sub-api-runtime_package_vars_heap_offset">runtime_package_vars_heap_offset</h3>
<p>
ランタイム構造体におけるパッケージ変数の保存領域のポインタへのオフセット。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-object_header_byte_size">object_header_byte_size</h3>
<p>
オブジェクトのヘッダーのバイトサイズ。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-object_weaken_backref_head_offset">object_weaken_backref_head_offset</h3>
<p>
オブジェクト構造体におけるウィークリファレンスのバックリファレンスへのポインタへのオフセット。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-object_ref_count_offset">object_ref_count_offset</h3>
<p>
オブジェクト構造体におけるリファレンスカウントのオフセット。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-object_basic_type_id_offset">object_basic_type_id_offset</h3>
<p>
オブジェクト構造体における基本型IDのオフセット。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-object_type_dimension_offset">object_type_dimension_offset</h3>
<p>
オブジェクト構造体における型の次元のオフセット。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-object_runtime_type_category_offset">object_runtime_type_category_offset</h3>
<p>
オブジェクト構造体におけるランタイムタイプのカテゴリーのオフセット。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-object_flag_offset">object_flag_offset</h3>
<p>
オブジェクト構造体におけるフラグのオフセット。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-object_length_offset">object_length_offset</h3>
<p>
オブジェクト構造体における長さのオフセット。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-byte_object_basic_type_id">byte_object_basic_type_id</h3>
<p>
SPVM::Byte型の基本型のID。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-short_object_basic_type_id">short_object_basic_type_id</h3>
<p>
SPVM::Short型の基本型のID。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-int_object_basic_type_id">int_object_basic_type_id</h3>
<p>
SPVM::Int型の基本型のID。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-long_object_basic_type_id">long_object_basic_type_id</h3>
<p>
SPVM::Long型の基本型のID。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-float_object_basic_type_id">float_object_basic_type_id</h3>
<p>
SPVM::Float型の基本型のID。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-double_object_basic_type_id">double_object_basic_type_id</h3>
<p>
SPVM::Double型の基本型のID。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-runtime">runtime</h3>
<p>
SPVMのランタイムへのポインタ。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-exception_object">exception_object</h3>
<p>
例外オブジェクト。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-native_mortal_stack">native_mortal_stack</h3>
<p>
ネイティブ呼び出しで利用されるモータルスタック。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-native_mortal_stack_top">native_mortal_stack_top</h3>
<p>
ネイティブ呼び出しで利用されるモータルスタックのトップ位置。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-native_mortal_stack_capacity">native_mortal_stack_capacity</h3>
<p>
ネイティブ呼び出しで利用されるモータルスタックの容量。内部的に利用されます。
</p>
<h3 id="native-api-native-sub-api-get_basic_type_id">basic_type_id</h3>
<p>
基本型の名前を指定して、基本型のIDを取得します。存在しない場合は、0より小さい値が返されます。
</p>
<pre>
int32_t (*get_basic_type_id)(SPVM_ENV* env, const char* basic_type_name);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t basic_type_id = env->get_basic_type_id(env, "SPVM::Int");
</pre>
<h3 id="native-api-native-sub-api-get_field_id">field_id</h3>
<p>
パッケージ名と、フィールド名と、シグネチャを指定して、フィールドのIDを取得します。フィールドが存在しない場合は、0より小さい値が返されます。
</p>
<pre>
int32_t (*get_field_id)(SPVM_ENV* env, const char* package_name, const char* field_name, const char* signature);
</pre>
<p>
シグネチャは、フィールドの型名と同一です。
</p>
<p>
サンプル:
</p>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "int");
</pre>
<h3 id="native-api-native-sub-api-get_field_offset">field_offset</h3>
<p>
フィールドIDを指定して、フィールドのオフセットを取得します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
int32_t (*get_field_offset)(SPVM_ENV* env, int32_t field_id);
</pre>
<h3 id="native-api-native-sub-api-get_package_var_id">get_package_var_id</h3>
<p>
パッケージ名とパッケージ変数名とシグネチャを指定して、パッケージ変数IDを取得します。パッケージ変数が存在しない場合は、0より小さい値が返されます。
</p>
<pre>
int32_t (*get_package_var_id)(SPVM_ENV* env, const char* package_name, const char* package_var_name, const char* signature);
</pre>
<p>
シグネチャは、パッケージ変数の型名と同一です。
</p>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "int");
</pre>
<h3 id="native-api-native-sub-api-get_sub_id">get_sub_id</h3>
<p>
パッケージ名とサブルーチン名とシグネチャを指定して、サブルーチンIDを取得します。サブルーチンが存在しない場合は、0より小さい値が返されます。
</p>
<pre>
int32_t (*get_sub_id)(SPVM_ENV* env, const char* package_name, const char* sub_name, const char* signature);
</pre>
<p>
シグネチャは、次のフォーマットで指定します。空白を含んではいけません。
</p>
<pre>
戻り値の型名(引数の型名1,引数の型名2,...)
</pre>
<p>
サンプル:
</p>
<pre>
int32_t sub_id = env->get_sub_id(env, "Foo", "func", "int(long,string)");
</pre>
<h3 id="native-api-native-sub-api-get_method_sub_id">get_method_sub_id</h3>
<pre>
int32_t (*get_method_sub_id)(SPVM_ENV* env, void* object, const char* method_name, const char* signature);
</pre>
<p>
オブジェクトとメソッド名を指定して、サブルーチンIDを取得します。メソッドが存在しない場合は、0より小さい値が返されます。
</p>
<p>
シグネチャは、sub_idのシグネチャと同一です。
</p>
<p>
サンプル:
</p>
<pre>
int32_t sub_id = env->get_method_sub_id(env, object, "method", "int(self,long,string)");
</pre>
<h3 id="native-api-native-sub-api-new_object_raw">new_object_raw</h3>
<p>
基本型IDを指定して、新しいオブジェクトを生成します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでなければなりません。
</p>
<pre>
void* (*new_object_raw)(SPVM_ENV* env, int32_t basic_type_id);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_objectを使用してください。
</p>
<h3 id="native-api-native-sub-api-new_object">new_object</h3>
<p>
基本型IDを指定して、新しいオブジェクトを生成し、返却します。基本型IDは、basic_type_idで取得した、正しい基本型IDでなければなりません。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*new_object)(SPVM_ENV* env, int32_t basic_type_id);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t basic_type_id = env->get_basic_type_id(env, "SPVM::Int");
void* object = env->new_object(env, basic_type_id);
</pre>
<h3 id="native-api-native-sub-api-new_byte_array_raw">new_byte_array_raw</h3>
<p>
配列の長さを指定して新しい「byte[]型」のオブジェクトを生成します。すべての要素の初期値は0です。
</p>
<pre>
void* (*new_byte_array_raw)(SPVM_ENV* env, int32_t length);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_byte_arrayを使用してください。
</p>
<h3 id="native-api-native-sub-api-new_byte_array">new_byte_array</h3>
<p>
配列の長さを指定して新しい「byte[]型」のオブジェクトを生成し、返却します。すべての要素の初期値は0です。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*new_byte_array)(SPVM_ENV* env, int32_t length);
</pre>
<p>
サンプル:
</p>
<pre>
void* byte_array_obj = env->new_byte_array(env, 100);
</pre>
<h3 id="native-api-native-sub-api-new_short_array_raw">new_short_array_raw</h3>
<p>
配列の長さを指定して新しい「short[]型」のオブジェクトを生成します。すべての要素の初期値は0です。
</p>
<pre>
void* (*new_short_array_raw)(SPVM_ENV* env, int32_t length);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_short_arrayを使用してください。
</p>
<h3 id="native-api-native-sub-api-new_short_array">new_short_array</h3>
<p>
配列の長さを指定して新しい「short[]型」のオブジェクトを生成し、返却します。すべての要素の初期値は0です。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*new_short_array)(SPVM_ENV* env, int32_t length);
</pre>
<p>
サンプル:
</p>
<pre>
void* short_array_obj = env->new_short_array(env, 100);
</pre>
<h3 id="native-api-native-sub-api-new_int_array_raw">new_int_array_raw</h3>
<p>
配列の長さを指定して新しい「int[]型」のオブジェクトを生成します。すべての要素の初期値は0です。
</p>
<pre>
void* (*new_int_array_raw)(SPVM_ENV* env, int32_t length);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_int_arrayを使用してください。
</p>
<h3 id="native-api-native-sub-api-new_int_array">new_int_array</h3>
<p>
配列の長さを指定して新しい「int[]型」のオブジェクトを生成し、返却します。すべての要素の初期値は0です。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*new_int_array)(SPVM_ENV* env, int32_t length);
</pre>
<p>
サンプル:
</p>
<pre>
void* int_array_obj = env->new_int_array(env, 100);
</pre>
<h3 id="native-api-native-sub-api-new_long_array_raw">new_long_array_raw</h3>
<p>
配列の長さを指定して新しい「long[]型」のオブジェクトを生成します。すべての要素の初期値は0です。
</p>
<pre>
void* (*new_long_array_raw)(SPVM_ENV* env, int32_t length);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_long_arrayを使用してください。
</p>
<h3 id="native-api-native-sub-api-new_long_array">new_long_array</h3>
<p>
配列の長さを指定して新しい「long[]型」のオブジェクトを生成し、返却します。すべての要素の初期値は0です。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*new_long_array)(SPVM_ENV* env, int32_t length);
</pre>
<p>
サンプル:
</p>
<pre>
void* long_array_obj = env->new_long_array(env, 100);
</pre>
<h3 id="native-api-native-sub-api-new_float_array_raw">new_float_array_raw</h3>
<p>
配列の長さを指定して新しい「float[]型」のオブジェクトを生成します。すべての要素の初期値は0です。
</p>
<pre>
void* (*new_float_array_raw)(SPVM_ENV* env, int32_t length);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_float_arrayを使用してください。
</p>
<h3 id="native-api-native-sub-api-new_float_array">new_float_array</h3>
<p>
配列の長さを指定して新しい「float[]型」のオブジェクトを生成し、返却します。すべての要素の初期値は0です。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*new_float_array)(SPVM_ENV* env, int32_t length);
</pre>
<p>
サンプル:
</p>
<pre>
void* float_array_obj = env->new_float_array(env, 100);
</pre>
<h3 id="native-api-native-sub-api-new_double_array_raw">new_double_array_raw</h3>
<p>
配列の長さを指定して新しい「double[]型」のオブジェクトを生成します。すべての要素の初期値は0です。
</p>
<pre>
void* (*new_double_array_raw)(SPVM_ENV* env, int32_t length);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_double_arrayを使用してください。
</p>
<h3 id="native-api-native-sub-api-new_double_array">new_double_array</h3>
<p>
配列の長さを指定して新しい「double[]型」のオブジェクトを生成し、返却します。すべての要素の初期値は0です。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*new_double_array)(SPVM_ENV* env, int32_t length);
</pre>
<p>
サンプル:
</p>
<pre>
void* double_array_obj = env->new_double_array(env, 100);
</pre>
<h3 id="native-api-native-sub-api-new_object_array_raw">new_object_array_raw</h3>
<p>
基本型IDと配列の長さを指定して新しいオブジェクト型の配列を生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでなければなりません。すべての要素の初期値はNULLです。
</p>
<pre>
void* (*new_object_array_raw)(SPVM_ENV* env, int32_t basic_type_id, int32_t length);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_object_arrayを使用してください。
</p>
<h3 id="native-api-native-sub-api-new_object_array">new_object_array</h3>
<p>
基本型IDと配列の長さを指定して新しいオブジェクト型の配列を生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでなければなりません。すべての要素の初期値はNULLです。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*new_object_array)(SPVM_ENV* env, int32_t basic_type_id, int32_t length);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t basic_type_id = env->get_basic_type_id(env, "SPVM::Int");
void* object_array_obj = env->new_object_array(env, basic_type_id, 100);
</pre>
<h3 id="native-api-native-sub-api-new_muldim_array_raw">new_muldim_array_raw</h3>
<p>
基本型IDと要素の型の次元と配列の長さを指定して新しい多次元のオブジェクト型の配列を生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでなければなりません。すべての要素の初期値はNULLです。
</p>
<pre>
void* (*new_muldim_array_raw)(SPVM_ENV* env, int32_t basic_type_id, int32_t element_dimension, int32_t length);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_muldim_arrayを使用してください。
</p>
<h3 id="native-api-native-sub-api-new_muldim_array">new_muldim_array</h3>
<p>
基本型IDと要素の型の次元と配列の長さを指定して新しい多次元のオブジェクト型の配列を生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでなければなりません。すべての要素の初期値はNULLです。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*new_muldim_array_raw)(SPVM_ENV* env, int32_t basic_type_id, int32_t element_dimension, int32_t length);
</pre>
<p>
要素の型の次元は、255より小さくなければなりません。
</p>
<p>
サンプル:
</p>
<pre>
// new SPVM::Int[][][100]
int32_t basic_type_id = env->get_basic_type_id(env, "SPVM::Int");
void* multi_array_obj = env->new_muldim_array(env, basic_type_id, 2, 100);
</pre>
<h3 id="native-api-native-sub-api-new_mulnum_array_raw">new_mulnum_array_raw</h3>
<p>
基本型IDと配列の長さを指定して新しい複数数値型の配列を生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでかつ、複合数値型として有効でなければなりません。すべての要素のすべてのフィールどの初期値は0です。
</p>
<pre>
void* (*new_mulnum_array_raw)(SPVM_ENV* env, int32_t basic_type_id, int32_t length);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_mulnum_arrayを使用してください。
</p>
<h3 id="native-api-native-sub-api-new_mulnum_array">new_mulnum_array</h3>
<p>
基本型IDと配列の長さを指定して新しい複数数値型の配列を生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでかつ、複合数値型として有効でなければなりません。すべての要素のすべてのフィールどの初期値は0です。
</p>
<pre>
void* (*new_mulnum_array)(SPVM_ENV* env, int32_t basic_type_id, int32_t length);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t basic_type_id = env->get_basic_type_id(env, "SPVM::Complex_2d");
void* value_array_obj = env->new_mulnum_array(env, basic_type_id, 100);
</pre>
<h3 id="native-api-native-sub-api-new_string_raw">new_string_raw</h3>
<p>
C言語の文字列を指定して、文字列型のオブジェクトを生成し、返却します。文字列は「\0」で終端していなければなりません。
</p>
<pre>
void* (*new_string_raw)(SPVM_ENV* env, const char* bytes);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_stringを使用してください。
</p>
<h3 id="native-api-native-sub-api-new_string">new_string</h3>
<p>
C言語の文字列を指定して、文字列型のオブジェクトを生成し、返却します。文字列は「\0」で終端していなければなりません。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*new_string)(SPVM_ENV* env, const char* bytes);
</pre>
<p>
サンプル:
</p>
<pre>
void* str_obj = env->new_string(env, "Hello World");
</pre>
<h3 id="native-api-native-sub-api-new_string_len_raw">new_string_len_raw</h3>
<p>
C言語の文字列と長さを指定して、文字列型のオブジェクトを生成し、返却します。
</p>
<pre>
void* (*new_string_len_raw)(SPVM_ENV* env, const char* bytes, int32_t length);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_string_lenを使用してください。
</p>
<h3 id="native-api-native-sub-api-new_string_len">new_string_len</h3>
<p>
C言語の文字列と長さを指定して、文字列型のオブジェクトを生成し、返却します。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*new_string_len)(SPVM_ENV* env, const char* bytes, int32_t length);
</pre>
<p>
サンプル:
</p>
<pre>
void* str_obj = env->new_string_len(env, "Hello\0World", 11);
</pre>
<h3 id="native-api-native-sub-api-new_pointer_raw">new_pointer_raw</h3>
<p>
基本型IDとC言語のポインタを指定して、ポインタ型のオブジェクトを生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでかつ、ポインタ型として有効でなければなりません。
</p>
<pre>
void* (*new_pointer_raw)(SPVM_ENV* env, int32_t basic_type_id, void* pointer);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_pointerを使用してください。
</p>
<h3 id="native-api-native-sub-api-new_pointer">new_pointer</h3>
<p>
基本型IDとC言語のポインタを指定して、ポインタ型のオブジェクトを生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでかつ、ポインタ型として有効でなければなりません。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*new_pointer)(SPVM_ENV* env, int32_t basic_type_id, void* pointer);
</pre>
<p>
サンプル:
</p>
<pre>
void* pointer = malloc(sizeof(struct tm));
void* pointer_obj = env->new_pointer(env, "MyTimeInfo", pointer);
</pre>
<p>
詳しいサンプルについては<a href="#native-api-use-pointer-type">ポインタ型の利用</a>を見てください。
</p>
<h3 id="native-api-native-sub-api-concat_raw">concat_raw</h3>
<p>
ふたつのbyte[]型の文字列を結合した新しいbyte[]型のオブジェクトを返却します。
</p>
<pre>
void* (*concat_raw)(SPVM_ENV* env, void* string1, void* string2);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、concatを使用してください。
</p>
<h3 id="native-api-native-sub-api-concat">concat</h3>
<p>
ふたつのbyte[]型の文字列を結合した新しいbyte[]型のオブジェクトを返却します。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*concat)(SPVM_ENV* env, void* string1, void* string2);
</pre>
<h3 id="native-api-native-sub-api-new_stack_trace_raw">new_stack_trace_raw</h3>
<p>
byte[]型の例外メッセージと、パッケージ名、サブルーチン名、ファイル名と行番号を指定すると、byte[]型の例外メッセージの末尾に、パッケージ名、サブルーチン名、ファイル名と行番号の文字列を追加した文字列を返却します。
</p>
<pre>
void* (*new_stack_trace_raw)(SPVM_ENV* env, void* exception, const char* package_name, const char* sub_name, const char* file, int32_t line);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_stack_traceを使用してください。
</p>
<h3 id="native-api-native-sub-api-new_stack_trace">new_stack_trace</h3>
<p>
byte[]型の例外メッセージと、パッケージ名、サブルーチン名、ファイル名と行番号を指定すると、string型の例外メッセージの末尾に、パッケージ名、サブルーチン名、ファイル名と行番号の文字列を追加した新しいstring型のオブジェクトを返却します。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*new_stack_trace)(SPVM_ENV* env, void* exception, const char* package_name, const char* sub_name, const char* file, int32_t line);
</pre>
<h3 id="native-api-native-sub-api-len">len</h3>
<p>
配列を指定すると、配列の長さを返却します。
</p>
<pre>
int32_t (*len)(SPVM_ENV*, void* array);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t length = env->length(env, array);
</pre>
<h3 id="native-api-native-sub-api-get_elems_byte">get_elems_byte</h3>
<p>
byte[]型の配列を指定すると、内部的に保有しているC言語のint8_t[]型の配列の先頭のポインタを返却します。
</p>
<pre>
int8_t* (*get_elems_byte)(SPVM_ENV* env, void* array);
</pre>
<p>
サンプル:
</p>
<pre>
int8_t* values = env->get_elems_byte(env, array);
values[3] = 5;
</pre>
<h3 id="native-api-native-sub-api-get_elems_short">get_elems_short</h3>
<p>
short[]型の配列を指定すると、内部的に保有しているC言語のint16_t[]型の配列の先頭のポインタを返却します。
</p>
<pre>
int16_t* (*get_elems_short)(SPVM_ENV* env, void* array);
</pre>
<p>
サンプル:
</p>
<pre>
int16_t* values = env->get_elems_short(env, array);
values[3] = 5;
</pre>
<h3 id="native-api-native-sub-api-get_elems_int">get_elems_int</h3>
<p>
int[]型の配列を指定すると、内部的に保有しているC言語のint32_t[]型の配列の先頭のポインタを返却します。
</p>
<pre>
int32_t* (*get_elems_int)(SPVM_ENV* env, void* array);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t* values = env->get_elems_int(env, array);
values[3] = 5;
</pre>
<h3 id="native-api-native-sub-api-get_elems_long">get_elems_long</h3>
<p>
long[]型の配列を指定すると、内部的に保有しているC言語のint64_t[]型の配列の先頭のポインタを返却します。
</p>
<pre>
int64_t* (*get_elems_long)(SPVM_ENV* env, void* array);
</pre>
<p>
サンプル:
</p>
<pre>
int64_t* values = env->get_elems_long(env, array);
values[3] = 5;
</pre>
<h3 id="native-api-native-sub-api-get_elems_float">get_elems_float</h3>
<p>
float[]型の配列を指定すると、内部的に保有しているC言語のfloat[]型の配列の先頭のポインタを返却します。
</p>
<pre>
float* (*get_elems_float)(SPVM_ENV* env, void* array);
</pre>
<p>
サンプル:
</p>
<pre>
float* values = env->get_elems_float(env, array);
values[3] = 1.5f;
</pre>
<h3 id="native-api-native-sub-api-get_elems_double">get_elems_double</h3>
<p>
double[]型の配列を指定すると、内部的に保有しているC言語のdouble[]型の配列の先頭のポインタを返却します。
</p>
<pre>
double* (*get_elems_double)(SPVM_ENV* env, void* array);
</pre>
<p>
サンプル:
</p>
<pre>
double* values = env->get_elems_double(env, array);
values[3] = 1.5;
</pre>
<h3 id="native-api-native-sub-api-get_elem_object">get_elem_object</h3>
<p>
オブジェクト型の配列と添え字を指定して、要素のオブジェクトを取得します。もし要素が弱参照になっていた場合は、弱参照が取り除かれます。
</p>
<pre>
void* (*get_elem_object)(SPVM_ENV* env, void* array, int32_t index);
</pre>
<p>
サンプル:
</p>
<pre>
void* object = env->get_elem_object(env, array, 3);
</pre>
<h3 id="native-api-native-sub-api-set_elem_object">set_elem_object</h3>
<p>
オブジェクト型の配列と添え字と要素のオブジェクトを指定すると、対応する添え字の位置に要素のオブジェクトが代入されます。要素のオブジェクトが弱参照になっていた場合は、弱参照が取り除かれます。もともと代入されていたオブジェクトのリファレンスカウントは、1減らされます。
</p>
<pre>
void (*set_elem_object)(SPVM_ENV* env, void* array, int32_t index, void* value);
</pre>
<p>
サンプル:
</p>
<pre>
env->get_elem_object(env, array, 3, object);
</pre>
<h3 id="native-api-native-sub-api-get_field_byte">get_field_byte</h3>
<p>
オブジェクトとフィールドIDを指定すると、byte型のフィールドの値をC言語のint8_t型の値として返却します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
int8_t (*get_field_byte)(SPVM_ENV* env, void* object, int32_t field_id);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "byte");
int8_t field_value = env->get_field_byte(env, object, field_id);
</pre>
<h3 id="native-api-native-sub-api-get_field_short">get_field_short</h3>
<p>
オブジェクトとフィールドIDを指定すると、short型のフィールドの値をC言語のint16_t型の値として返却します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
int16_t (*get_field_short)(SPVM_ENV* env, void* object, int32_t field_id);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "short");
int16_t field_value = env->get_field_short(env, object, field_id);
</pre>
<h3 id="native-api-native-sub-api-get_field_int">get_field_int</h3>
<p>
オブジェクトとフィールドIDを指定すると、int型のフィールドの値をC言語のint32_t型の値として返却します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
int32_t (*get_field_int)(SPVM_ENV* env, void* object, int32_t field_id);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "int");
int32_t field_value = env->get_field_int(env, object, field_id);
</pre>
<h3 id="native-api-native-sub-api-get_field_long">get_field_long</h3>
<p>
オブジェクトとフィールドIDを指定すると、long型のフィールドの値をC言語のint64_t型の値として返却します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
int64_t (*get_field_long)(SPVM_ENV* env, void* object, int32_t field_id);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "long");
int64_t field_value = env->get_field_long(env, object, field_id);
</pre>
<h3 id="native-api-native-sub-api-get_field_float">get_field_float</h3>
<p>
オブジェクトとフィールドIDを指定すると、float型のフィールドの値をC言語のfloat型の値として返却します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
float (*get_field_float)(SPVM_ENV* env, void* object, int32_t field_id);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "float");
float field_value = env->get_field_float(env, object, field_id);
</pre>
<h3 id="native-api-native-sub-api-get_field_double">get_field_double</h3>
<p>
オブジェクトとフィールドIDを指定すると、double型のフィールドの値をC言語のdouble型の値として返却します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
double (*get_field_double)(SPVM_ENV* env, void* object, int32_t field_id);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "double");
double field_value = env->get_field_double(env, object, field_id);
</pre>
<h3 id="native-api-native-sub-api-get_field_object">get_field_object</h3>
<p>
オブジェクトとフィールドIDを指定すると、オブジェクト型のフィールドの値をC言語のvoid*型の値として返却します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。フィールドが弱参照である場合は、取り除かれます。
</p>
<pre>
void* (*get_field_object)(SPVM_ENV* env, void* object, int32_t field_id);
</pre>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "SPVM::Int");
void* field_value = env->get_field_object(env, object, field_id);
</pre>
<h3 id="native-api-native-sub-api-set_field_byte">set_field_byte</h3>
<p>
オブジェクトとフィールドIDとフィールドの値を指定すると、byte型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
void (*set_field_byte)(SPVM_ENV* env, void* object, int32_t field_id, int8_t value);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "byte");
int8_t field_value = 5;
env->set_field_byte(env, object, field_id, field_value);
</pre>
<h3 id="native-api-native-sub-api-set_field_short">set_field_short</h3>
<p>
オブジェクトとフィールドIDとフィールドの値を指定すると、short型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
void (*set_field_short)(SPVM_ENV* env, void* object, int32_t field_id, int16_t value);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "short");
int16_t field_value = 5;
env->set_field_short(env, object, field_id, field_value);
</pre>
<h3 id="native-api-native-sub-api-set_field_int">set_field_int</h3>
<p>
オブジェクトとフィールドIDとフィールドの値を指定すると、int型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
void (*set_field_int)(SPVM_ENV* env, void* object, int32_t field_id, int32_t value);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "int");
int32_t field_value = 5;
env->set_field_int(env, object, field_id, field_value);
</pre>
<h3 id="native-api-native-sub-api-set_field_long">set_field_long</h3>
<p>
オブジェクトとフィールドIDとフィールドの値を指定すると、long型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
void (*set_field_long)(SPVM_ENV* env, void* object, int32_t field_id, int64_t value);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "long");
int64_t field_value = 5;
env->set_field_long(env, object, field_id, field_value);
</pre>
<h3 id="native-api-native-sub-api-set_field_float">set_field_float</h3>
<p>
オブジェクトとフィールドIDとフィールドの値を指定すると、float型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
void (*set_field_float)(SPVM_ENV* env, void* object, int32_t field_id, float value);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "float");
float field_value = 1.5f;
env->set_field_float(env, object, field_id, field_value);
</pre>
<h3 id="native-api-native-sub-api-set_field_double">set_field_double</h3>
<p>
オブジェクトとフィールドIDとフィールドの値を指定すると、double型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
void (*set_field_double)(SPVM_ENV* env, void* object, int32_t field_id, double value);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "double");
double field_value = 1.55;
env->set_field_double(env, object, field_id, field_value);
</pre>
<h3 id="native-api-native-sub-api-set_field_object">set_field_object</h3>
<p>
オブジェクトとフィールドIDとフィールドの値を指定すると、オブジェクト型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。設定後の値は、リファレンスカウントが1増やされます。元の値は、リファレンスカウントが1減らされます。
</p>
<pre>
void (*set_field_object)(SPVM_ENV* env, void* object, int32_t field_id, void* value);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t field_id = env->get_field_id(env, "Foo", "x", "SPVM::Int");
int32_t basic_type_id = env->get_basic_type_id(env, "SPVM::Int");
void* object = env->new_object(env, basic_type_id);
env->set_field_object(env, object, field_id, object);
</pre>
<h3 id="native-api-native-sub-api-get_package_var_byte">get_package_var_byte</h3>
<p>
オブジェクトとパッケージ変数IDを指定すると、byte型のパッケージ変数の値をC言語のint8_t型の値として返却します。パッケージ変数IDはfield_id関数で取得した有効なパッケージ変数IDである必要があります。
</p>
<pre>
int8_t (*get_package_var_byte)(SPVM_ENV* env, int32_t pkgvar_id);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "byte");
int8_t pkgvar_value = env->get_package_var_byte(env, object, pkgvar_id);
</pre>
<h3 id="native-api-native-sub-api-get_package_var_short">get_package_var_short</h3>
<p>
オブジェクトとパッケージ変数IDを指定すると、short型のパッケージ変数の値をC言語のint16_t型の値として返却します。パッケージ変数IDはfield_id関数で取得した有効なパッケージ変数IDである必要があります。
</p>
<pre>
int16_t (*get_package_var_short)(SPVM_ENV* env, int32_t pkgvar_id);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "short");
int16_t pkgvar_value = env->get_package_var_short(env, object, pkgvar_id);
</pre>
<h3 id="native-api-native-sub-api-get_package_var_int">get_package_var_int</h3>
<p>
オブジェクトとパッケージ変数IDを指定すると、int型のパッケージ変数の値をC言語のint32_t型の値として返却します。パッケージ変数IDはfield_id関数で取得した有効なパッケージ変数IDである必要があります。
</p>
<pre>
int32_t (*get_package_var_int)(SPVM_ENV* env, int32_t pkgvar_id);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "int");
int32_t pkgvar_value = env->get_package_var_int(env, object, pkgvar_id);
</pre>
<h3 id="native-api-native-sub-api-get_package_var_long">get_package_var_long</h3>
<p>
オブジェクトとパッケージ変数IDを指定すると、long型のパッケージ変数の値をC言語のint64_t型の値として返却します。パッケージ変数IDはfield_id関数で取得した有効なパッケージ変数IDである必要があります。
</p>
<pre>
int64_t (*get_package_var_long)(SPVM_ENV* env, int32_t pkgvar_id);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "long");
int64_t pkgvar_value = env->get_package_var_long(env, object, pkgvar_id);
</pre>
<h3 id="native-api-native-sub-api-get_package_var_float">get_package_var_float</h3>
<p>
オブジェクトとパッケージ変数IDを指定すると、float型のパッケージ変数の値をC言語のfloat型の値として返却します。パッケージ変数IDはfield_id関数で取得した有効なパッケージ変数IDである必要があります。
</p>
<pre>
float (*get_package_var_float)(SPVM_ENV* env, int32_t pkgvar_id);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "float");
float pkgvar_value = env->get_package_var_float(env, object, pkgvar_id);
</pre>
<h3 id="native-api-native-sub-api-get_package_var_double">get_package_var_double</h3>
<p>
オブジェクトとパッケージ変数IDを指定すると、double型のパッケージ変数の値をC言語のdouble型の値として返却します。パッケージ変数IDはfield_id関数で取得した有効なパッケージ変数IDである必要があります。
</p>
<pre>
double (*get_package_var_double)(SPVM_ENV* env, int32_t pkgvar_id);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "double");
double pkgvar_value = env->get_package_var_double(env, object, pkgvar_id);
</pre>
<h3 id="native-api-native-sub-api-get_package_var_object">get_package_var_object</h3>
<p>
オブジェクトとパッケージ変数IDを指定すると、オブジェクト型のパッケージ変数の値をC言語のvoid*型の値として返却します。パッケージ変数IDはfield_id関数で取得した有効なパッケージ変数IDである必要があります。
</p>
<pre>
void* (*get_package_var_object)(SPVM_ENV* env, int32_t pkgvar_id);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "SPVM::Int");
void* pkgvar_value = env->get_package_var_byte(env, object, pkgvar_id);
</pre>
<h3 id="native-api-native-sub-api-set_package_var_byte">set_package_var_byte</h3>
<p>
オブジェクトとフィールドIDとフィールドの値を指定すると、byte型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
void (*set_package_var_byte)(SPVM_ENV* env, int32_t pkgvar_id, int8_t value);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "byte");
int8_t pkgvar_value = 5;
env->set_package_var_byte(env, pkgvar_id, pkgvar_value);
</pre>
<h3 id="native-api-native-sub-api-set_package_var_short">set_package_var_short</h3>
<p>
オブジェクトとフィールドIDとフィールドの値を指定すると、short型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
void (*set_package_var_short)(SPVM_ENV* env, int32_t pkgvar_id, int16_t value);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "short");
int16_t pkgvar_value = 5;
env->set_package_var_short(env, pkgvar_id, pkgvar_value);
</pre>
<h3 id="native-api-native-sub-api-set_package_var_int">set_package_var_int</h3>
<p>
オブジェクトとフィールドIDとフィールドの値を指定すると、int型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
void (*set_package_var_int)(SPVM_ENV* env, int32_t pkgvar_id, int32_t value);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "int");
int32_t pkgvar_value = 5;
env->set_package_var_int(env, pkgvar_id, pkgvar_value);
</pre>
<h3 id="native-api-native-sub-api-set_package_var_long">set_package_var_long</h3>
<p>
オブジェクトとフィールドIDとフィールドの値を指定すると、long型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
void (*set_package_var_long)(SPVM_ENV* env, int32_t pkgvar_id, int64_t value);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "long");
int64_t pkgvar_value = 5;
env->set_package_var_long(env, pkgvar_id, pkgvar_value);
</pre>
<h3 id="native-api-native-sub-api-set_package_var_float">set_package_var_float</h3>
<p>
オブジェクトとフィールドIDとフィールドの値を指定すると、float型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
void (*set_package_var_float)(SPVM_ENV* env, int32_t pkgvar_id, float value);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "float");
float pkgvar_value = 5;
env->set_package_var_float(env, pkgvar_id, pkgvar_value);
</pre>
<h3 id="native-api-native-sub-api-set_package_var_double">set_package_var_double</h3>
<p>
オブジェクトとフィールドIDとフィールドの値を指定すると、double型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。
</p>
<pre>
void (*set_package_var_double)(SPVM_ENV* env, int32_t pkgvar_id, double value);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "double");
double pkgvar_value = 5;
env->set_package_var_double(env, pkgvar_id, pkgvar_value);
</pre>
<h3 id="native-api-native-sub-api-set_package_var_object">set_package_var_object</h3>
<p>
オブジェクトとフィールドIDとフィールドの値を指定すると、オブジェクト型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。設定後の値は、リファレンスカウントが1増やされます。元の値は、リファレンスカウントが1減らされます。
</p>
<pre>
void (*set_package_var_object)(SPVM_ENV* env, int32_t pkgvar_id, void* value);
</pre>
<p>
サンプル:
</p>
<pre>
int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "SPVM::Int");
int32_t basic_type_id = env->get_basic_type_id(env, "SPVM::Int");
void* object = env->new_object(env, basic_type_id);
env->set_package_var_object(env, pkgvar_id, pkgvar_value);
</pre>
<h3 id="native-api-native-sub-api-get_pointer">get_pointer</h3>
<p>
ポインタ型のオブジェクトを指定して、オブジェクトの内部に保存されているC言語のポインタを返却します。
</p>
<pre>
void* (*get_pointer)(SPVM_ENV* env, void* pointer_object);
</pre>
<p>
サンプル:
</p>
<pre>
strcut tm* tm_ptr = (struct tm*)env->get_pointer(env, tm_obj);
</pre>
<p>
詳しいサンプルについては<a href="#native-api-use-pointer-type">ポインタ型の利用</a>を見てください。
</p>
<h3 id="native-api-native-sub-api-set_pointer">set_pointer</h3>
<p>
ポインタ型のオブジェクトと、C言語のポインタを指定すると、ポインタ型のオブジェクトの内部データに、C言語のポインタが保存されます。
</p>
<pre>
void (*set_pointer)(SPVM_ENV* env, void* pointer_object, void* pointer);
</pre>
<h3 id="native-api-native-sub-api-call_sub">call_sub</h3>
<p>
サブルーチンIDと引数を指定して、サブルーチンを呼び出します。戻り値は、サブルーチンで例外が発生した場合は0以外を、例外が発生しなかった場合は0を返却します。
</p>
<pre>
int32_t (*call_sub)(SPVM_ENV* env, int32_t sub_id, SPVM_VALUE* args);
</pre>
<p>
サブルーチンの戻り値は「args[0]」に、設定されます。
</p>
<h3 id="native-api-native-sub-api-get_exception">get_exception</h3>
<p>
例外として保存されているbyte[]型のオブジェクトを返却します。
</p>
<pre>
void* (*get_exception)(SPVM_ENV* env);
</pre>
<h3 id="native-api-native-sub-api-set_exception">set_exception</h3>
<p>
byte[]型のオブジェクトを指定すると、例外として保存します。
</p>
<pre>
void (*set_exception)(SPVM_ENV* env, void* exception);
</pre>
<h3 id="native-api-native-sub-api-get_ref_count">get_ref_count</h3>
<p>
オブジェクトを指定すると、オブジェクトのリファレンスカウントを返却します。
</p>
<pre>
int32_t (*get_ref_count)(SPVM_ENV* env, void* object);
</pre>
<h3 id="native-api-native-sub-api-inc_ref_count">inc_ref_count</h3>
<p>
オブジェクトを指定すると、オブジェクトのリファレンスカウントを1増やします。
</p>
<pre>
void (*inc_ref_count)(SPVM_ENV* env, void* object);
</pre>
<p>
このメソッドは、使うべき、特別な理由がある場合のみ使用してください。通常は、リファレンスカウントは、自動的に管理されています。
</p>
<h3 id="native-api-native-sub-api-dec_ref_count">dec_ref_count</h3>
<p>
オブジェクトを指定すると、オブジェクトのリファレンスカウントを1減らします。リファレンスカウントが0になった場合、オブジェクトを解放します。
</p>
<pre>
void (*dec_ref_count)(SPVM_ENV* env, void* object);
</pre>
<p>
このメソッドは、使うべき、特別な理由がある場合のみ使用してください。通常は、リファレンスカウントは、自動的に管理されています。
</p>
<h3 id="native-api-native-sub-api-enter_scope">enter_scope</h3>
<p>
新しいスコープを作成し、スコープIDを返却します。
</p>
<pre>
int32_t (*enter_scope)(SPVM_ENV* env);
</pre>
<h3 id="native-api-native-sub-api-push_mortal">push_mortal</h3>
<p>
モータルスタックに、オブジェクトを追加します。
</p>
<pre>
void (*push_mortal)(SPVM_ENV* env, void* object);
</pre>
<h3 id="native-api-native-sub-api-leave_scope">leave_scope</h3>
<p>
スコープIDを指定して、そのスコープを終了し、モータルスタックに格納されている、オブジェクトのリファレンスカウントを1減らします。リファレンスカウントが0になったオブジェクトは解放されます。スコープIDは、enter_scope関数で取得したIDでなければなりません。
</p>
<pre>
void (*leave_scope)(SPVM_ENV* env, int32_t scope_id);
</pre>
<h3 id="native-api-native-sub-api-remove_mortal">remove_mortal</h3>
<p>
スコープIDと、オブジェクトを指定すると、指定されたオブジェクトをモータルスタックから削除します。
</p>
<pre>
int32_t (*remove_mortal)(SPVM_ENV* env, int32_t scope_id, void* remove_object);
</pre>
<h3 id="native-api-native-sub-api-is_type">is_type</h3>
<p>
オブジェクトと基本型IDと型の次元を指定すると、オブジェクトが、基本型IDと型の次元の両方に一致した場合、0以外の値を、そうでない場合は、0を返します。
</p>
<pre>
int32_t (*is_type)(SPVM_ENV* env, void* object, int32_t basic_type_id, int32_t type_dimension);
</pre>
<h3 id="native-api-native-sub-api-has_callback">has_callback</h3>
<p>
オブジェクトとコールバック型の基本型IDを指定すると、オブジェクトが、コールバック型に適合した場合は0以外の値を、そうでない場合は、0を返します。
</p>
<pre>
int32_t (*has_callback)(SPVM_ENV* env, void* object, int32_t callback_basic_type_id);
</pre>
<h3 id="native-api-native-sub-api-get_object_basic_type_id">get_object_basic_type_id</h3>
<p>
オブジェクトの基本型IDを取得します。
</p>
<pre>
int32_t (*get_object_basic_type_id)(SPVM_ENV* env, void* object);
</pre>
<h3 id="native-api-native-sub-api-object_type_dimension">get_object_type_dimension</h3>
<p>
オブジェクトの型の次元を取得します。
</p>
<pre>
int32_t (*get_object_type_dimension)(SPVM_ENV* env, void* object);
</pre>
<h3 id="native-api-native-sub-api-weaken">weaken</h3>
<p>
オブジェクトのアドレスを指定すると、オブジェクトを弱参照にします。
</p>
<pre>
void (*weaken)(SPVM_ENV* env, void** object_address);
</pre>
<h3 id="native-api-native-sub-api-isweak">isweak</h3>
<p>
オブジェクトのアドレスを指定すると、オブジェクトが弱参照の場合は、0以外の値を、そうでない場合は、0を返します。
</p>
<pre>
int32_t (*isweak)(SPVM_ENV* env, void** object);
</pre>
<h3 id="native-api-native-sub-api-unweaken">unweaken</h3>
<p>
オブジェクトのアドレスを指定すると、オブジェクトの弱参照を解除します。
</p>
<pre>
void (*unweaken)(SPVM_ENV* env, void** object_address);
</pre>
<h3 id="native-api-native-sub-api-alloc_memory_block_zero">alloc_memory_block_zero</h3>
<p>
サイズをバイトで指定すると、メモリブロックを割り当て、割り当てられたメモリブロックのポインタを返却します。メモリブロックのビットはすべて0で初期化されます。メモリブロックカウントが1増加します。
</p>
<pre>
void* (*alloc_memory_block_zero)(SPVM_ENV* env, int64_t byte_size);
</pre>
<h3 id="native-api-native-sub-api-free_memory_block">free_memory_block</h3>
<p>
メモリブロックを指定すると、解放します。メモリブロックカウントが1減少します。
</p>
<pre>
void (*free_memory_block)(SPVM_ENV* env, void* block);
</pre>
<h3 id="native-api-native-sub-api-get_memory_blocks_count">get_memory_blocks_count</h3>
<p>
現在のメモリブロックの数を返却します。
</p>
<pre>
int32_t (*get_memory_blocks_count)(SPVM_ENV* env);
</pre>
<p>
メモリブロックは、オブジェクトを生成した場合、alloc_memory_block_zero関数を呼び出した場合、weaken関数でバックリファレンスが追加された場合に、1増加します。
</p>
<h3 id="native-api-native-sub-api-get_type_name_raw">get_type_name_raw</h3>
<p>
オブジェクトを指定すると、型名を保存した新しいbyte[]型のオブジェクトを返却します。
</p>
<pre>
void* (*get_type_name_raw)(SPVM_ENV* env, void* object);
</pre>
<p>
この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、type_nameを使用してください。
</p>
<h3 id="native-api-native-sub-api-get_type_name">get_type_name</h3>
<p>
オブジェクトを指定すると、型名を保存した新しいbyte[]型のオブジェクトを返却します。モータルスタックに新しく生成されたオブジェクトを追加します。
</p>
<pre>
void* (*get_type_name)(SPVM_ENV* env, void* object);
</pre>
<h3 id="native-api-native-sub-api-new_env">new_env</h3>
<p>
現在の実行環境を元にした、新しい実行環境を作成します。
</p>
<pre>
SPVM_ENV* (*new_env)(SPVM_ENV* env);
</pre>
<p>
この関数は、新しいスレッドにおいて、新しい実行環境を生成したい場合に、利用してください。
</p>
<p>
例外オブジェクト、モータルスタックの情報は、初期化されます。
</p>
<p>
パッケージ変数は、元の実行環境と共有します。
</p>
<p>
メモリブロックの数は、元の実行環境と共有します。
</p>
<h3 id="native-api-native-sub-api-free_env">free_env</h3>
<p>
実行環境を開放します。
</p>
<pre>
void (*free_env)(SPVM_ENV* env);
</pre>
</div>
<div class="footer">
<div><a href="javascript:void(0)" class="to-top">▲</a></div>
<a href="https://github.com/yuki-kimoto/SPVM">SPVMプロジェクト</a>
</div>
</body>
</html>