· <мнемоническое_имя> <метка>; Такую форму имеют команды перехода: goto, goto_w, if_acmpeq, if_acmpne, if_acmpge, if_acmpgt, if_icmple, if_icmplt, if_icmpne, ifeq, ifge, ifgt, ifle, iflt, ifne, ifnonull, ifnull, jsr, jsr_w;
· <мнемоническое_имя> <целое число>; Число должно удовлетворять ограничениям конкретной команды: aload, astore, dload, dstore, fload, fstore, iload, istore, lload, lstore, ret, bipush, sipush, wide_aload, wide_astore, wide_dload, wide_dstore, wide_fload, wide_fstore, wide_iload, wide_istore, wide_lload, wide_lstore, wide_ret;
· <мнемоническое_имя> @::<имя_поля>:<тип_поля>; Тип_поля - имя примитивного типа, принятое в языке Java, либо имя класса. Команды: getfield, putfield, getstatic, putstatic;
· <мнемоническое_имя> <полное_имя_класса>::<имя_метода>(<тип_параметра_1>, ... , <тип_параметра_n>):<тип_возвращаемого значения>; Здесь типы параметров и возвращаемого значения - имена примитивных типов, принятые в языке Java, имена классов, либо (только для возвращаемого значения) void. Команды: invokespecial, invokestatic, invokevirtual;
· <мнемоническое_имя> <полное_имя_класса>; Такой формат имеют следующие команды: anewarray, checkcast, instanceof, new;
· <мнемоническое_имя> <целое_число_индекс_переменной> <целое_число>; Команды: iinc, wide_iinc;
· <мнемоническое_имя> <тип> <константа>; - команды ldc, ldc_w, ldc_2w. Здесь тип - int, float, string (для ldc, ldc_w), double, long (для ldc_2w). Константа должна иметь соответствующий тип (целые числа записываются обычным способом, вещественные - в десятичной или экспоненциальной форме, в формате, принятом в Java, строки записываются в двойных кавычках, при этом две двойные кавычки внутри строки интерпретируются как одна двойная кавычка в строке);
· invokeinterface <имя_интерфейса>::<имя_метода>(<тип_аргумента_1>, ... , <тип_аргумента_2>):<тип_возвращаемого_значения> <целое_число>; - типы - аналогично другим командам вызова методов;
· multianewarray <полное_имя_класса> <число_измерений>;
· newarray short;
· tableswitch <число_1>:<число_n> default: <метка_0> <число_1>:<метка_1> ... <число_n>:<метка_n>; Здесь числа число_1 ... число_n должны быть последовательными целыми числами. При этом числа, указанные сразу после мнемонического имени команды, должны совпадать с границами диапазона чисел, для которых указаны метки перехода. lookupswitch default:<метка_0> <число_1>:<метка_1> ... <число_n>:<метка_n>; Здесь среди чисел, для которых указаны метки перехода, не должно быть одинаковых. Эти числа должны быть целыми, они не обязаны быть упорядочены по возрастанию, сортировка происходит при обработке команды компилятором.
Для тестирования компилятора использовались, в частности, следующие примеры:
%файл Summator.jsm
public class Summator;
fields;
private m_i:int;
methods;
%Конструктор. Заносит в поле m_i целое число, содержащееся в строке,
%передаваемой в качестве параметра. В случае, если строка не содержит
%правильной записи целого числа, либо это число отрицательное,
%то выводится сообщение об ошибке.
public <init>(java.lang.String):void;
maxstack 4;
maxlocals 2;
aload_0; %this
dup;
invokespecial java.lang.Object::<init>():void;
aload_1; %arg1
begin_try:
invokestatic java.lang.Integer::parseInt(java.lang.String):int;
iconst_0;
if_icmpge end_try;
new java.lang.Exception;
invokespecial java.lang.Exception::<init>():void;
athrow;
end_try:
putfield @::m_i:int;
return;
exception:
pop;
getstatic java.lang.System::out:java.io.PrintStream;
ldc string "Invalid argument";
invokevirtual java.io.PrintStream::println(java.lang.String):void;
protected_blocks;
java.lang.Exception
begin_try : end_try > exception;
end;
%возвращает сумму натуральных чисел от 1 до m_i.
public getSum():int;
maxstack 3;
istore_1;
getfield @::m_i:int;
loop:
iload_1; %result
iadd;
istore_1; %result
iconst_1;
isub;
if_icmpgt loop;
ireturn;
%возвращает значение поля m_i
public getI():int;
maxstack 1;
maxlocals 1;
%файл Switches.jsm
public class Switches;
%оба метода функционально эквивалентны следующей функции, написанной на Java.
% static int function(int i) {
% switch(i) {
% case 1: return 2;
% case 2: return -1;
% default: return 0;
% }
public static lookup(int):int;
iload_0;
lookupswitch
default : l_def
1 : l_1
2 : l_2;
l_def:
l_1:
iconst_2;
l_2:
iconst_m1;
public static table(int):int;
tableswitch 1:2
Следующий пример представляет собой программу, состоящую из 5 классов.
%-------------------------------------------------------------%
%файл Figure.jsm
public interface Figure;
public abstract getArea():double;
%файл Circle.jsm
public class Circle;
implements Figure;
private m_radius:double;
public <init>(double):void;
maxlocals 3;
aload_0;
dload_1;
dconst_0;
dcmpg;
ifge l_endif;
new java.lang.IllegalArgumentException;
invokespecial java.lang.IllegalArgumentException::<init>():void;
l_endif:
putfield @::m_radius:double;
public getArea():double;
getfield @::m_radius:double;
dmul;
ldc2_w double 3.14159265;
dreturn;
%файл Rectangle.jsm
public class Rectangle;
private m_a:double;
private m_b:double;
public <init>(double, double):void;
maxlocals 5;
Страницы: 1, 2, 3, 4, 5, 6, 7