Coins Java - Bytecode Mapping

バイトコードマッピング

TODO

共通マクロ

#define CHECK_NULL(obj) if (!obj) (例外)
#define CHECK_BOUNDS(ar, i) if (ARRAY_LENGTH(ar) >= i) (例外)
#define ARRAY_LENGTH(ar) (*(int *)((void *)array + 1))
#define ARRAY_BODY(ar) ((void *)((int *)((void *)array + 1) + 1))

定数処理

aconst_null

ivar = (void *)0;

iconst_<n>, bipush n, sipush n, ldc (int), ldc_w (int)

ivar = n;

lconst_<l>, ldc2_w (long)

lvar = l;

fconst_<f>, ldc (float), ldc_w (float)

fvar = f;

dconst_<d>, ldc2_w (double)

dvar = d;

ldc (String), ldc_w (String)

avar = String::intern(_Jv_NewStringUTF(文字列));

ローカル変数の処理

iload n, iload_<n>

ivar = ivar_n;

lload n, lload_<n>

lvar = lvar_n;

fload n, fload_<n>

fvar = fvar_n;

dload n, dload_<n>

dvar = dvar_n;

aload n, aload_<n>

avar = avar_n;

istore n, istore_<n>

ivar_n = ivar;

lstore n, lstore_<n>

lvar_n = lvar;

fstore n, fstore_<n>

fvar_n = fvar;

dstore n, dstore_<n>

dvar_n = dvar;

astore n, astore_<n>

avar_n = avar;

算術演算

Tadd

Tvar1 += Tvar2;

Tsub

Tvar1 -= Tvar2;

Tmul

Tvar1 *= Tvar2;

idiv

_Jv_divI(ivar1, ivar2);

ldiv

_Jv_divJ(lvar1, lvar2);

fdiv, ddiv

Tdiv1 /= Tdiv2;

irem

_Jv_remI(ivar1, ivar2);

lrem

_Jv_remJ(lvar1, lvar2);

frem, drem

__ieee754_fmod(Tvar1, Tvar2);

Tneg

Tvar = -Tvar;

ishl

ivar1 <<= ivar2 & 0x1f

lshl

lvar <<= ivar & 0x3f

ishr

ivar1 >>= ivar2 & 0x1f

lshr

lvar >>= ivar & 0x3f

iushr

ivar1 = ivar1 >> ((unsigned long)ivar2 & 0x1f)

lushr

lvar = lvar >> ((unsigned long)ivar & 0x3f)

Tand

Tvar1 &= Tvar2;

Tor

Tvar1 |= Tvar2;

Txor

Tvar1 ^= Tvar2;

iinc index n

ivar_<index> += n;

比較

lcmp

if (lvar1 > lvar2)
  ivar = 1;
else if (lvar1 == lvar2)
  ivar = 0;
else
  ivar = -1;

Tcmpl

if (Tvar1 > Tvar2)
  ivar = 1;
else if (Tvar1 == Tvar2)
  ivar = 0;
else
  ivar = -1;
  

Tcmpg

if (Tvar1 < Tvar2)
  ivar = -1;
else if (Tvar1 == Tvar2)
  ivar = 0;
else
  ivar = 1;

分岐

ifeq

if (!ivar) goto LABEL;

ifne

if (ivar) goto LABEL;

iflt

if (ivar < 0) goto LABEL;

ifge

if (ivar >= 0) goto LABEL;

ifgt

if (ivar > 0) goto LABEL;

ifle

if (ivar <= 0) goto LABEL;

if_icmpeq

if (ivar1 == ivar2) goto LABEL;

if_icmpne

if (ivar1 != ivar2) goto LABEL; 

if_icmplt

if (ivar1 < ivar2) goto LABEL; 

if_icmpge

if (ivar1 >= ivar2) goto LABEL; 

if_icmpgt

if (ivar1 > ivar2) goto LABEL; 

if_icmple

if (ivar1 <= ivar2) goto LABEL; 

if_acmpeq

if (avar1 == avar2) goto LABEL; 

if_acmpne

if (avar1 != avar2) goto LABEL; 

ifnull

if (!avar1) goto LABEL; 

ifnonnull

if (avar1) goto LABEL; 

goto, goto_w

goto LABEL;

jsr, jsr_w

TODO

ret

TODO

tableswitch, lookupswitch

switch(ivar) {
  case key1: goto LABEL1;
  case key2: goto LABEL2;
  case key3: goto LABEL3;
  ...
  default  : goto LABEL_DEFAULT;
}

配列の処理

newarray atype

avar = _Jv_NewArray(ivar, atype);

anewarray type

void *klass = &(クラス名);
_Jv_InitClass(klass);
avar = _Jv_NewObjectArray (ivar, klass, 0);

multianewarray dim type

作成される配列の次元を表したクラスを、こちら側で用意する必要がある模様

{
  long i;
  long sizes[dim];
  Class *klass0 = &(クラス名);
  ClassLoader *loader = klass->getClassLoaderInternal();
  for (int i = 0; i < dim; i++) {
    sizes[i] = ivar_i;
    klass0 = _Jv_GetArrayClass(klass0, loader);
  }
  multiarray = (多次元配列生成関数)(klass0, dim, sizes);
}

arraylength

void *array = avar;
CHECK_NULL(array);
ivar = ARRAY_LENGTH(array);

Taload

void *array = avar;
int index;
CHECK_NULL(array);
index = ivar;
CHECK_BOUNDS(array, index);
Tvar = ((T *)ARRAY_BODY(array))[index]; 

Tastore (aastore以外)

void *array = avar;
int index;
CHECK_NULL(array);
index = ivar;
CHECK_BOUNDS(array, index);
((T *)ARRAY_BODY(array))[index] = Tvar;

aastore

void *array = avar;
int index;
CHECK_NULL(array);
index = ivar;
CHECK_BOUNDS(array, index);
CHECK_ASSIGNABLE(TODO);
_Jv_CheckArrayStore(array, Tvar);
((void **)ARRAY_BODY(array))[index] = Tvar;

オブジェクト生成

new

void *klass = (クラス);
_Jv_InitClass(klass);
avar = _Jv_AllocObject(klass, (クラスのサイズ));

フィールドの処理

getstatic

_Jv_InitClass((クラス));
Tvar = (フィールド名);

putstatic

_Jv_InitClass((クラス));
(フィールド名) = Tvar;

getfield

CHECK_NULL(avar);
char *field = (char *)avar + 1;
Tvar = *(T *)&field[(オフセット)];

putfield

CHECK_NULL(avar);
char *field = (char *)avar + 1;
*(T *)&field[(オフセット)] = Tvar;

メソッドの処理

invokevirtual

CHECK_NULL(avar);
void **vtable = *(void ***)avar;
// clas, gc_descの分だけずらす
vtable = vtable + 2;
Tvar = ((T(*)(void *, T_ARGS))vtable[(オフセット)])(avar, (実引数));

invokespecial

CHECK_NULL(avar);
Tvar = (メソッドシンボル)(avar, (実引数));

invokestatic

_Jv_InitClass((クラス));
Tvar = (メソッドシンボル)((実引数));

invokeinterface

CHECK_NULL(avar);
void *klass = **(void ***)avar;
void *iface = (インターフェース);
void *mptr = _Jv_LookupInterfaceMethodIdx(klass, iface, (オフセット));
Tvar = ((T(*)(void *, T_ARGS))mptr)(avar, (実引数));

スタック操作

pop, pop2

/* 明示的なコード無し */

dup*

割愛

swap

割愛

その他

nop

/* 明示的なコード無し */

T2S

Svar = (S)Tvar;

Treturn

TODO

return

TODO

athrow

TODO

checkcast

_Jv_CheckCast(avar, (クラス));

instanceof

ivar = _Jv_IsInstanceOf(avar, (クラス));

monitorenter

NULLCHECK(avar);
_Jv_MonitorEnter(avar);

monitorexit

NULLCHECK(avar);
_Jv_MonitorExit(avar);

wide

Copyright (C) 2002-2006 s.arakawa