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ネイティブサブルーチンの宣言は、サブルーチンのディスクリプタ「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

引数の取得

引数とスタック

スタックとは、ネイティブサブルーチンの定義における第二引数で渡される「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;

戻り値の設定

戻り値とスタック

ネイティブサブルーチンは、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->sub_id(env, "Foo", "sum", "int(int,int)");

// メソッドの場合
int32_t sub_id = env->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_obj」などのオブジェクトを生成するネイティブ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_str」で例外メッセージを作成して「set_exception」で設定できます。

env->set_exception(env, env->new_str(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->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->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メソッドです。pointer関数を使うと、ポインタ型のオブジェクトから「struct tm」として割り当てられたメモリのポインタを取得することができます。

  void* tm_obj = stack[0].oval;
  
  strcut tm* tm_ptr = (struct tm*)env->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->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    basic_type_id
21    field_id
22    field_offset
23    pkgvar_id
24    sub_id
25    method_sub_id
26    new_obj_raw
27    new_obj
28    new_barray_raw
29    new_barray
30    new_sarray_raw
31    new_sarray
32    new_iarray_raw
33    new_iarray
34    new_larray_raw
35    new_larray
36    new_farray_raw
37    new_farray
38    new_darray_raw
39    new_darray
40    new_oarray_raw
41    new_oarray
42    new_marray_raw
43    new_marray
44    new_varray_raw
45    new_varray
46    new_str_raw
47    new_str
48    new_str_len_raw
49    new_str_len
50    new_pointer_raw
51    new_pointer
52    concat_raw
53    concat
54    new_stack_trace_raw
55    new_stack_trace
56    len
57    belems
58    selems
59    ielems
60    lelems
61    felems
62    delems
63    oelem
64    set_oelem
65    bfield
66    sfield
67    ifield
68    lfield
69    ffield
70    dfield
71    ofield
72    set_bfield
73    set_sfield
74    set_ifield
75    set_lfield
76    set_ffield
77    set_dfield
78    set_ofield
79    bpkgvar
80    spkgvar
81    ipkgvar
82    lpkgvar
83    fpkgvar
84    dpkgvar
85    opkgvar
86    set_bpkgvar
87    set_spkgvar
88    set_ipkgvar
89    set_lpkgvar
90    set_fpkgvar
91    set_dpkgvar
92    set_opkgvar
93    pointer
94    set_pointer
95    call_sub
96    exception
97    set_exception
98    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   object_basic_type_id
108   object_type_dimension
109   weaken
110   isweak
111   unweaken
112   alloc_memory_block_zero
113   free_memory_block
114   memory_blocks_count
115   type_name_raw
116   type_name
117   new_env
118   free_env

ネイティブAPIの呼び出し

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

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

ネイティブAPIの一覧

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 (*basic_type_id)(SPVM_ENV* env, const char* basic_type_name);

サンプル:

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

field_id

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

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

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

サンプル:

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

field_offset

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

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

pkgvar_id

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

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

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

サンプル:

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

sub_id

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

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

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

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

サンプル:

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

method_sub_id

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

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

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

サンプル:

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

new_obj_raw

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

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

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

new_obj

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

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

サンプル:

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

new_barray_raw

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

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

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

new_barray

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

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

サンプル:

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

new_sarray_raw

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

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

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

new_sarray

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

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

サンプル:

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

new_iarray_raw

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

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

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

new_iarray

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

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

サンプル:

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

new_larray_raw

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

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

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

new_larray

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

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

サンプル:

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

new_farray_raw

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

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

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

new_farray

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

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

サンプル:

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

new_darray_raw

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

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

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

new_darray

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

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

サンプル:

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

new_oarray_raw

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

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

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

new_oarray

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

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

サンプル:

int32_t basic_type_id = env->basic_type_id(env, "SPVM::Int");
void* object_array_obj = env->new_oarray(env, basic_type_id, 100);

new_marray_raw

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

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

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

new_marray

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

void* (*new_marray_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->basic_type_id(env, "SPVM::Int");
void* multi_array_obj = env->new_marray(env, basic_type_id, 2, 100);

new_varray_raw

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

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

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

new_varray

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

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

サンプル:

int32_t basic_type_id = env->basic_type_id(env, "SPVM::Complex_2d");
void* value_array_obj = env->new_varray(env, basic_type_id, 100);

new_str_raw

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

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

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

new_str

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

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

サンプル:

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

new_str_len_raw

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

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

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

new_str_len

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

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

サンプル:

void* str_obj = env->new_str_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->len(env, array);

belems

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

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

サンプル:

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

selems

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

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

サンプル:

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

ielems

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

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

サンプル:

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

lelems

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

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

サンプル:

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

felems

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

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

サンプル:

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

delems

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

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

サンプル:

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

oelem

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

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

サンプル:

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

set_oelem

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

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

サンプル:

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

bfield

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

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

サンプル:

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

sfield

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

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

サンプル:

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

ifield

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

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

サンプル:

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

lfield

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

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

サンプル:

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

ffield

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

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

サンプル:

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

dfield

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

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

サンプル:

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

ofield

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

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

set_bfield

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

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

サンプル:

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

set_sfield

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

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

サンプル:

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

set_ifield

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

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

サンプル:

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

set_lfield

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

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

サンプル:

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

set_ffield

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

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

サンプル:

int32_t field_id = env->field_id(env, "Foo", "x", "float");
float field_value = 1.5f;
env->set_ffield(env, object, field_id, field_value);

set_dfield

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

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

サンプル:

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

set_ofield

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

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

サンプル:

int32_t field_id = env->field_id(env, "Foo", "x", "SPVM::Int");
int32_t basic_type_id = env->basic_type_id(env, "SPVM::Int");
void* object = env->new_obj(env, basic_type_id);
env->set_ofield(env, object, field_id, object);

bpkgvar

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

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

サンプル:

int32_t pkgvar_id = env->pkgvar_id(env, "Foo", "$VAR", "byte");
int8_t pkgvar_value = env->bpkgvar(env, object, pkgvar_id);

spkgvar

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

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

サンプル:

int32_t pkgvar_id = env->pkgvar_id(env, "Foo", "$VAR", "short");
int16_t pkgvar_value = env->spkgvar(env, object, pkgvar_id);

ipkgvar

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

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

サンプル:

int32_t pkgvar_id = env->pkgvar_id(env, "Foo", "$VAR", "int");
int32_t pkgvar_value = env->ipkgvar(env, object, pkgvar_id);

lpkgvar

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

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

サンプル:

int32_t pkgvar_id = env->pkgvar_id(env, "Foo", "$VAR", "long");
int64_t pkgvar_value = env->lpkgvar(env, object, pkgvar_id);

fpkgvar

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

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

サンプル:

int32_t pkgvar_id = env->pkgvar_id(env, "Foo", "$VAR", "float");
float pkgvar_value = env->fpkgvar(env, object, pkgvar_id);

dpkgvar

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

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

サンプル:

int32_t pkgvar_id = env->pkgvar_id(env, "Foo", "$VAR", "double");
double pkgvar_value = env->dpkgvar(env, object, pkgvar_id);

opkgvar

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

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

サンプル:

int32_t pkgvar_id = env->pkgvar_id(env, "Foo", "$VAR", "SPVM::Int");
void* pkgvar_value = env->bpkgvar(env, object, pkgvar_id);

set_bpkgvar

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

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

サンプル:

int32_t pkgvar_id = env->pkgvar_id(env, "Foo", "$VAR", "byte");
int8_t pkgvar_value = 5;
env->set_bpkgvar(env, pkgvar_id, pkgvar_value);

set_spkgvar

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

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

サンプル:

int32_t pkgvar_id = env->pkgvar_id(env, "Foo", "$VAR", "short");
int16_t pkgvar_value = 5;
env->set_spkgvar(env, pkgvar_id, pkgvar_value);

set_ipkgvar

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

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

サンプル:

int32_t pkgvar_id = env->pkgvar_id(env, "Foo", "$VAR", "int");
int32_t pkgvar_value = 5;
env->set_ipkgvar(env, pkgvar_id, pkgvar_value);

set_lpkgvar

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

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

サンプル:

int32_t pkgvar_id = env->pkgvar_id(env, "Foo", "$VAR", "long");
int64_t pkgvar_value = 5;
env->set_lpkgvar(env, pkgvar_id, pkgvar_value);

set_fpkgvar

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

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

サンプル:

int32_t pkgvar_id = env->pkgvar_id(env, "Foo", "$VAR", "float");
float pkgvar_value = 5;
env->set_fpkgvar(env, pkgvar_id, pkgvar_value);

set_dpkgvar

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

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

サンプル:

int32_t pkgvar_id = env->pkgvar_id(env, "Foo", "$VAR", "double");
double pkgvar_value = 5;
env->set_dpkgvar(env, pkgvar_id, pkgvar_value);

set_opkgvar

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

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

サンプル:

int32_t pkgvar_id = env->pkgvar_id(env, "Foo", "$VAR", "SPVM::Int");
int32_t basic_type_id = env->basic_type_id(env, "SPVM::Int");
void* object = env->new_obj(env, basic_type_id);
env->set_opkgvar(env, pkgvar_id, pkgvar_value);

pointer

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

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

サンプル:

strcut tm* tm_ptr = (struct tm*)env->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]」に、設定されます。

exception

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

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

set_exception

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

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

ref_count

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

int32_t (*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);

object_basic_type_id

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

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

object_type_dimension

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

int32_t (*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);

memory_blocks_count

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

int32_t (*memory_blocks_count)(SPVM_ENV* env);

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

type_name_raw

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

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

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

type_name

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

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

new_env

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

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

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

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

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

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

free_env

実行環境を開放します。

void (*free_env)(SPVM_ENV* env);