Ассемблер для платформы Java

public final static COUNT:int = 10;

static c:char = `A';

static c1:char = 13;

private volatile m_flag:boolean;

protected m_list:java.util.ArrayList;

Описание способа в общем случае имеет вид:

[] (,, ... ,): [throws , ... , ];

% для способов с модификатором abstract нижележащая часть описания

% отсутствует

maxstack ;

maxlocals ;

[:]

;

...

[:]

;

[

protected_blocks;

: > ;

...

finally : > ;

]

end;

Тут модификаторы_доступа - ключевики: public, protected Ассемблер для платформы Java, private, static, final, abstract, надлежащие последующим флагам доступа способа: ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_ABSTRACT. Повторение схожих модификаторов доступа в заголовке 1-го способа и сочетания модификаторов, надлежащие нелегальным сочетаниям флагов доступа (см. The Java Virtual Machine Specification), вызывают ошибку времени компиляции. Способы интерфейса непременно Ассемблер для платформы Java должны быть объявлены с модификаторами public и abstract. Имя_метода - корректный идентификатор, или либо для конструкторов и статических инициализаторов. Типы характеристик и тип возвращаемого значения должны быть именами классов, или именами простых типов, принятыми в языке Java (byte, short, int, long, char, float, double, boolean). Не считая того, тип Ассемблер для платформы Java возвращаемого значения может быть указан как void. После ключевика throws в заголовке способа могут быть перечислены через запятую имена классов исключений, генерируемых способом. Для способов, не являющихся абстрактными, после заголовка непременно записываются предложения maxstack и maxlocals, в каких указывается размер стека операндов и области локальных переменных Ассемблер для платформы Java способа (в четырехбайтных ячейках). Потом следует код способа в виде последовательности команд, разбитых точками с запятыми. Каждой команде может предшествовать метка, отделяемая от нее двоеточием. Метка должна быть корректным. Любая команда может иметь менее одной метки, и любая метка должна предшествовать той либо другой команде. Но, имеется особая псевдокоманда none Ассемблер для платформы Java, для которой не генерируется какой-нибудь код (пустая команда). Ее можно использовать, если нужно расположить более одной метки у одной команды либо поместить метку в конец способа. После ключевика protected_blocks могут быть перечислены защищенные блоки (обработчики исключений) способа. Описание каждого защищенного блока состоит из имени класса исключения Ассемблер для платформы Java либо ключевика finally и 3-х меток, разбитых знаками `:' и `>'. 1-ая из их показывает на начало защищенного блока, 2-ая на его конец, 3-я - на место в коде способа, куда перебегает управление при появлении исключения либо при выходе из защищенного блока в случае finally.

Применяемые в коде мнемонические имена команд совпадают с Ассемблер для платформы Java принятыми в The Java Virtual Machine Specification. Но, как исключение, префикс wide не рассматривается как отдельная команда, заместо этого команды, его имеющие, записываются как wide_. Форматы записи команд:

· <мнемоническое_имя>; Такую форму имеют последующие команды: aaload, aastore, aconst_null, aload_0, aload_1, aload_2, aload_3 ,areturn, arraylength, astore_0, astore_1, astore_2, astore_3, athrow, baload, bastore Ассемблер для платформы Java, caload, castore, d2f, d2i, d2l, dadd, daload, dastore, dcmpg, dcmpl, dconst_0, dconst_1, ddiv, dload_0, dload_1, dload_2, dload_3, dmul, dneg, drem, dreturn, dstore_0, dstore_1, dstore_2, dstore_3, dsub, dup, dup2, dup2_x1, dup2_x2, dup_x1, dup_x2, f2d, f2i, f2l, fadd, faload, fastore, fcmpg, fcmpl Ассемблер для платформы Java, fconst_0, fconst_1, fconst_2, fdiv, fload_0, fload_1, fload_2, fload_3, fmul, fneg, frem, freturn, fstore_0, fstore_1, fstore_2, fstore_3, fsub, i2b, i2c, i2d, i2f, i2l, i2s, iadd, iaload, iand, iastore, iconst_0, iconst_1, iconst_2, iconst_3, iconst_4, iconst_5, iconst_m1, idiv, iload_0, iload_1, iload_2, iload_3, imul, ineg, ior Ассемблер для платформы Java, irem, ireturn, ishl, ishr, istore_0, istore_1, istore_2, istore_3, isub, iushr, ixor, l2d, l2f, l2i, ladd, laload, land, lastore, lcmp, lconst_0, lconst_1, ldiv, lload_0, lload_1, lload_2, lload_3, lmul, lneg, lor, lrem, lreturn, lshl, lshr, lstore_0, lstore_1, lstore_2, lstore_3, lsub, lushr, lxor, monitorenter, monitorexit, nop Ассемблер для платформы Java, pop, pop2, return, saload, sastore, swap;

· <мнемоническое_имя> <метка>; Такую форму имеют команды перехода: 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 Ассемблер для платформы Java, 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;

· @::(, ... , <тип_параметра_n>):; Тут Ассемблер для платформы Java типы характеристик и возвращаемого значения - имена простых типов, принятые в языке Java, имена классов, или (только для возвращаемого значения) void. Команды: invokespecial, invokestatic, invokevirtual;

· ; Таковой формат имеют последующие команды: anewarray, checkcast, instanceof, new;

· ; Команды: iinc, wide_iinc;

· ; - команды ldc, ldc_w, ldc_2w. Тут тип - int, float, string (для Ассемблер для платформы Java ldc, ldc_w), double, long (для ldc_2w). Константа обязана иметь соответственный тип (целые числа записываются обыденным методом, вещественные - в десятичной либо экспоненциальной форме, в формате, принятом в Java, строчки записываются в двойных кавычках, при всем этом две двойные кавычки снутри строчки интерпретируются как одна двойная кавычка в строке);

· invokeinterface Ассемблер для платформы Java ::(, ... , ): ; - типы - аналогично другим командам вызова способов;

· multianewarray ;

· newarray double;

· tableswitch :<число_n> default: : ... <число_n>:<метка_n>; Тут числа число_1 ... число_n должны быть поочередными целыми числами. При всем этом числа, обозначенные сходу после мнемонического имени команды, должны совпадать с границами спектра чисел, для которых указаны метки перехода. lookupswitch default: : ... <число_n>:<метка_n>; Тут посреди чисел, для Ассемблер для платформы Java которых указаны метки перехода, не должно быть схожих. Эти числа должны быть целыми, они не должны быть упорядочены по возрастанию, сортировка происходит при обработке команды компилятором.

Тестовые примеры. Для тестирования компилятора использовались, а именно, последующие примеры: 1.

%файл Summator.jsm

public class Summator;

fields;

private m_i:int;

methods;

%Конструктор. Вносит в Ассемблер для платформы Java поле m_i целое число, находящееся в строке,

%передаваемой в качестве параметра. В случае, если строчка не содержит

%правильной записи целого числа, или это число отрицательное,

%то выводится сообщение об ошибке.

public (java.lang.String):void;

maxstack 4;

maxlocals 2;

aload_0; %this

dup;

invokespecial java.lang.Object::():void;

aload_1; %arg1

begin_try:

invokestatic java.lang Ассемблер для платформы Java.Integer::parseInt(java.lang.String):int;

dup;

iconst_0;

if_icmpge end_try;

new java.lang.Exception;

dup;

invokespecial java.lang.Exception::():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(java.lang.String):void;

return;

protected_blocks;

java.lang.Exception

begin_try : end_try > exception;

end;

%возвращает сумму натуральных чисел от 1 до m_i.

public getSum():int;

maxstack 3;

maxlocals 2;

iconst_0;

istore_1;

aload_0; %this

getfield @::m_i:int;

loop:

dup;

iload_1; %result

iadd;

istore_1; %result

iconst_1;

isub;

dup;

iconst_0;

if_icmpgt loop Ассемблер для платформы Java;

pop;

iload_1; %result

ireturn;

end;

%возвращает значение поля m_i

public getI():int;

maxstack 1;

maxlocals 1;

aload_0; %this

getfield @::m_i:int;

ireturn;

end;

2.

%файл Switches.jsm

public class Switches;

fields;

methods;

%оба способа функционально эквивалентны последующей функции, написанной на Java.

% static int function(int i) {

% switch(i) {

% case 1: return 2;

% case 2: return -1;

% default: return 0;

% }

% }

public static Ассемблер для платформы Java lookup(int):int;

maxstack 1;

maxlocals 1;

iload_0;

lookupswitch

default : l_def

1 : l_1

2 : l_2;

l_def:

iconst_0;

ireturn;

l_1:

iconst_2;

ireturn;

l_2:

iconst_m1;

ireturn;

end;

public static table(int):int;

maxstack 1;

maxlocals 1;

iload_0;

tableswitch 1:2

default : l_def

1 : l_1

2 : l_2;

l_def:

iconst_0;

ireturn;

l_1:

iconst_2;

ireturn;

l_2:

iconst_m1;

ireturn;

end;

3. Последующий пример Ассемблер для платформы Java представляет собой программку, состоящую из 5 классов.

%-------------------------------------------------------------%

%файл Figure.jsm

public interface Figure;

methods;

public abstract getArea():double;

%-------------------------------------------------------------%

%-------------------------------------------------------------%

%файл Circle.jsm

public class Circle;

implements Figure;

fields;

private m_radius:double;

methods;

public (double):void;

maxstack 4;

maxlocals 3;

aload_0;

invokespecial java.lang.Object::():void;

dload_1;

dconst_0;

dcmpg;

ifge l_endif;

new Ассемблер для платформы Java java.lang.IllegalArgumentException;

dup;

invokespecial java.lang.IllegalArgumentException::():void;

athrow;

l_endif:

aload_0;

dload_1;

putfield @::m_radius:double;

return;

end;

public getArea():double;

maxstack 4;

maxlocals 1;

aload_0;

getfield @::m_radius:double;

aload_0;

getfield @::m_radius:double;

dmul;

ldc2_w double 3.14159265;

dmul;

dreturn;

end;

%-------------------------------------------------------------%

%-------------------------------------------------------------%

%файл Rectangle.jsm

public class Rectangle;

implements Ассемблер для платформы Java Figure;

fields;

private m_a:double;

private m_b:double;

methods;

public (double, double):void;

maxstack 4;

maxlocals 5;

aload_0;

invokespecial java.lang.Object::():void;

dload_1;

dconst_0;

dcmpl;

iflt l_error;

dload_3;

dconst_0;

dcmpl;

ifge l_endif;

l_error:

new java.lang.IllegalArgumentException;

dup;

invokespecial java.lang.IllegalArgumentException::():void;

athrow;

l Ассемблер для платформы Java_endif:

aload_0;

dload_1;

putfield @::m_a:double;

aload_0;

dload_3;

putfield @::m_b:double;

return;

end;

public getArea():double;

maxstack 4;

maxlocals 1;

aload_0;

getfield @::m_a:double;

aload_0;

getfield @::m_b:double;

dmul;

dreturn;

end;

%-------------------------------------------------------------%

%-------------------------------------------------------------%

%файл Square.jsm

public class Square;

extends Rectangle;

methods;

public (double):void;

maxstack 5;

maxlocals 3;

aload_0;

dload_1;

dload_1;

invokespecial Rectangle::(double Ассемблер для платформы Java, double):void;

return;

end;

%-------------------------------------------------------------%

%-------------------------------------------------------------%

%файл MainClass.jsm

public class MainClass;

methods;

public ():void;

maxstack 1;

maxlocals 1;

aload_0;

invokespecial java.lang.Object::():void;

return;

end;

public static main(java.lang.String[]):void;

maxstack 8;

maxlocals 7;

iconst_3;

anewarray Figure;

astore_1;

aload_1;

iconst_0;

new Circle;

dup;

ldc2_w double 10;

invokespecial Circle::(double):void Ассемблер для платформы Java;

aastore;

aload_1;

iconst_1;

new Rectangle;

dup;

dconst_1;

ldc2_w double 2;

invokespecial Rectangle::(double, double):void;

aastore;

aload_1;

iconst_2;

new Square;

dup;

ldc2_w double 3;

invokespecial Square::(double):void;

aastore;

dconst_0;

dstore_2;

iconst_0;

istore 4;

l_50:

iload 4;

aload_1;

arraylength;

if_icmpge l_75;

dload_2;

aload_1;

iload 4;

aaload;

invokeinterface Figure::getArea():double, 1;

dadd Ассемблер для платформы Java;

dstore_2;

iinc 4, 1;

goto l_50;

l_75:

new java.io.BufferedReader;

dup;

new java.io.InputStreamReader;

dup;

getstatic java.lang.System::in:java.io.InputStream;

invokespecial java.io.InputStreamReader::(java.io.InputStream):void;

invokespecial java.io.BufferedReader::(java.io.Reader):void;

astore 4;

l_50:

aload 4;

invokevirtual java.io.BufferedReader::readLine():java.lang.String Ассемблер для платформы Java;

invokestatic java.lang.Double::parseDouble(java.lang.String):double;

dstore 5;

getstatic java.lang.System::out:java.io.PrintStream;

dload 5;

dload_2;

dadd;

invokevirtual java.io.PrintStream::println(double):void;

l_114:

goto l_127;

l_117:

astore 4;

getstatic java.lang.System::out:java.io.PrintStream;

ldc string "Error";

invokevirtual java.io Ассемблер для платформы Java.PrintStream::println(java.lang.String):void;

l_127:

return;

protected_blocks;

java.io.IOException l_75 : l_114 > l_117;

end;

%-------------------------------------------------------------%

Данная программка функционально эквивалентна последующему коду на Java (ассемблерный вариант сотворен на базе дизассемблированной при помощи утилиты javap Java-программы):

//-----------------------------------------------------------//

public interface Figure {

double getArea();

}

//-----------------------------------------------------------//

//-----------------------------------------------------------//

public class Circle implements Figure {

private double Ассемблер для платформы Java m_radius;

public Circle(double radius) {

if(radius<0)

throw new IllegalArgumentException();

m_radius = radius;

}

public double getArea() {

return m_radius*m_radius*Math.PI;

}

}

//-----------------------------------------------------------//

//-----------------------------------------------------------//

public class Rectangle implements Figure {

private double m_a;

private double m_b;

public Rectangle(double a, double b) {

if(!((a>=0)&&(b>=0)))

throw new IllegalArgumentException();

m Ассемблер для платформы Java_a = a;

m_b = b;

}

public double getArea() {

return m_a*m_b;

}

}

//-----------------------------------------------------------//

//-----------------------------------------------------------//

public class Square extends Rectangle {

public Square(double a) {

super(a, a);

}

}

//-----------------------------------------------------------//

//-----------------------------------------------------------//

import java.io.*;

public class MainClass {

public static void main(String[] args) {

Figure[] figures = new Figure[3];

figures[0] = new Circle(10);

figures[1] = new Rectangle(1, 2);

figures[2] = new Square(3);

double Ассемблер для платформы Java sum = 0;

for(int i = 0; i

sum += figures[i].getArea();

try{

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

double d = Double.parseDouble(br.readLine());

System.out.println(d+sum);

} catch(IOException exc) {

System.out.println("Error!");

}

}

}

//-----------------------------------------------------------//

Проектирование и реализация компилятора. Для реализации компилятора был применен Ассемблер для платформы Java язык программирования Java (JDK версии 1.5). Это позволяет запускать данный компилятор на хоть какой платформе, для которой существует виртуальная машина Java v 1.5. При каждом запуске компилятора обрабатывается один файл начального текста на языке ассемблера для платформы Java. Компилятор воспринимает два аргумента командной строчки: название файла начального текста и имя создаваемого файла класса Ассемблер для платформы Java (очевидное указание расширения .class непременно). В случае, если выходной файл уже существует, он перезаписывается без предупреждения. В случае синтаксической либо другой ошибки на консоль выводится соответственное сообщение. Можно выделить несколько главных шагов компиляции (проходов): · Чтение начального файла. При всем этом он разбивается на предложения, разбитые точками с запятыми, также Ассемблер для платформы Java выбрасываются комменты; · Разбор начального текста. При поочередном переборе перечня предложений выделяются синтаксические конструкции. При разборе употребляется лексический анализатор, разделяющий предложения на лексемы. На основании выделенных синтаксических конструкций генерируется внутреннее представление программки, имеющее вид древовидной структуры данных, корнем которой является представление класса в целом, узлами первого уровня - объекты, надлежащие способам Ассемблер для платформы Java, полям, элементам Constant Pool и т. д.; · Подмена номеров меток надлежащими смещениями в коде способов; · Генерация байт-кода способов как массивов б; · Генерация файла класса на основании внутреннего представления программки. Данное деление является условным и не значит серьезной временной последовательности. 3-ий и 4-ый этапы, на самом деле Ассемблер для платформы Java дела, являются частями второго шага. Диаграмма пакетов проекта изображена на рис. 1. Рис. 1. Диаграмма пакетов Корневой пакет проекта имеет имя jasm. Он содержит класс MainClass, способ main() которого является точкой входа в программку, и классы SyntaxErrorException и InternalCompilerErrorException, унаследованные от java.lang.Exception и представляющие ошибки, которые могут появиться в Ассемблер для платформы Java процессе компиляции. Пакет compiler содержит классы, ответственные за разбор начального текста, при этом классы, работающие с кодом способов, содержатся во вложенном пакете code_compiler. Пакет structures содержит классы, из объектов которых состоит внутреннее промежуточное представление программки, также некие вспомогательные классы. Он имеет три вложенных пакета: commands, consts и attributes, классы Ассемблер для платформы Java из которых обрисовывают, соответственно, команды байт-кода, элементы Constant Pool и атрибуты полей и способов. В пакет commands в свою очередь вложены пакет command_formats, содержащий базисные абстрактные классы для команд обычных форматов, пакеты, содержащие классы, представляющие команды каждого из обычных форматов, также пакет special для классов, представляющих команды, имеющие Ассемблер для платформы Java особенный формат. Большая часть классов из пакета structures входят в иерархию, корнем которой является интерфейс IStructure, содержащий два способа int getLength() и byte[] getContent(), дозволяющие получить, соответственно, размер, который займет структура при записи в выходной файл, и массив б, которыми она представляется в выходном файле. Данный интерфейс не употребляется Ассемблер для платформы Java для полиморфного вызова способов, он играет только роль структурирования программки. Главные классы пакета structures изображены на диаграмме на рис. 2. Рис. 2. Классы пакета jasm.structures. Генерируемый класс как целое представляется объектом класса ClassFile, который содержит в собственных полях ссылки на объекты классов ConstantPool, FiledInfo и MethodInfo, описывающие область констант, поля Ассемблер для платформы Java и способы создаваемого класса. Сам класс ClassFile интерфейс IStructure не реализует. Посреди его членов необходимо подчеркнуть способ writeToFile(), создающий файл класса на основании инфы, содержащейся в объекте. Данный компилятор может создавать атрибуты способов Code, Exceptions и атрибут поля ConstantValue, которые представляются классами, производными от AttributeStructure. Отмечу, что объект Ассемблер для платформы Java класса CodeAttribute содержит байт-код способа уже в виде массива б, а не в виде объектов классов, представляющих отдельные команды (производных от Command), списки таких объектов употребляются только в процессе обработки кода способа. Абстрактный класс Command дополнительно к способам интерфейса IStructure содержит абстрактный способ byte getByte(int n), который Ассемблер для платформы Java должен возвращать б с данным номером в команде. Очередной способ changeOffset имеет пустую реализацию, но переопределяется в классах-потомках, соответственных командам перехода. Он употребляется для подмены номеров меток смещениями на 3-ем шаге компиляции. Конкретными наследниками класса Command являются классы, надлежащие обычным форматам команд (абстрактные) и командам, имеющим уникальные форматы. Большая Ассемблер для платформы Java часть команд представляются классами, наследующими классы обычных форматов. Имена классов команд имеют вид C_xxx, где xxx - мнемоническое имя команды. Пустой команде none соответствует класс NoCommand. Класс ConstantPool содержит как общий перечень для всех типов констант, хранящий объекты класса CpInfo (базисный тип для классов, представляющих разные виды констант), так и Ассемблер для платформы Java списки для констант отдельных типов, содержащие индексы частей в первом перечне. Эти списки описываются классами, вложенными в класс ConstantPool. Такая структура употребляется для того, чтоб при добавлении константы можно было стремительно проверить, не находится ли уже схожий элемент в ConstantPool (эта проверка делается не для всех типов констант Ассемблер для платформы Java). Для каждого типа констант в классе ConstantPool существует собственный способ прибавления, который возвращает индекс добавленного (либо отысканного имеющегося) элемента в общем перечне. Посреди наследников CpInfo имеется особый класс CpNone, который соответствует пустой структуре, вставляемой после констант типа Long и Double т. к. последующий за ними индекс считается неиспользуемым. За процесс Ассемблер для платформы Java компиляции отвечает пакет compiler, который содержит последующие классы: · Source - делает функцию выделения предложений в начальном тексте. Конструктор этого класса воспринимает в качестве параметра название файла, содержимое которого разбивается на предложения и заносится в коллекцию типа ArrayList. Способ String nextStatement() при каждом вызове возвращает еще одно предложение; · StringParser - делает Ассемблер для платформы Java функцию разделения строк на лексемы. Каждый объект этого класса соответствует одной обрабатываемой строке. · TokenRecognizer - имеет статические способы, дозволяющие найти, является ли некая строчка главным словом либо корректным идентификатором. Объекты этого класса никогда не создаются; · DescriptorCreator - содержит статические способы для сотворения дескрипторов типов, полей и способов из строк, содержащих запись типов Ассемблер для платформы Java и сигнатур, применяемую в языке. Экземпляры класса также не создаются; · ClassHeaderParser, FieldDeclarationParser, MethodHeaderParser - применяются при анализе заголовка класса, описаний полей и заголовков способов. Объекты этих классов сохраняют внутри себя информацию, извлеченную из анализируемого в конструкторе класса предложения; · code_compiler.CodeCompiler - производит анализ кода способа и генерацию байт Ассемблер для платформы Java-кода (включая 3-ий и 4-ый этапы компиляции). Данный процесс подвергнется рассмотрению подробнее ниже; · code_compiler.CommandCompiler - анализирует команды в начальном коде способа и делает объекты классов-потомков Command; · code_compiler.Label - представляет метку в коде способа; · code_compiler.LabelTable - таблица меток способа. Содержит имена меток, номера соответственных им строк и смещения Ассемблер для платформы Java команд. · SourceAnalyser - занимает центральное место в процессе анализа начального текста. Конструктор данного класса воспринимает в качестве параметра объект класса Source. При вызове способа analyse() происходит анализ начального кода и генерируется промежуточное представление программки в виде описанной чуть повыше структуры. В процессе анализа употребляются классы StringParser, ClassHeaderParser, FieldDeclarationParser Ассемблер для платформы Java, MethodHeaderParser, CodeCompiler и др. Данный способ возвращает объект класса ClassFile. Класс MainClass содержит единственный способ main, являющийся точкой входа в программку. Тут сначала создается объект класса Source, который передается для обработки объекту класса SourceAnalyser, потом у возвращенного способом SourceAnalyser.analyse() объекта класса ClassFile вызывается способ writeToFile, который и генерирует файл Ассемблер для платформы Java класса, являющийся результатом работы компилятора. Все перечисленные операции заключены в блок try/catch, перехватывающий любые исключения, в случае появления которых на консоль выводится соответственное сообщение и процесс компиляции заканчивается. Диаграмма, в облегченном виде показывающая этот процесс, изображена на рис. 3. Рис. 3. Обработка начального файла. Разглядим подробнее процесс компиляции кода способа Ассемблер для платформы Java. После обработки заголовка способа при помощи класса MethodHeaderParser, в случае, если способ не является абстрактным, в способе SourceAnalyser .analyse() считываются предложения maxstack и maxlocals. Потом считываются и заносятся в массивы предложения, содержащие команды и описания защищенных блоков. Эти массивы, также ссылка на объект ConstantPool, представляющий область констант класса, передаются Ассемблер для платформы Java в качестве характеристик конструктору класса CodeCompiler. У сделанного объекта CodeCompiler вызывается способ compile(), ворачивающий объект класса CodeAttribute, описывающий атрибут Code, содержащий байт-код способа. При всем этом происходят последующие процессы. В конструкторе класса CodeCompiler из строк, содержащих команды, выделяются имена меток, которые сохраняются в объекте класса LabelTable. Потом Ассемблер для платформы Java обрабатывается перечень строк, описывающих защищенные блоки. В способе CodeCompiler.compile() производятся последующие операции. Поначалу при помощи объекта класса CommandCompiler для каждой команды создается объект соответственного класса. При всем этом сразу для команд, при которых имеется метка, в объекте LabelTable сохраняется информация о смещении метки относительно начала способа. Как в Ассемблер для платформы Java описаниях защищенных блоков, так и в объектах, соответственных командам перехода, на момент окончания этого шага заместо смещений перехода, содержатся порядковые номера команд, при которых размещены надлежащие метки. Подмена их на действительные смещения делается на последнем шаге при помощи способов LabelTable.changePC() и Command.changeOffset(). Заключение. Разработка Java нацелена на внедрение 1-го Ассемблер для платформы Java языка программирования. Система типов данных и другие особенности языка Java плотно сплетены с функционированием JVM и форматом файла класса. Но, существует открытая спецификация, дозволяющие создавать как собственные реализации JVM, так и другие средства разработки. С ее внедрением мною разработан язык JASM, представляющий из себя язык ассемблера Ассемблер для платформы Java для платформы Java, который позволяет создавать файлы классов, использующие значительную часть способностей JVM, и реализован его компилятор. Использованная литература. 1. Грис, Д. Конструирование компиляторов для цифровых вычислительных машин. М., «Мир», 1975. 2. Эккель, Б. Философия JAVA. СПб. 3-е изд.: Питер, 2003. 3. Tim Lindholm, Frank Yellin. The Java Virtual Machine Specification Second Edition. Sun Microsystems Ассемблер для платформы Java Inc. 1999.

1, 2


assortiment-i-ocenka-kachestva-ikri.html
assortiment-i-tehnologiya-izgotovleniya-blyud-iz-ribi.html
assortiment-kulinarnoj-produkcii.html