Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
Ответ: создание MIDletPascal compiler'a
Вчера в спешке откомпилил и скинул старую версию дизассемблера, вот последняя.
Исправленны некоторые ошибки, возникающие при разборе определенных классов.
Для удобства дизассемблирования можно применить bat-файл, он преобразует длинные пути и имена с пробелами и длинными расширениями в короткие-dos.
Использование: выделить мышкой группу "*.class" файлов (до 255 шт.) и перетащить на этот батник или его ярлык. bat-файл должен находиться в каталоге с программой jd.exe.
также можно поставить настройку на "*.class" файлы "Открыть с помощью" и указываем этот bat.
____
jdisasm.bat
echo off
set prog=%~dp0jd.exe
:n1
if -%1==- goto :n2
echo %~sf1
%prog% %~sf1 > "%~dpn1.txt"
shift
goto :n1
:n2
pause
___
В случае замены константы можно поступить способом как предлогал в самом начале:
-Т.е. берем и делим бинарный *.class-файл, в месте где у нас находиться необходимая константа.
-Должно получится два кусочка: до константы и после константы.
-В проге генерируем серединку (строку-массив) и сохраняем в файл.
-И завершении склеиваем все три файла: НАЧАЛО + НАШ_КУСОЧЕК + ОСТАЛЬНАЯ_ЧАСТЬ
___
Народ! половина работы почти сделана, теперь нужно доработать java-assembler. и сделать генератор-конвертировщик с языка Pascal в asm-текстовый-исходник предоставленного формата.
Написанный ассемблер позволяет размещать структурные единицы в произвольных местах, но желательно придерживаться предложенного формата:
объявление классов
объявление имен_и_типов
прочие переменные
интерфейсы
поля
методы
___
p.s.: не откажусь от помощи, т.к. мало времени и много дел...
просьба админам добавить default-пользователя с которого можно было-бы скачивать выложенные архивы и резместить имя и логин на страничке скачивания
Сообщений: 99
Написано 18 полезных сообщений (для 28 пользователей)
Re: создание MIDletPascal compiler'a
Народ! половина работы почти сделана, теперь нужно доработать java-assembler. и сделать генератор-конвертировщик с языка Pascal в asm-текстовый-исходник предоставленного формата.
Написанный ассемблер позволяет размещать структурные единицы в произвольных местах, но желательно придерживаться предложенного формата:
объявление классов
объявление имен_и_типов
прочие переменные
интерфейсы
поля
методы
А я чем занимаюсь??? Сижу и пишу парсер (с оптимизом минимальным)
как ток допишу, останецо токма разобрать структуры и контекстный пул заполнить!!!
ЗЫ...
Экзешник - исполняемый файл для Windows( типа Notepad.exe )
вот файл, написан коряво, так как надо было общюю суть передать, но работает и компилит вроде...
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
Ответ: создание MIDletPascal compiler'a
Ггггг... Я так и подумал... Только вот какое он имеет отношение к Java? Я для компа никогда ничего не писал. Я Java-то толком не знаю. =) Как он мне поможет?
Сообщений: 99
Написано 18 полезных сообщений (для 28 пользователей)
Re: создание MIDletPascal compiler'a
Поможет разобраться как делать файл по его описанию...
Тоесть берёте описание Class файла и с помощью php собираете его в рабочий код,
почитайте с начала темы, и поймете, что это не так уж и трудно, по смещению (не по адресу) который виден в редакторах, а по смещению от этих адресов, находить и модифицировать код какой вам нужен.
В примере создаётся файл при запуске которого вылетает ОКНО СООБЩЕНИЯ (вроде Hello Word) откройте его HEX редактором и сравните с кодом на PHP как происходит процесс записи байтов в файл, так же там комменты для того, что бы знать для чего те или иные байты в файле служат...
Ну и т.д....
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
Ответ: создание MIDletPascal compiler'a
Спасибо, поковыряю. Но мне ведь не надо писать компилятор или ассемблер. Мне вообще минимум надо реализовать. Хотя... Если азарт возьмёт верх... Особенно если быстро въеду как это делается.
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
Ответ: создание MIDletPascal compiler'a
Доработал некоторые структуры - теперь полученный class-файл дизассемблируется и декомпилиться в NMI's Java Code Viewer 6.0, но WTK 2.5 отказывается его запускать... видимо где-то несоответствие типов, выложил в архиве последнюю версию java-assembler'a адаптированную для компиляции как в TurboPascal так и Delphi.
В архиве также оригинальный class-файл сделанный в WTK 2.5,
и компилированный в нашем ассемблере...
___
satan сравни-ка, теперь нужно немножко добрать, чтоб запускался...
в MidpX не пробуй, почему-то не работает даже оригинальны hello.class, хотя WTK-эмулятор запускает нормально
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
Ответ: создание MIDletPascal compiler'a
нужно создавать структуру StackMap_attribute в ней записываются типы переменных которые лежат в стеке и параметров метода. это записывается на стадии верификации (проверки) класса. кто-нить найдите подробное описание, похоже там структура переменного размера
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
Ответ: создание MIDletPascal compiler'a
нашел пару интересных сайтов по java-bytecode.
доработал java-bytecode assembler и java-bytecode disassembler.
теперь разбирают структуру StackMap_attribute,
также доработал вычисление размера стека max_stack для компилируемого метода.
грамотное описание формата класса и работы и ним на примере исходника, жаль не попадалось раньше.. тогда б несколько по иному спроектировал алгоритм java - ассемблера http://devdaily.com/java/jwarehouse/...sm/index.shtml
___
LearnJavaByExample.zip - сохраненные страницы с представленных сайтов
java_.zip - последнии версии java ассемблера/дизассемблера.
___
p.s. необходимо проверить работу алгоритмов и профиксить погрешности. сюда заглядывают java-програмисты?.. необходима помощь в тестировании
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
Ответ: создание MIDletPascal compiler'a
теперь немножко о формате asm-файла для компиляции.
Файл компилируется без каких либо проверок на корректность объявленных структур, синтаксиса описания команд - частично.
Первая строка файла - команда объявление текущего класса.
команды ассемблера:
class внутренне_имя_класса его_строковый_тип
nameandtype имя_переменной его_строковый_тип
другие_константы_(string, int и т.д.) внутренне_имя строка_или_число
interface строковое_имя_ранее_объявленнго_класса
field "указываем_атрибуты" имя_переменной_nameandtype
method "указываем_атрибуты" имя_метода его_строковый_тип
между блоками method ... endmethod указываются java-bytecode команды
и объявляются блоки localvariabletable stackmap, которые обнуляются при выходе из текушего метода командой endmethod
синтаксис описания bytecode можно получить дизассемблированием программой jd.exe любого class-файла
Сообщений: 99
Написано 18 полезных сообщений (для 28 пользователей)
Re: создание MIDletPascal compiler'a
Вобчем хоть убей я всеравно мысли не улавливаю...
Давай обьясню чо я мутю...
Итак, делаю 4 (пока) модуля
global.pas
scaner.pas
parser.pas
codegen.pas
В первом вынес все переменные и константы.
Второй отвечает за разбор исходного текста
Третий по разобраному лепит class файл
четвертый как раз функции генерации class файла.
Принцип следующий.
scaner.pas разбирает исходный текст на слова и возвращает нам
тип слова (оператор, переменная, функция...) парсеру,
парсер в зависимоста от типа вырабатывает вызов функции кодогенератора
который в свою очередь и лепит байт к байту в соответствии с правилами
построения class файла.
Пример
program HelloWord;
begin
writeln('HelloWord');
end.
Парсер запрашивает у сканера тип первого слова
Сканер возвращает program - > оператор - начало программы
Парсер проверяет что бы за этим оператором шло название программы
и точка с запятой, если ошибок не было, парсер делает следующий запрос...
И т.д. и т.п. рекурсивно. В итоге любой язык можно транслировать в другой,
не взирая на синтаксис программиста (переносы строк и т.д) и более того,
к компилятору можно прикрутить любой выходной файл, в принципе повторить
Турбо паскаль не сложно, или бэйсик или яву... Так как функции рекурсивны, то вызов их может быть выполнен из любой точки кода...
Допустим имеем код
a:= 22+ 12.3/45 - (a+b);
За операцию присваевания будет отвечать функция assignment()
за разбор выражения - expression();
В итоге у нас наше присваевание сведется к минимальному разбору
типа assignment( expression()); и рекурсия позволит учитывать приоритет
операций.
Просто у меня пока запарка с работой, а так я уже пишу помалень оптимизированый на этом уровне код, который из строки
a:= 2+3 -1/2 +(a*2-4);
сразу же просчитает все смысловые выражения и странслирует только
a:= 4.5 + (a*2 - 4);
дальше пока не иду....
Вот где самый затор - в оптимизации, остальное все просто дело техники...
А у тебя я поверь, не могу смысла уловить? На кой декомпилировать class файл и потом из этого что получилось опять лепить class файл???
Ты опиши хотя б в двух словах, что хоть на этапах построения или компиляции будет?
Типа вот так
Компилер рекурсивный
Исходный код на Pascal транслирует в JavaAsm
создаст контекстный пул исходя из записей таблиц переменных, функций
и констант, которые возникнут при работе парсера и сканера.
Для дальнейшего расширения, можно будет копировать сканер с анализом
Java синтаксиса и сделать транслятор Pascal - Java (для разработчиков библиотек
и Java кодеров) таким образом подключив всю яву...
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
Ответ: создание MIDletPascal compiler'a
эх, наверное скоро язык намозолю, ... задача pascal-компилятора подготовить текстовый javaAsm-исходник.
_________
"...А у тебя я поверь, не могу смысла уловить? На кой декомпилировать class файл и потом из этого что получилось опять лепить class файл???..."
- я думаю все поняли, мне например лень разбирать class-файлы в hex-редакторе, ну можно поковырять парочку, но сотню-другую ни за что...
дизассемблер нужен для разбора/экспериментов с class-файлами, чтоб лучше уяснить их структуру и возможные вариации. Поле деятельности огромное: бери любую игрушку и декомпиль,.. а потом смотри сможет ли асссемблер сделать также, если нет - смотри в чем ошибка алгоритма.
Возможные применения java-decompiler'a:
Если для компиляции простенькой библиотеки для MIDletPascal нужно писать кучу заглушек, то можно с помощью decompiler'а сделать заготовку, изменить ее и скомпилировать библиотеку.
Или же нужно изменить логику программы (подправить несколько байт в коде), то decompiler'ом можно пользоваться как инструментом анализа class-файлов.
_________
"...Ты опиши хотя б в двух словах, что хоть на этапах построения или компиляции будет?
Типа вот так
Компилер рекурсивный..."
-я думал это и так ясно, тем более что предложил переработать исходник <pascals.zip>, в который нужно немного изменить кодо-генератор для вывода java-bytecode команд, а также добавить структуру переменных/функций и их параметров под названием Constant Pool.
В предложенном исходнике уже создана оптимизация константных выражений (над которой ты сейчас работаешь), проверка типов при вычислении и многое другое, а также все необходимые структурные единицы языка Pascal.
_________
"...и сделать транслятор Pascal - Java (для разработчиков библиотек и Java кодеров) таким образом подключив всю яву..."
-как думаю уже стало ясно, то в данном паскале можно будет вызвать любой java-метод, даже тот которого нет и ни будет,.. поэтому нужно определить стандартные функции языка pascal и сопоставить им таблицу с аналогичными java-методами, чтоб проверялся тип параметров и при разборе синтаксиса.
а вообще поле TYPE будет заполнено в отдельном файле, а в программах в поле TYPE будет добавляться только какой-нибудь класс из нестандартного набора. Т.е. другими словами в этом отдельном файле будут находиться “стандартные” подпрограммы языка Pascal
-если очень нужен java исходник, то его можно получить и путем дизассемблирования готового class-файла с помощью программы NMI's Java Code Viewer 6.0.
Сейчас главное определиться с необходимым набором java-команд для pascal-компилятора. И созданием необходимых структур для оформления class-файла.
_________________________________
файл stackmap_works.zip - немного доки
файл JD_.ZIP - декомпилер для экспериментов..
Опять загвоздка с разбором StackMap
его структура такова:
StackMap_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 number_of_entries;
{
u2 byte_code_offset;
u2 number_of_locals;
ty types_of_locals[number_of_locals];
u2 number_of_stack_items;
ty stack_item_types[number_of_stack_items];
} entries[number_of_entries];
}
где ty -как я понял, это записи Constant Pool
в предыдущей версии было сделано распознавание только структуры ConstantPool_Class,
а вообще нужно сделать так:
....
else if s='{utf8}StackMap' then
begin
writeln(hex4(rc),'h StackMap');
p:=get(p,2);
pNumber_of_entries := swap2(p);
writeln(' number_of_entries:',pNumber_of_entries^);
for n := 1 to pNumber_of_entries^ do
begin
writeln(hex4(rc),'h entries:',n,'__');
p:=get(p,2);
pByte_code_offset:=swap2(p);
p:=get(p,2);
pNumber_of_locals:=swap2(p);
writeln(' byte_code_offset: ',pByte_code_offset^);
writeln(' number_of_locals:[',pNumber_of_locals^,']=');
for k := 1 to pNumber_of_locals^ do
begin
write(hex4(rc-1),'h ',k:3,' ');
load_const;
end;
p:=get(p,2);
pNumber_of_stack_items:=swap2(p);
writeln(' number_of_stack_items:[',pNumber_of_stack_items^,']=');
for k := 1 to pNumber_of_stack_items^ do
begin
write(hex4(rc-1),'h ',k:3,' ');
load_const;{}
end;
end;
end
....
и вот тут заковырка неправильно разбирается тип ConstantPool_Utf8
вроде так выглядит кодирование/декодирование-в utf8
function decodeutf8 : word;
var
w : word
n : integer;
begin
w:=getbyte;
if w>127 then
begin
if (w and $80)=$00 then n:=1;
if (w and $E0)=$C0 then n:=2
if (w and $F0)=$E0 then n:=3;
w := (w and $1F);
while (n>1) do
beign
w:=(w shl 6)+(getbyte and $3F);
dec(n);
end;
end;
decodeutf8:=w;
end;
putUTF8:
if (w >= 1 and w <= 177) then
begin
data[length] = byte(w);
inc(length);
end
else if (w > $07FF) then
begin
data[length] := byte($E0 or ((w shr 12) and $0F));
inc(length);
data[length] := byte($80 or ((w shr 6) and $3F));
inc(length);
data[length] := byte($80 or (w and $3F));
inc(length);
end
else
begin
data[length] := byte($C0 or ((w shr 6) and $1F));
inc(length);
data[length] := byte($80 or (w and $3F));
inc(length);
end;
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
Ответ: создание MIDletPascal compiler'a
Доработал java decompiler, разбирает почти все структуры, добавлен алгоритм декодирования utf8, распознавание stackMap и т.д.
Если какой-либо из работающих class-файлов будет декомпилироваться с ошибками, присылайте его в упакованном виде на почтовый ящик: [email protected] с темой сообшения "class file error"
для начальных экспериментов по генерации текстового asm-файла предлагаю посмотреть исходник http://exmortis.narod.ru/pcode_src/sc.zip на его базе можно создать пробную модель простого компилятора, а после экспериментов приступить к переработке pascals-компилятора.
Сообщений: 99
Написано 18 полезных сообщений (для 28 пользователей)
Re: создание MIDletPascal compiler'a
Ну наконец то подошли к компиляторам!!! Гы... Я поетому и молчал немножко!!!
На http://exmortis.narod.ru/ я изучил и скачал почти все компилеры (Интерес представляли тока пара 32 битных)
Советую изучить внимательно статьи и (кстати код вполне там рабочий если поправить пару строк кода) компилятор Inno Pascal - 32 бит с отладчиком по мойму и дебаггером и оптимизацией....
ЗЫ...
Кстати а линуксоиды чево не подключаются... FreePascal тож в исходниках идет!!!
Вот прикрепляю исходник базового компилятора для любого языка (кто какой потом кодоген сделает и сканер прикрутит)...
Реализована функция разбора выражений... наглядная пока, тоесть попросту калькулятор (оптимизация с шагом назад), потом мож прикручу полную с заглядыванием вперед.
Разбор выражений вида
Ну то есть ядро любого компилера, то есть вычисления, затем, если не будет вопросов
прикручу присваивание и формирование таблицы переменных и таблицы вызовов функций...
Далее булевы операции и управляющие конструкции типа for-next if-then-else ...
И останетцо самая малая часть - разбор прецедур-функций и типизация переменных...
Последний раз редактировалось satan, 07.11.2008 в 07:58.
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
Ответ: создание MIDletPascal compiler'a
Переработал простой компилятор http://exmortis.narod.ru/pcode_src/sc.zip для генерации простого текстового java-asm листинга. Который затем компилируется в class-файл.
_________
Принцип постороения программы:
имеется простой class-файл (prog.class) - эмулятор консоли, работая с методами которого созданный java-код выводит на экран: константный_текст, символ или число и получает числа с поля ввода.
Это минимально рабочий компилятор для создания java-class файлов.
Файлы созданные в полной версии должны работать без дополнительных библиотек и реализовывать все возможности java.
_________
В архиве имеется asm.bat при перетаскивании на который pascal'e-подобного исходника, (примеры: 1.txt; 2.txt; 3.txt; 4.txt) автоматически собирается файл *.cla, его переименовываем в jc.class и добавляем в архив prog.zip, который переименовываем в prog.jar и запускаем
_________
Порядок работы в ручном режиме:
compile.exe list < входной_файл_pas_листинга > выходной_asm_файл
параметр list говорит чтоб выводился только листинг, а программа не запускалась на внутреннем эмуляторе
jd.exe входной_class_файл.cla > выходной_дизассемблированный_файл_для_проверки
_________
Примечание:
компилятор не генерирует структуру StackMap, она необходима если в методе встречаются команды перехода, поэтому если программа не линейная (циклы,условия) - необходимо запистить утилиту preverify.exe которая проверит class-файл на корректность и добавит структуру StackMap.
В архиве также имеется bat-файл с параметрами вызова утилиты preverify.exe, если будете использовать то создайте структуру каталогов
c:\wtk25\bin\preverify.exe
c:\wtk25\lib\midpapi10.jar;
c:\wtk25\lib\cldcapi10.jar;
c:\wtk25\lib\midpapi10.jar;
c:\wtk25\lib\cldcapi10.jar
c:\wtk25\apps\prog\classes
c:\wtk25\apps\prog\tmpclasses
и положите в tmpclasses файл jc.class
Сообщений: 99
Написано 18 полезных сообщений (для 28 пользователей)
Re: создание MIDletPascal compiler'a
Воопче бросай хреновиной занимаца! Оч хорошо что народ разобрался со строением классов, но сейчас требуется копать не байт код компилеры, а в сторону оптимизации!
Для примеру закидываю перевод строки в ОПЗ (потому что тогда генерация в асм идет напрямую без всяких выпендрезов с рекурсией)
Во вторых прикрепляю наработку (считает тока целые... пока) но немного надо доточить напильником что бы полностью просчитывала строку.
Как только создадим оптимизатор, мля он станет КОНКУРЕНТНОСПОСОБНЫМ, и более того, потом паскаль просто тупо распарсим и в пул запихнем.
Вообще щас копаю модулу и компилер "странник", достал самокомпилируемые исходники и пробую перевести на паскаль с модулы...