SPVMネイティブAPI仕様 1.0

# SPVMドキュメント 1.0 ベータ

SPVMドキュメント > SPVMネイティブAPI仕様

## SPVMネイティブAPI仕様

SPVMネイティブAPI仕様がこのドキュメントには記述されています。SPVMは、1.0のリリースに向けて、ベータテスト中です。SPVMネイティブAPI仕様は、警告なく変更されることがあります。

最終更新日 2019年7月16日

## 目次

## SPVMネイティブAPIとは

SPVMネイティブAPIとは、SPVMのネイティブサブルーチンの中で呼び出すことのできるC言語のAPIのことです。SPVMのネイティブサブルーチンの仕様についてもここに記述されます。

- ネイティブサブルーチンの定義方法
- SPVMのサブルーチンの引数をネイティブサブルーチンで受け取る
- ネイティブサブルーチンの戻り値を、SPVMのサブルーチンの戻り値として返す
- SPVMの配列の要素をC言語の配列として取得

作成したネイティブサブルーチンは、SPVMから呼び出すことができます。

## SPVMネイティブサブルーチンの宣言

SPVMネイティブサブルーチンの宣言は、サブルーチンのディスクリプタ「native」を使うことによって行います。サブルーチンのブロックを書かずに、セミコロンで終わります。以下は、Foo::Barというモジュールの中で宣言する場合の例です。

    # Foo/Bar.spvm
    package Foo::Bar {
      native sub sum : int ($num1 : int, $num2 : int);
    }

## ネイティブサブルーチンの定義

ネイティブサブルーチンの定義は、ネイティブソースファイルの中で行います。ネイティブソースファイルは、SPVMのモジュールの拡張子を、対象の言語の拡張子に変えたものになります。たとえばC言語であれば「.c」に変えたものです。C++であれば、「.cpp」に変えたものです。これは、ネイティブサブルーチンの設定において、変更することができます。

    # モジュール名がFoo::Barの場合のネイティブソースファイル
    Foo/Bar.c

ネイティブソースファイルを作成するときは、合わせてネイティブ設定ファイルを作成する必要があります。ネイティブ設定ファイルは、SPVMのモジュールの拡張子を「.config」に変えたものになります。ネイティブ設定ファイルが存在しない場合は、例外が発生します。

    # モジュール名がFoo::Barの場合のネイティブ設定ファイル
    Foo/Bar.config

ネイティブ設定ファイルはPerlのソースコードです。SPVM::Builder::Configオブジェクトをソースコードの最後に記述して、返却しなければなりません。そうでない場合は、例外が発生します。

SPVMと同じC99で、C言語を書きたい場合は、以下のように記述します。

    use strict;
    use warnings;

    use SPVM::Builder::Config;
    my $bconf = SPVM::Builder::Config->new_c99;

    $bconf;

C99以外でコンパイルしたい場合や、ライブラリを追加したい場合はSPVM::Builder::Configのドキュメントのサンプルを見てください。

ネイティブサブルーチンの定義は、ネイティブソースファイルの中で行います。この場合の例は「Foo/Bar.c」です。

    #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;
    }

ネイティブソースファイルの先頭で「spvm_native.h」をインクルードしてください。このヘッダファイルには、SPVMネイティブAPIと必要な構造体が定義されています。

ネイティブサブルーチンの定義は、簡単なC言語の関数です。

ネイティブサブルーチンのCにおける関数名は「SPNATIVE__」で始まり、モジュール名の「::」を「__」に変換したものが続き、「__」が続き、サブルーチン名で終わります。SPVMにおけるサブルーチン名との対応が正しくない場合は、コンパイルエラーが発生します。

引数は二つで、第一引数は、実行環境の情報を持った「SPVM_ENV* env」で、第二引数は引数と戻り値に利用される「SPVM_VALUE* stack」です。

戻り値の型は「int32_t」です。サブルーチンが例外を発生させる場合は「SPVM_EXCEPTION」、それ以外の場合は「SPVM_SUCCESS」を返却します。

上記のサンプルでは、SPVMのint型の引数を二つ受け取り、合計を計算し、戻り値を返すということを行っています。

## ネイティブサブルーチンのコンパイル

ネイティブサブルーチンは、Perlをコンパイルしたコンパイラで、コンパイルされて、OSに応じた、動的に読み可能な共有ライブラリにコンパイルされます。Unix/Linuxにおいては、共有ライブラリ(.so)、Windowsにおいてはダイナミックリンクライブラリ(.dll)などです。

動的に読み可能な共有ライブラリへのコンパイルは、SPVMのコンパイル時に行われます。コンパイルのときに、ビルドディレクトリが存在していなければなりません。ビルドディレクトリが存在しない場合は、例外が発生します。

ビルドディレクトリのデフォルトは、実行したPerlスクリプトが存在するディレクトリの「spvm_build」ディレクトリで、環境変数「SPVM_BUILD_DIR」で変更することができます。

PerlからSPVMネイティブサブルーチンを利用したい場合は実行したPerlスクリプトが存在するディレクトリに「spvm_build」ディレクトリ作成します。

    script.pl
    spvm_build/

中間的に生成されるオブジェクトファイルは、ビルドディレクトリの下の「work/object」の下に生成されます。オブジェクトファイル名は、SPVMのモジュールの拡張子を「.o」に変えたものになります。

    spvm_build/work/object/Foo/Bar.o

動的に読み可能な共有ライブラリは、ビルドディレクトリの下の「work/lib」の下に生成されます。動的に読み可能な共有ライブラリのファイル名は、SPVMのモジュールの拡張子を、OSに応じた、動的に読み可能な共有ライブラリの拡張子に変えたものになります。

    # Unix/Linux
    spvm_build/work/object/Foo/Bar.so

    # Windows
    spvm_build/work/object/Foo/Bar.dll

## 引数の取得

- 引数とスタック
- byte型の引数の取得
- short型の引数の取得
- int型の引数の取得
- long型の引数の取得
- float型の引数の取得
- double型の引数の取得
- オブジェクト型の引数の取得
- 引数のスタック
- byteのリファレンス型の引数の取得
- shortのリファレンス型の引数の取得
- intのリファレンス型の引数の取得
- longのリファレンス型の引数の取得
- floatのリファレンス型の引数の取得
- doubleのリファレンス型の引数の取得
- 複数数値型の引数の取得

### 引数とスタック

スタックとは、ネイティブサブルーチンの定義における第二引数で渡される「SPVM_VALUE* stack」のことで、この中に引数が格納されています。

    int32_t SPNATIVE__Foo__Bar__sum(SPVM_ENV* env, SPVM_VALUE* stack) {

    }

SPVM_VALUEは、SPVMの値を格納するためのC言語の共用体です。数値型、オブジェクト型、リファレンス型の値を保存できます。

「SPVM_VALUE* stack」の「SPVM_VALUE型の配列」の先頭のポインタです。SPVM側からコールされたネイティブサブルーチンの引数の値がこの配列に設定されます。

たとえば、int型の第一引数の値を取得する場合は、以下のように書きます。

    int32_t args1 = stack[0].ival;

たとえば、long型の第二引数の値を取得する場合は、以下のように書きます。

    int64_t args2 = stack[0].lval;

### byte型の引数の取得

SPVMのbyte型の引数を取得するには、bvalフィールドにアクセスします。C言語のint8_t型に代入します。

    int8_t args1 = stack[0].bval;

### short型の引数の取得

SPVMのshort型の引数を取得するには、svalフィールドにアクセスします。C言語のint16_t型に代入します。

    int16_t args1 = stack[0].sval;

### int型の引数の取得

SPVMのint型の引数を取得するには、ivalフィールドにアクセスします。C言語のint32_t型に代入します。

    int32_t args1 = stack[0].ival;

### long型の引数の取得

SPVMのlong型の引数を取得するには、lvalフィールドにアクセスします。C言語のint64_t型に代入します。

    int64_t args1 = stack[0].lval;

### float型の引数の取得

SPVMのfloat型の引数を取得するには、fvalフィールドにアクセスします。C言語のfloat型に代入します。

    float args1 = stack[0].fval;

### double型の引数の取得

SPVMのdouble型の引数を取得するには、dvalフィールドにアクセスします。C言語のdouble型に代入します。

    double args1 = stack[0].dval;

### オブジェクト型の引数の取得

SPVMのobject型の引数を取得するには、ovalフィールドにアクセスします。C言語のvoid*型に代入します。

    void* args1 = stack[0].oval;

### byteのリファレンス型の引数の取得

SPVMのbyteのリファレンス型の引数を取得するには、brefフィールドにアクセスします。C言語のint8_t*型に代入します。

    int8_t* args1 = stack[0].bref;

### shortのリファレンス型の引数の取得

SPVMのshortのリファレンス型の引数を取得するには、srefフィールドにアクセスします。C言語のint16_t*型に代入します。

    int16_t* args1 = stack[0].sref;

### intのリファレンス型の引数の取得

SPVMのintのリファレンス型の引数を取得するには、irefフィールドにアクセスします。C言語のint32_t*型に代入します。

    int32_t* args1 = stack[0].iref;

### longのリファレンス型の引数の取得

SPVMのlongのリファレンス型の引数を取得するには、lrefフィールドにアクセスします。C言語のint64_t*型に代入します。

    int64_t* args1 = stack[0].lref;

### floatのリファレンス型の引数の取得

SPVMのfloatのリファレンス型の引数を取得するには、frefフィールドにアクセスします。C言語のfloat*型に代入します。

    float* args1 = stack[0].fref;

### doubleのリファレンス型の引数の取得

SPVMのdoubleのリファレンス型の引数を取得するには、drefフィールドにアクセスします。C言語のdouble*型に代入します。

    double* args1 = stack[0].dref;

### 複数数値型の引数の取得

ネイティブサブルーチンにおいては、複数数値型の引数は、複数の引数に代入されます。

たとえば、SPVM::Complex_2d型の引数の場合は、二つの引数から取得します。フィールド名からはアクセスできないことに注意してください。

    double args_re = stack[0].dval;
    double args_im = stack[1].dval;

## 戻り値の設定

- 戻り値とスタック
- byte型の戻り値の設定
- short型の戻り値の設定
- int型の戻り値の設定
- long型の戻り値の設定
- float型の戻り値の設定
- double型の戻り値の設定
- オブジェクト型の戻り値の設定
- 複数数値型の戻り値の設定

### 戻り値とスタック

ネイティブサブルーチンは、C言語のreturn文によって戻り値を返すのではなく、スタックを使って戻り値を設定します。

たとえば、int型の戻り値を返す場合は、以下のように書きます。

    stack[0].ival = 3;

たとえば、long型の第二引数の値を取得する場合は、以下のように書きます。

    stack[0].lval = 56;

### byte型の戻り値の設定

SPVMのbyte型の戻り値を設定するには、bvalフィールドに代入します。C言語のint8_t型の値を代入します。

    int8_t retval;
    stack[0].bval = retval;

### short型の戻り値の設定

SPVMのshort型の戻り値を設定するには、svalフィールドに代入します。C言語のint16_t型の値を代入します。

    int16_t retval;
    stack[0].sval = retval;

### int型の戻り値の設定

SPVMのint型の戻り値を設定するには、ivalフィールドに代入します。C言語のint32_t型の値を代入します。

    int32_t retval;
    stack[0].ival = retval;

### long型の戻り値の設定

SPVMのlong型の戻り値を設定するには、lvalフィールドに代入します。C言語のint64_t型の値を代入します。

    int64_t retval;
    stack[0].lval = retval;

### float型の戻り値の設定

SPVMのfloat型の戻り値を設定するには、fvalフィールドに代入します。C言語のfloat型の値を代入します。

    float retval;
    stack[0].fval = retval;

### double型の戻り値の設定

SPVMのdouble型の戻り値を設定するには、dvalフィールドに代入します。C言語のdouble型の値を代入します。

    double retval;
    stack[0].dval = retval;

### オブジェクト型の戻り値の設定

SPVMのobject型の戻り値を設定するには、ovalフィールドに代入します。C言語のvoid*型の値を代入します。

    void* retval;
    stack[0].oval = retval;

### 複数数値型の戻り値の設定

ネイティブサブルーチンにおいては、複数数値型の戻り値は、複数の戻り値に代入します。

たとえば、SPVM::Complex_2d型の戻り値の場合は、二つの戻り値を設定します。

    double retval_re;
    double retval_im;
    stack[0].dval = retval_re;
    stack[1].dval = retval_im;

## サブルーチンの呼び出し

SPVMのサブルーチンを呼び出すには、最初に、sub_id関数か、method_sub_id関数を使ってサブルーチンのIDを取得します

    // メソッドでないサブルーチンの場合
    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)");

sub_idが0より小さい場合は、サブルーチンが見つからなかったことを示します。以下のように、例外処理をしておくと安全です。

    if (sub_id < 0) {
      SPVM_DIE("Can't find sub id", "Foo/Bar.c", __LINE__);
    }

SPVMのサブルーチンの引数を、サブルーチン呼び出しを行う前に、stackに設定します。

      stack[0].ival = 1;
      stack[0].ival = 2;

SPVMのサブルーチンを呼び出すにはcall_sub関数を使用します。

    int32_t exception_flag = env->call_sub(env, sub_id, stack);

サブルーチンで例外が発生した場合は0以外、例外が発生しなかった場合は、0が返されます。

サブルーチンの戻り値は、スタックの最初の要素に保存されています。

    int32_t total = stack[0].ival;

## ネイティブサブルーチンのスコープ

ネイティブサブルーチンは、全体がスコープに囲まれています。

モータルスタックに追加されたオブジェクトは、ネイティブサブルーチンが終了すると、オブジェクトのリファレンスカウントが自動的に1減らされます。リファレンスカウントが0になった場合は、解放されます。

オブジェクトを、モータルスタックに追加するには、push_mortalを使用します。

    env->push_mortal(env, object);

通常は「new_object」などのオブジェクトを生成するネイティブAPIは、自動的に生成されたオブジェクトをモータルスタックに追加するので、これを使う必要はありません。

スコープを作成するには「enter_scope」を使用します。戻り値は、そのスコープのIDです。

    int32_t scope_id = env->enter_scope(env);

スコープを終了するには「leave_scope」を使用します。引数には、「enter_scope」で取得した、スコープIDを指定する必要があります。

    env->leave_scope(env, scope_id);

オブジェクトをモータルスタックから取り除くには「remove_mortal」を使用します。引数には「enter_scope」で取得したスコープIDと取り除きたいオブジェクトを指定します。オブジェクトはモータルスタックから取り除かれ、リファレンスカウントが自動的に1減らされます。リファレンスカウントが0になった場合は、解放されます。

    env->remove_mortal(env, scope_id, object);

モータルスタックに関する情報は、envに保存されているので、スレッドローカルなデータです。

## ネイティブサブルーチンにおける例外

ネイティブサブルーチンにおいて、例外が発生したかどうかを示すのは、戻り値です。

    return SPVM_SUCCESS;

    return SPVM_EXCEPTION;

例外が発生しなかった場合は「SPVM_SUCCESS」を返します。これは「0」として定義されています。

例外が発生した場合は「SPVM_EXCEPTION」を返します。これは「0」以外の値として定義されています。

例外メッセージを、自分で設定したい場合は「new_string」で例外メッセージを作成して「set_exception」で設定できます。

    env->set_exception(env, env->new_string(env, "Exception occur");\
    return SPVM_EXCEPTION;

例外メッセージが設定されなかった場合は、デフォルトの例外メッセージが設定されます。

通常の場合は、これを使いやすくした「SPVM_DIE」が定義されていますので、これを使うのがよいでしょう。

    SPVM_DIE("Error. Values must be %d and %d", 3, 5, "Foo/Bar.c", __LINE__);

SPVM_DIEは、C言語のsprintf関数と同じ使い方ができます。最後から二つ目には、このファイル名を、最後の引数には、行番号を必ず含めてください。メッセージが255バイトを超える場合は、超えた部分が切り捨てられます。

例外はenvに保存されているので、スレッドローカルなデータです。

## ポインタ型の利用

SPVMには、ポインタ型という型が存在しますが、利用方法について解説します。

ポインタ型の定義は、SPVMのパッケージ定義で、pointer_tデスクリプタを指定します。ポインタ型は、フィールド定義を持つことはできません。この例では、C標準の「struct tm」をポインタ型として利用する方法を解説します。

    # 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);
    }

newとうコンストラクタ、secという秒の情報をとるメソッド、DESTROYというデストラクタを定義しています。これらは、ネイティブサブルーチンです。

次にC言語側での定義です。

    # 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;
    }

コンストラクタnewでは、まず「struct tm」のメモリを、alloc_memory_block_zero関数で、割り当てます。これは、SPVMでメモリブロックを一つ確保する関数です。mallocでの同様のことがかのうですが、この関数は、メモリブロックのカウントを一つ増やすので、メモリリークの発見が容易になります。

      // Alloc strcut tm
      void* tm_ptr = env->alloc_memory_block_zero(sizeof(struct tm));

次に、new_pointer関数を使って、確保したメモリに、MyTimeInfoを関連付けた新しいポインタ型のオブジェクトを作成します。

      // Create strcut tm instance
      void* tm_obj = env->new_pointer(env, "MyTimeInfo", tm_ptr);

これを戻り値として返せば、コンストラクタの完成です。

      stack[0].ival = tm_ptr->tm_sec;

      return SPVM_SUCCESS;

次に、tm_secの値を取得してみましょう。secメソッドです。get_pointer関数を使うと、ポインタ型のオブジェクトから「struct tm」として割り当てられたメモリのポインタを取得することができます。

      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;

最後はデストラクタです。確保されたメモリは、自動的には解放されないので、必ずデストラクタを定義しましょう。

    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;
    }

free_memory_block関数を実行してメモリを開放します。alloc_memory_block_zeroで確保したメモリは、必ずfree_memory_block関数で解放しましょう。メモリを開放し、メモリブロック数のカウントを一つ減らします。

## ネイティブAPIのインデックス

ネイティブAPIは、名前に対応するインデックスを持っています。この番号は、ネイティブサブルーチンののバイナリ互換性を保つために、永続的に維持されます。新しいAPIの追加の場合は、末尾に追加されます。

    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

## ネイティブAPIの呼び出し

ネイティブAPIは、引数に渡された「SPVM_ENV* env」から呼び出すことができます。第一引数に、envを渡さなければならないことに注意してください。

    int32_t basic_type_id = env->get_basic_type_id(env, "SPVM::Int");

## ネイティブAPIの一覧

- runtime_package_vars_heap_offset
- object_header_byte_size
- weaken_backref_head
- object_ref_count_offset
- object_basic_type_id_offset
- object_type_dimension_offset
- object_runtime_type_category_offset
- object_flag_offset
- object_length_offset
- byte_object_basic_type_id
- short_object_basic_type_id
- int_object_basic_type_id
- long_object_basic_type_id
- float_object_basic_type_id
- double_object_basic_type_id
- runtime
- exception_object
- native_mortal_stack
- native_mortal_stack_top
- native_mortal_stack_capacity
- get_basic_type_id
- get_field_id
- get_field_offset
- get_package_var_id
- get_sub_id
- get_method_sub_id
- new_object_raw
- new_object
- new_byte_array_raw
- new_byte_array
- new_short_array_raw
- new_short_array
- new_int_array_raw
- new_int_array
- new_long_array_raw
- new_long_array
- new_float_array_raw
- new_float_array
- new_double_array_raw
- new_double_array
- new_object_array_raw
- new_object_array
- new_muldim_array_raw
- new_muldim_array
- new_mulnum_array_raw
- new_mulnum_array
- new_string_raw
- new_string
- new_string_len_raw
- new_string_len
- new_pointer_raw
- new_pointer
- concat_raw
- concat
- new_stack_trace_raw
- new_stack_trace
- length
- get_elems_byte
- get_elems_short
- get_elems_int
- get_elems_long
- get_elems_float
- get_elems_double
- get_elem_object
- set_elem_object
- get_field_byte
- get_field_short
- get_field_int
- get_field_long
- get_field_float
- get_field_double
- get_field_object
- set_field_byte
- set_field_short
- set_field_int
- set_field_long
- set_field_float
- set_field_double
- set_field_object
- get_package_var_byte
- get_package_var_short
- get_package_var_int
- get_package_var_long
- get_package_var_float
- get_package_var_double
- get_package_var_object
- set_package_var_byte
- set_package_var_short
- set_package_var_int
- set_package_var_long
- set_package_var_float
- set_package_var_double
- set_package_var_object
- get_pointer
- set_pointer
- call_sub
- get_exception
- set_exception
- get_ref_count
- inc_ref_count
- dec_ref_count
- enter_scope
- push_mortal
- leave_scope
- remove_mortal
- is_type
- has_callback
- get_object_basic_type_id
- get_object_type_dimension
- weaken
- isweak
- unweaken
- alloc_memory_block_zero
- free_memory_block
- get_memory_blocks_count
- get_type_name_raw
- get_type_name
- new_env
- free_env

### runtime_package_vars_heap_offset

ランタイム構造体におけるパッケージ変数の保存領域のポインタへのオフセット。内部的に利用されます。

### object_header_byte_size

オブジェクトのヘッダーのバイトサイズ。内部的に利用されます。

### object_weaken_backref_head_offset

オブジェクト構造体におけるウィークリファレンスのバックリファレンスへのポインタへのオフセット。内部的に利用されます。

### object_ref_count_offset

オブジェクト構造体におけるリファレンスカウントのオフセット。内部的に利用されます。

### object_basic_type_id_offset

オブジェクト構造体における基本型IDのオフセット。内部的に利用されます。

### object_type_dimension_offset

オブジェクト構造体における型の次元のオフセット。内部的に利用されます。

### object_runtime_type_category_offset

オブジェクト構造体におけるランタイムタイプのカテゴリーのオフセット。内部的に利用されます。

### object_flag_offset

オブジェクト構造体におけるフラグのオフセット。内部的に利用されます。

### object_length_offset

オブジェクト構造体における長さのオフセット。内部的に利用されます。

### byte_object_basic_type_id

SPVM::Byte型の基本型のID。内部的に利用されます。

### short_object_basic_type_id

SPVM::Short型の基本型のID。内部的に利用されます。

### int_object_basic_type_id

SPVM::Int型の基本型のID。内部的に利用されます。

### long_object_basic_type_id

SPVM::Long型の基本型のID。内部的に利用されます。

### float_object_basic_type_id

SPVM::Float型の基本型のID。内部的に利用されます。

### double_object_basic_type_id

SPVM::Double型の基本型のID。内部的に利用されます。

### runtime

SPVMのランタイムへのポインタ。内部的に利用されます。

### exception_object

例外オブジェクト。内部的に利用されます。

### native_mortal_stack

ネイティブ呼び出しで利用されるモータルスタック。内部的に利用されます。

### native_mortal_stack_top

ネイティブ呼び出しで利用されるモータルスタックのトップ位置。内部的に利用されます。

### native_mortal_stack_capacity

ネイティブ呼び出しで利用されるモータルスタックの容量。内部的に利用されます。

### basic_type_id

基本型の名前を指定して、基本型のIDを取得します。存在しない場合は、0より小さい値が返されます。

    int32_t (*get_basic_type_id)(SPVM_ENV* env, const char* basic_type_name);

サンプル:

    int32_t basic_type_id = env->get_basic_type_id(env, "SPVM::Int");

### field_id

パッケージ名と、フィールド名と、シグネチャを指定して、フィールドのIDを取得します。フィールドが存在しない場合は、0より小さい値が返されます。

    int32_t (*get_field_id)(SPVM_ENV* env, const char* package_name, const char* field_name, const char* signature);

シグネチャは、フィールドの型名と同一です。

サンプル:

    int32_t field_id = env->get_field_id(env, "Foo", "x", "int");

### field_offset

フィールドIDを指定して、フィールドのオフセットを取得します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

    int32_t (*get_field_offset)(SPVM_ENV* env, int32_t field_id);

### get_package_var_id

パッケージ名とパッケージ変数名とシグネチャを指定して、パッケージ変数IDを取得します。パッケージ変数が存在しない場合は、0より小さい値が返されます。

    int32_t (*get_package_var_id)(SPVM_ENV* env, const char* package_name, const char* package_var_name, const char* signature);

シグネチャは、パッケージ変数の型名と同一です。

サンプル:

    int32_t pkgvar_id = env->get_package_var_id(env, "Foo", "$VAR", "int");

### get_sub_id

パッケージ名とサブルーチン名とシグネチャを指定して、サブルーチンIDを取得します。サブルーチンが存在しない場合は、0より小さい値が返されます。

    int32_t (*get_sub_id)(SPVM_ENV* env, const char* package_name, const char* sub_name, const char* signature);

シグネチャは、次のフォーマットで指定します。空白を含んではいけません。

    戻り値の型名(引数の型名1,引数の型名2,...)

サンプル:

    int32_t sub_id = env->get_sub_id(env, "Foo", "func", "int(long,string)");

### get_method_sub_id

    int32_t (*get_method_sub_id)(SPVM_ENV* env, void* object, const char* method_name, const char* signature);

オブジェクトとメソッド名を指定して、サブルーチンIDを取得します。メソッドが存在しない場合は、0より小さい値が返されます。

シグネチャは、sub_idのシグネチャと同一です。

サンプル:

    int32_t sub_id = env->get_method_sub_id(env, object, "method", "int(self,long,string)");

### new_object_raw

基本型IDを指定して、新しいオブジェクトを生成します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでなければなりません。

    void* (*new_object_raw)(SPVM_ENV* env, int32_t basic_type_id);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_objectを使用してください。

### new_object

基本型IDを指定して、新しいオブジェクトを生成し、返却します。基本型IDは、basic_type_idで取得した、正しい基本型IDでなければなりません。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*new_object)(SPVM_ENV* env, int32_t basic_type_id);

サンプル:

    int32_t basic_type_id = env->get_basic_type_id(env, "SPVM::Int");
    void* object = env->new_object(env, basic_type_id);

### new_byte_array_raw

配列の長さを指定して新しい「byte[]型」のオブジェクトを生成します。すべての要素の初期値は0です。

    void* (*new_byte_array_raw)(SPVM_ENV* env, int32_t length);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_byte_arrayを使用してください。

### new_byte_array

配列の長さを指定して新しい「byte[]型」のオブジェクトを生成し、返却します。すべての要素の初期値は0です。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*new_byte_array)(SPVM_ENV* env, int32_t length);

サンプル:

    void* byte_array_obj = env->new_byte_array(env, 100);

### new_short_array_raw

配列の長さを指定して新しい「short[]型」のオブジェクトを生成します。すべての要素の初期値は0です。

    void* (*new_short_array_raw)(SPVM_ENV* env, int32_t length);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_short_arrayを使用してください。

### new_short_array

配列の長さを指定して新しい「short[]型」のオブジェクトを生成し、返却します。すべての要素の初期値は0です。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*new_short_array)(SPVM_ENV* env, int32_t length);

サンプル:

    void* short_array_obj = env->new_short_array(env, 100);

### new_int_array_raw

配列の長さを指定して新しい「int[]型」のオブジェクトを生成します。すべての要素の初期値は0です。

    void* (*new_int_array_raw)(SPVM_ENV* env, int32_t length);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_int_arrayを使用してください。

### new_int_array

配列の長さを指定して新しい「int[]型」のオブジェクトを生成し、返却します。すべての要素の初期値は0です。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*new_int_array)(SPVM_ENV* env, int32_t length);

サンプル:

    void* int_array_obj = env->new_int_array(env, 100);

### new_long_array_raw

配列の長さを指定して新しい「long[]型」のオブジェクトを生成します。すべての要素の初期値は0です。

    void* (*new_long_array_raw)(SPVM_ENV* env, int32_t length);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_long_arrayを使用してください。

### new_long_array

配列の長さを指定して新しい「long[]型」のオブジェクトを生成し、返却します。すべての要素の初期値は0です。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*new_long_array)(SPVM_ENV* env, int32_t length);

サンプル:

    void* long_array_obj = env->new_long_array(env, 100);

### new_float_array_raw

配列の長さを指定して新しい「float[]型」のオブジェクトを生成します。すべての要素の初期値は0です。

    void* (*new_float_array_raw)(SPVM_ENV* env, int32_t length);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_float_arrayを使用してください。

### new_float_array

配列の長さを指定して新しい「float[]型」のオブジェクトを生成し、返却します。すべての要素の初期値は0です。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*new_float_array)(SPVM_ENV* env, int32_t length);

サンプル:

    void* float_array_obj = env->new_float_array(env, 100);

### new_double_array_raw

配列の長さを指定して新しい「double[]型」のオブジェクトを生成します。すべての要素の初期値は0です。

    void* (*new_double_array_raw)(SPVM_ENV* env, int32_t length);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_double_arrayを使用してください。

### new_double_array

配列の長さを指定して新しい「double[]型」のオブジェクトを生成し、返却します。すべての要素の初期値は0です。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*new_double_array)(SPVM_ENV* env, int32_t length);

サンプル:

    void* double_array_obj = env->new_double_array(env, 100);

### new_object_array_raw

基本型IDと配列の長さを指定して新しいオブジェクト型の配列を生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでなければなりません。すべての要素の初期値はNULLです。

    void* (*new_object_array_raw)(SPVM_ENV* env, int32_t basic_type_id, int32_t length);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_object_arrayを使用してください。

### new_object_array

基本型IDと配列の長さを指定して新しいオブジェクト型の配列を生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでなければなりません。すべての要素の初期値はNULLです。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*new_object_array)(SPVM_ENV* env, int32_t basic_type_id, int32_t length);

サンプル:

    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);

### new_muldim_array_raw

基本型IDと要素の型の次元と配列の長さを指定して新しい多次元のオブジェクト型の配列を生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでなければなりません。すべての要素の初期値はNULLです。

    void* (*new_muldim_array_raw)(SPVM_ENV* env, int32_t basic_type_id, int32_t element_dimension, int32_t length);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_muldim_arrayを使用してください。

### new_muldim_array

基本型IDと要素の型の次元と配列の長さを指定して新しい多次元のオブジェクト型の配列を生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでなければなりません。すべての要素の初期値はNULLです。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*new_muldim_array_raw)(SPVM_ENV* env, int32_t basic_type_id, int32_t element_dimension, int32_t length);

要素の型の次元は、255より小さくなければなりません。

サンプル:

    // 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);

### new_mulnum_array_raw

基本型IDと配列の長さを指定して新しい複数数値型の配列を生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでかつ、複合数値型として有効でなければなりません。すべての要素のすべてのフィールどの初期値は0です。

    void* (*new_mulnum_array_raw)(SPVM_ENV* env, int32_t basic_type_id, int32_t length);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_mulnum_arrayを使用してください。

### new_mulnum_array

基本型IDと配列の長さを指定して新しい複数数値型の配列を生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでかつ、複合数値型として有効でなければなりません。すべての要素のすべてのフィールどの初期値は0です。

    void* (*new_mulnum_array)(SPVM_ENV* env, int32_t basic_type_id, int32_t length);

サンプル:

    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);

### new_string_raw

C言語の文字列を指定して、文字列型のオブジェクトを生成し、返却します。文字列は「\0」で終端していなければなりません。

    void* (*new_string_raw)(SPVM_ENV* env, const char* bytes);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_stringを使用してください。

### new_string

C言語の文字列を指定して、文字列型のオブジェクトを生成し、返却します。文字列は「\0」で終端していなければなりません。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*new_string)(SPVM_ENV* env, const char* bytes);

サンプル:

    void* str_obj = env->new_string(env, "Hello World");

### new_string_len_raw

C言語の文字列と長さを指定して、文字列型のオブジェクトを生成し、返却します。

    void* (*new_string_len_raw)(SPVM_ENV* env, const char* bytes, int32_t length);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_string_lenを使用してください。

### new_string_len

C言語の文字列と長さを指定して、文字列型のオブジェクトを生成し、返却します。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*new_string_len)(SPVM_ENV* env, const char* bytes, int32_t length);

サンプル:

    void* str_obj = env->new_string_len(env, "Hello\0World", 11);

### new_pointer_raw

基本型IDとC言語のポインタを指定して、ポインタ型のオブジェクトを生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでかつ、ポインタ型として有効でなければなりません。

    void* (*new_pointer_raw)(SPVM_ENV* env, int32_t basic_type_id, void* pointer);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_pointerを使用してください。

### new_pointer

基本型IDとC言語のポインタを指定して、ポインタ型のオブジェクトを生成し、返却します。基本型IDは「basic_type_id関数」で取得した、正しい基本型IDでかつ、ポインタ型として有効でなければなりません。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*new_pointer)(SPVM_ENV* env, int32_t basic_type_id, void* pointer);

サンプル:

    void* pointer = malloc(sizeof(struct tm));
    void* pointer_obj = env->new_pointer(env, "MyTimeInfo", pointer);

詳しいサンプルについてはポインタ型の利用を見てください。

### concat_raw

ふたつのbyte[]型の文字列を結合した新しいbyte[]型のオブジェクトを返却します。

    void* (*concat_raw)(SPVM_ENV* env, void* string1, void* string2);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、concatを使用してください。

### concat

ふたつのbyte[]型の文字列を結合した新しいbyte[]型のオブジェクトを返却します。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*concat)(SPVM_ENV* env, void* string1, void* string2);

### new_stack_trace_raw

byte[]型の例外メッセージと、パッケージ名、サブルーチン名、ファイル名と行番号を指定すると、byte[]型の例外メッセージの末尾に、パッケージ名、サブルーチン名、ファイル名と行番号の文字列を追加した文字列を返却します。

    void* (*new_stack_trace_raw)(SPVM_ENV* env, void* exception, const char* package_name, const char* sub_name, const char* file, int32_t line);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、new_stack_traceを使用してください。

### new_stack_trace

byte[]型の例外メッセージと、パッケージ名、サブルーチン名、ファイル名と行番号を指定すると、string型の例外メッセージの末尾に、パッケージ名、サブルーチン名、ファイル名と行番号の文字列を追加した新しいstring型のオブジェクトを返却します。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*new_stack_trace)(SPVM_ENV* env, void* exception, const char* package_name, const char* sub_name, const char* file, int32_t line);

### len

配列を指定すると、配列の長さを返却します。

    int32_t (*len)(SPVM_ENV*, void* array);

サンプル:

    int32_t length = env->length(env, array);

### get_elems_byte

byte[]型の配列を指定すると、内部的に保有しているC言語のint8_t[]型の配列の先頭のポインタを返却します。

    int8_t* (*get_elems_byte)(SPVM_ENV* env, void* array);

サンプル:

    int8_t* values = env->get_elems_byte(env, array);
    values[3] = 5;

### get_elems_short

short[]型の配列を指定すると、内部的に保有しているC言語のint16_t[]型の配列の先頭のポインタを返却します。

    int16_t* (*get_elems_short)(SPVM_ENV* env, void* array);

サンプル:

    int16_t* values = env->get_elems_short(env, array);
    values[3] = 5;

### get_elems_int

int[]型の配列を指定すると、内部的に保有しているC言語のint32_t[]型の配列の先頭のポインタを返却します。

    int32_t* (*get_elems_int)(SPVM_ENV* env, void* array);

サンプル:

    int32_t* values = env->get_elems_int(env, array);
    values[3] = 5;

### get_elems_long

long[]型の配列を指定すると、内部的に保有しているC言語のint64_t[]型の配列の先頭のポインタを返却します。

    int64_t* (*get_elems_long)(SPVM_ENV* env, void* array);

サンプル:

    int64_t* values = env->get_elems_long(env, array);
    values[3] = 5;

### get_elems_float

float[]型の配列を指定すると、内部的に保有しているC言語のfloat[]型の配列の先頭のポインタを返却します。

    float* (*get_elems_float)(SPVM_ENV* env, void* array);

サンプル:

    float* values = env->get_elems_float(env, array);
    values[3] = 1.5f;

### get_elems_double

double[]型の配列を指定すると、内部的に保有しているC言語のdouble[]型の配列の先頭のポインタを返却します。

    double* (*get_elems_double)(SPVM_ENV* env, void* array);

サンプル:

    double* values = env->get_elems_double(env, array);
    values[3] = 1.5;

### get_elem_object

オブジェクト型の配列と添え字を指定して、要素のオブジェクトを取得します。もし要素が弱参照になっていた場合は、弱参照が取り除かれます。

    void* (*get_elem_object)(SPVM_ENV* env, void* array, int32_t index);

サンプル:

    void* object = env->get_elem_object(env, array, 3);

### set_elem_object

オブジェクト型の配列と添え字と要素のオブジェクトを指定すると、対応する添え字の位置に要素のオブジェクトが代入されます。要素のオブジェクトが弱参照になっていた場合は、弱参照が取り除かれます。もともと代入されていたオブジェクトのリファレンスカウントは、1減らされます。

    void (*set_elem_object)(SPVM_ENV* env, void* array, int32_t index, void* value);

サンプル:

    env->get_elem_object(env, array, 3, object);

### get_field_byte

オブジェクトとフィールドIDを指定すると、byte型のフィールドの値をC言語のint8_t型の値として返却します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

    int8_t (*get_field_byte)(SPVM_ENV* env, void* object, int32_t field_id);

サンプル:

    int32_t field_id = env->get_field_id(env, "Foo", "x", "byte");
    int8_t field_value = env->get_field_byte(env, object, field_id);

### get_field_short

オブジェクトとフィールドIDを指定すると、short型のフィールドの値をC言語のint16_t型の値として返却します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

      int16_t (*get_field_short)(SPVM_ENV* env, void* object, int32_t field_id);

サンプル:

    int32_t field_id = env->get_field_id(env, "Foo", "x", "short");
    int16_t field_value = env->get_field_short(env, object, field_id);

### get_field_int

オブジェクトとフィールドIDを指定すると、int型のフィールドの値をC言語のint32_t型の値として返却します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

      int32_t (*get_field_int)(SPVM_ENV* env, void* object, int32_t field_id);

サンプル:

    int32_t field_id = env->get_field_id(env, "Foo", "x", "int");
    int32_t field_value = env->get_field_int(env, object, field_id);

### get_field_long

オブジェクトとフィールドIDを指定すると、long型のフィールドの値をC言語のint64_t型の値として返却します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

      int64_t (*get_field_long)(SPVM_ENV* env, void* object, int32_t field_id);

サンプル:

    int32_t field_id = env->get_field_id(env, "Foo", "x", "long");
    int64_t field_value = env->get_field_long(env, object, field_id);

### get_field_float

オブジェクトとフィールドIDを指定すると、float型のフィールドの値をC言語のfloat型の値として返却します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

      float (*get_field_float)(SPVM_ENV* env, void* object, int32_t field_id);

サンプル:

    int32_t field_id = env->get_field_id(env, "Foo", "x", "float");
    float field_value = env->get_field_float(env, object, field_id);

### get_field_double

オブジェクトとフィールドIDを指定すると、double型のフィールドの値をC言語のdouble型の値として返却します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

      double (*get_field_double)(SPVM_ENV* env, void* object, int32_t field_id);

サンプル:

    int32_t field_id = env->get_field_id(env, "Foo", "x", "double");
    double field_value = env->get_field_double(env, object, field_id);

### get_field_object

オブジェクトとフィールドIDを指定すると、オブジェクト型のフィールドの値をC言語のvoid*型の値として返却します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。フィールドが弱参照である場合は、取り除かれます。

      void* (*get_field_object)(SPVM_ENV* env, void* object, int32_t field_id);

    int32_t field_id = env->get_field_id(env, "Foo", "x", "SPVM::Int");
    void* field_value = env->get_field_object(env, object, field_id);

### set_field_byte

オブジェクトとフィールドIDとフィールドの値を指定すると、byte型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

      void (*set_field_byte)(SPVM_ENV* env, void* object, int32_t field_id, int8_t value);

サンプル:

    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);

### set_field_short

オブジェクトとフィールドIDとフィールドの値を指定すると、short型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

      void (*set_field_short)(SPVM_ENV* env, void* object, int32_t field_id, int16_t value);

サンプル:

    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);

### set_field_int

オブジェクトとフィールドIDとフィールドの値を指定すると、int型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

      void (*set_field_int)(SPVM_ENV* env, void* object, int32_t field_id, int32_t value);

サンプル:

    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);

### set_field_long

オブジェクトとフィールドIDとフィールドの値を指定すると、long型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

      void (*set_field_long)(SPVM_ENV* env, void* object, int32_t field_id, int64_t value);

サンプル:

    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);

### set_field_float

オブジェクトとフィールドIDとフィールドの値を指定すると、float型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

      void (*set_field_float)(SPVM_ENV* env, void* object, int32_t field_id, float value);

サンプル:

    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);

### set_field_double

オブジェクトとフィールドIDとフィールドの値を指定すると、double型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

      void (*set_field_double)(SPVM_ENV* env, void* object, int32_t field_id, double value);

サンプル:

    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);

### set_field_object

オブジェクトとフィールドIDとフィールドの値を指定すると、オブジェクト型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。設定後の値は、リファレンスカウントが1増やされます。元の値は、リファレンスカウントが1減らされます。

      void (*set_field_object)(SPVM_ENV* env, void* object, int32_t field_id, void* value);

サンプル:

    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);

### get_package_var_byte

オブジェクトとパッケージ変数IDを指定すると、byte型のパッケージ変数の値をC言語のint8_t型の値として返却します。パッケージ変数IDはfield_id関数で取得した有効なパッケージ変数IDである必要があります。

    int8_t (*get_package_var_byte)(SPVM_ENV* env, int32_t pkgvar_id);

サンプル:

    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);

### get_package_var_short

オブジェクトとパッケージ変数IDを指定すると、short型のパッケージ変数の値をC言語のint16_t型の値として返却します。パッケージ変数IDはfield_id関数で取得した有効なパッケージ変数IDである必要があります。

    int16_t (*get_package_var_short)(SPVM_ENV* env, int32_t pkgvar_id);

サンプル:

    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);

### get_package_var_int

オブジェクトとパッケージ変数IDを指定すると、int型のパッケージ変数の値をC言語のint32_t型の値として返却します。パッケージ変数IDはfield_id関数で取得した有効なパッケージ変数IDである必要があります。

    int32_t (*get_package_var_int)(SPVM_ENV* env, int32_t pkgvar_id);

サンプル:

    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);

### get_package_var_long

オブジェクトとパッケージ変数IDを指定すると、long型のパッケージ変数の値をC言語のint64_t型の値として返却します。パッケージ変数IDはfield_id関数で取得した有効なパッケージ変数IDである必要があります。

    int64_t (*get_package_var_long)(SPVM_ENV* env, int32_t pkgvar_id);

サンプル:

    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);

### get_package_var_float

オブジェクトとパッケージ変数IDを指定すると、float型のパッケージ変数の値をC言語のfloat型の値として返却します。パッケージ変数IDはfield_id関数で取得した有効なパッケージ変数IDである必要があります。

    float (*get_package_var_float)(SPVM_ENV* env, int32_t pkgvar_id);

サンプル:

    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);

### get_package_var_double

オブジェクトとパッケージ変数IDを指定すると、double型のパッケージ変数の値をC言語のdouble型の値として返却します。パッケージ変数IDはfield_id関数で取得した有効なパッケージ変数IDである必要があります。

    double (*get_package_var_double)(SPVM_ENV* env, int32_t pkgvar_id);

サンプル:

    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);

### get_package_var_object

オブジェクトとパッケージ変数IDを指定すると、オブジェクト型のパッケージ変数の値をC言語のvoid*型の値として返却します。パッケージ変数IDはfield_id関数で取得した有効なパッケージ変数IDである必要があります。

    void* (*get_package_var_object)(SPVM_ENV* env, int32_t pkgvar_id);

サンプル:

    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);

### set_package_var_byte

オブジェクトとフィールドIDとフィールドの値を指定すると、byte型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

    void (*set_package_var_byte)(SPVM_ENV* env, int32_t pkgvar_id, int8_t value);

サンプル:

    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);

### set_package_var_short

オブジェクトとフィールドIDとフィールドの値を指定すると、short型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

    void (*set_package_var_short)(SPVM_ENV* env, int32_t pkgvar_id, int16_t value);

サンプル:

    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);

### set_package_var_int

オブジェクトとフィールドIDとフィールドの値を指定すると、int型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

    void (*set_package_var_int)(SPVM_ENV* env, int32_t pkgvar_id, int32_t value);

サンプル:

    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);

### set_package_var_long

オブジェクトとフィールドIDとフィールドの値を指定すると、long型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

    void (*set_package_var_long)(SPVM_ENV* env, int32_t pkgvar_id, int64_t value);

サンプル:

    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);

### set_package_var_float

オブジェクトとフィールドIDとフィールドの値を指定すると、float型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

    void (*set_package_var_float)(SPVM_ENV* env, int32_t pkgvar_id, float value);

サンプル:

    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);

### set_package_var_double

オブジェクトとフィールドIDとフィールドの値を指定すると、double型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。

    void (*set_package_var_double)(SPVM_ENV* env, int32_t pkgvar_id, double value);

サンプル:

    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);

### set_package_var_object

オブジェクトとフィールドIDとフィールドの値を指定すると、オブジェクト型のフィールドに値を設定します。フィールドIDはfield_id関数で取得した有効なフィールドIDである必要があります。設定後の値は、リファレンスカウントが1増やされます。元の値は、リファレンスカウントが1減らされます。

    void (*set_package_var_object)(SPVM_ENV* env, int32_t pkgvar_id, void* value);

サンプル:

    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);

### get_pointer

ポインタ型のオブジェクトを指定して、オブジェクトの内部に保存されているC言語のポインタを返却します。

    void* (*get_pointer)(SPVM_ENV* env, void* pointer_object);

サンプル:

    strcut tm* tm_ptr = (struct tm*)env->get_pointer(env, tm_obj);

詳しいサンプルについてはポインタ型の利用を見てください。

### set_pointer

ポインタ型のオブジェクトと、C言語のポインタを指定すると、ポインタ型のオブジェクトの内部データに、C言語のポインタが保存されます。

    void (*set_pointer)(SPVM_ENV* env, void* pointer_object, void* pointer);

### call_sub

サブルーチンIDと引数を指定して、サブルーチンを呼び出します。戻り値は、サブルーチンで例外が発生した場合は0以外を、例外が発生しなかった場合は0を返却します。

    int32_t (*call_sub)(SPVM_ENV* env, int32_t sub_id, SPVM_VALUE* args);

サブルーチンの戻り値は「args[0]」に、設定されます。

### get_exception

例外として保存されているbyte[]型のオブジェクトを返却します。

    void* (*get_exception)(SPVM_ENV* env);

### set_exception

byte[]型のオブジェクトを指定すると、例外として保存します。

    void (*set_exception)(SPVM_ENV* env, void* exception);

### get_ref_count

オブジェクトを指定すると、オブジェクトのリファレンスカウントを返却します。

    int32_t (*get_ref_count)(SPVM_ENV* env, void* object);

### inc_ref_count

オブジェクトを指定すると、オブジェクトのリファレンスカウントを1増やします。

    void (*inc_ref_count)(SPVM_ENV* env, void* object);

このメソッドは、使うべき、特別な理由がある場合のみ使用してください。通常は、リファレンスカウントは、自動的に管理されています。

### dec_ref_count

オブジェクトを指定すると、オブジェクトのリファレンスカウントを1減らします。リファレンスカウントが0になった場合、オブジェクトを解放します。

    void (*dec_ref_count)(SPVM_ENV* env, void* object);

このメソッドは、使うべき、特別な理由がある場合のみ使用してください。通常は、リファレンスカウントは、自動的に管理されています。

### enter_scope

新しいスコープを作成し、スコープIDを返却します。

    int32_t (*enter_scope)(SPVM_ENV* env);

### push_mortal

モータルスタックに、オブジェクトを追加します。

    void (*push_mortal)(SPVM_ENV* env, void* object);

### leave_scope

スコープIDを指定して、そのスコープを終了し、モータルスタックに格納されている、オブジェクトのリファレンスカウントを1減らします。リファレンスカウントが0になったオブジェクトは解放されます。スコープIDは、enter_scope関数で取得したIDでなければなりません。

    void (*leave_scope)(SPVM_ENV* env, int32_t scope_id);

### remove_mortal

スコープIDと、オブジェクトを指定すると、指定されたオブジェクトをモータルスタックから削除します。

    int32_t (*remove_mortal)(SPVM_ENV* env, int32_t scope_id, void* remove_object);

### is_type

オブジェクトと基本型IDと型の次元を指定すると、オブジェクトが、基本型IDと型の次元の両方に一致した場合、0以外の値を、そうでない場合は、0を返します。

    int32_t (*is_type)(SPVM_ENV* env, void* object, int32_t basic_type_id, int32_t type_dimension);

### has_callback

オブジェクトとコールバック型の基本型IDを指定すると、オブジェクトが、コールバック型に適合した場合は0以外の値を、そうでない場合は、0を返します。

    int32_t (*has_callback)(SPVM_ENV* env, void* object, int32_t callback_basic_type_id);

### get_object_basic_type_id

オブジェクトの基本型IDを取得します。

    int32_t (*get_object_basic_type_id)(SPVM_ENV* env, void* object);

### get_object_type_dimension

オブジェクトの型の次元を取得します。

    int32_t (*get_object_type_dimension)(SPVM_ENV* env, void* object);

### weaken

オブジェクトのアドレスを指定すると、オブジェクトを弱参照にします。

    void (*weaken)(SPVM_ENV* env, void** object_address);

### isweak

オブジェクトのアドレスを指定すると、オブジェクトが弱参照の場合は、0以外の値を、そうでない場合は、0を返します。

    int32_t (*isweak)(SPVM_ENV* env, void** object);

### unweaken

オブジェクトのアドレスを指定すると、オブジェクトの弱参照を解除します。

    void (*unweaken)(SPVM_ENV* env, void** object_address);

### alloc_memory_block_zero

サイズをバイトで指定すると、メモリブロックを割り当て、割り当てられたメモリブロックのポインタを返却します。メモリブロックのビットはすべて0で初期化されます。メモリブロックカウントが1増加します。

    void* (*alloc_memory_block_zero)(SPVM_ENV* env, int64_t byte_size);

### free_memory_block

メモリブロックを指定すると、解放します。メモリブロックカウントが1減少します。

    void (*free_memory_block)(SPVM_ENV* env, void* block);

### get_memory_blocks_count

現在のメモリブロックの数を返却します。

    int32_t (*get_memory_blocks_count)(SPVM_ENV* env);

メモリブロックは、オブジェクトを生成した場合、alloc_memory_block_zero関数を呼び出した場合、weaken関数でバックリファレンスが追加された場合に、1増加します。

### get_type_name_raw

オブジェクトを指定すると、型名を保存した新しいbyte[]型のオブジェクトを返却します。

    void* (*get_type_name_raw)(SPVM_ENV* env, void* object);

この関数は、モータルスタックにオブジェクトを追加しないので、通常の利用はメモリリークを避けるために、type_nameを使用してください。

### get_type_name

オブジェクトを指定すると、型名を保存した新しいbyte[]型のオブジェクトを返却します。モータルスタックに新しく生成されたオブジェクトを追加します。

    void* (*get_type_name)(SPVM_ENV* env, void* object);

### new_env

現在の実行環境を元にした、新しい実行環境を作成します。

    SPVM_ENV* (*new_env)(SPVM_ENV* env);

この関数は、新しいスレッドにおいて、新しい実行環境を生成したい場合に、利用してください。

例外オブジェクト、モータルスタックの情報は、初期化されます。

パッケージ変数は、元の実行環境と共有します。

メモリブロックの数は、元の実行環境と共有します。

### free_env

実行環境を開放します。

    void (*free_env)(SPVM_ENV* env);