Cześć!
Pół roku temu (z małym hakiem) zacząłem pisać maszynę wirtualną. Nie potrafi jeszcze tyle co maszyna Javy czy interpreter Pythona, ale coś już można w niej napisać (jest gotowy wrapper na libnotify więc można np. wysłać sobie powiadomienie na pulpit, a na kod źródłowy składa się między innymi ponad 1500 linii kodu testów napisanych w języku assemblera maszyny).
Z okazji wydania wersji 0.5.0 uznałem, że zapostuję na liście i poproszę brać hakerską o peer review. Thank you from the mountain za czas i każdy komentarz!
Krótki przegląd podstawowej funkcjonalności:
* programy są pisane w jeżyku assemblera maszyny i kompilowane do bytecodu przed wykonaniem, * instrukcje w maszynie operują na rejestrach (w przeciwieństwie do Javy czy Pythona, które operują stosem operandów), * maszyna obsługuje mechanizm throw/catch (można rzucać obiekty dowolnego typu, nie tylko wyjątki), * dostępne typy danych to int, boolean, float, string i vector, * dostępne są instrukcje warunkowe "jump" i "branch" oraz funkcje,
Z bardziej zaawansowanych rzeczy, maszyna wspiera programowanie funkcyjne (w źródłach umieściłem moduł, który implementuje trzy główne funkcje: "map", "apply" i "filter", oraz również przydatną "invoke"). Da się też tworzyć funkcje zagnieżdżone. Jeśli ktoś lubi takie rzeczy to wie, że to fajna sprawa; a jak ktoś nie lubi to szkoda ;-) Przy błędach i niezłapanych wyjątkach CPU wyświetli ładny stack trace, z informacjami wystarczającymi do uruchomienia debuggera z breakpointem na odpowiedniej instrukcji. Zaimplementowałem wsparcie dla kompilacji rozłącznej, linkowania statycznego i dynamicznego, oraz linkowania modułów zewnętrzych napisanych w C++.
Nie istnieje jeszcze możliwość tworzenia własnych typów danych, ale można symulować je za pomocą wektorów (z tego co wiem, w podobny sposób działa Lua). Nad utworzeniem systemu typów właśnie pracuję.
Nie chcę pchać na listę zbyt dużego maila. Jeśli jednak ktoś będzie chciał dowiedzieć się więcej, z przyjemnością rozwinę temat. Zainteresowanych mogę pokierować do kodu: https://github.com/marekjm/wudoovm i dokumentu PDF z dokumentacją: http://docs.viuavm.org/viua_virtual_machine.pdf
Marek Marecki
On Sat, 18 Jul 2015, Marek Marecki wrote:
Cześć!
Pół roku temu (z małym hakiem) zacząłem pisać maszynę wirtualną. Nie potrafi jeszcze tyle co maszyna Javy czy interpreter Pythona, ale coś już można w niej napisać (jest gotowy wrapper na libnotify więc można np. wysłać sobie powiadomienie na pulpit, a na kod źródłowy składa się między innymi ponad 1500 linii kodu testów napisanych w języku assemblera maszyny).
Masz ode mnie dwa trywialne pull requesty na mojej maszynie leżą cztery testy
https://gist.github.com/saper/c74f1e251c90bba40217
Swoją drogą - jest genialny rysunek Andrzeja Mleczki doskonale pasujący do nazwy Twojego projektu (o religii "wudu")
Może dogadaj się z autorem do wykorzystania w projekcie
~Saper
On 07/18/2015 08:56 PM, Marcin Cieslak wrote:
Masz ode mnie dwa trywialne pull requesty
Dzięki! Oba zmerdżowane.
na mojej maszynie leżą cztery testy
Również dzięki! Spojrzę co się może wykrzaczać.
Swoją drogą - jest genialny rysunek Andrzeja Mleczki doskonale pasujący do nazwy Twojego projektu (o religii "wudu")
Może dogadaj się z autorem do wykorzystania w projekcie
Pomysł fajny, ale nie do wykorzystania już :-/ Zmieniłem nazwę na Viua (zanglicyzowana nazwa słowiańskiej boginki). Lepiej brzmi (i pasuje do żeńskich nazw typu Lua i Java) niż nijakie "Wudoo". Dzięki za poświęcony czas!
On Sat, 18 Jul 2015, Marek Marecki wrote:
On 07/18/2015 08:56 PM, Marcin Cieslak wrote:
Masz ode mnie dwa trywialne pull requesty
Dzięki! Oba zmerdżowane.
na mojej maszynie leżą cztery testy
Również dzięki! Spojrzę co się może wykrzaczać.
Rozpisałem Ci to na dwa błędu na Githubie. Robisz m.in. coś nie tak w dektruktorze swojej maszyny wirtualnej.
Testy też mogłyby wykrywać core dump, tak przy okazji (nie wiedziałem, czy core powstał z jednego testu - okazało się, że każda z czterech awarii coś zrzuca).
Swoją drogą - jest genialny rysunek Andrzeja Mleczki doskonale pasujący do nazwy Twojego projektu (o religii "wudu")
Może dogadaj się z autorem do wykorzystania w projekcie
Pomysł fajny, ale nie do wykorzystania już :-/ Zmieniłem nazwę na Viua (zanglicyzowana nazwa słowiańskiej boginki). Lepiej brzmi (i pasuje do żeńskich nazw typu Lua i Java) niż nijakie "Wudoo".
Szkoda, ja do dziś nie wiem jak się po polsku odmienia Lua (d:Luji,c:Luje,b:Luję?:) czy może jak "Lła"?
Przy okazji pytanie, bo akurat siedzę teraz trochę w obsłudze wyjątków w C++ i w CoreCLR (open source .NET):
Jak rozwiązałeś problem "rozwijania stosu" - przywracania kontekstu miejsca, w którym łapiesz wyjątek?
~Marcin
On 07/19/2015 12:31 AM, Marcin Cieslak wrote:
Rozpisałem Ci to na dwa błędu na Githubie. Robisz m.in. coś nie tak w dektruktorze swojej maszyny wirtualnej.
Testy też mogłyby wykrywać core dump, tak przy okazji (nie wiedziałem, czy core powstał z jednego testu - okazało się, że każda z czterech awarii coś zrzuca).
Tego błędu nie mogę od dosyć dawna trafić. Na jedynym sprzęcie, na którym udało mi się go wywołać pojawia się "losowo", ale będę szukać dalej skoro ktoś jeszcze trafił. Czy przypadkiem nie uruchamiasz testów na i7? Myślałem kiedyś, że może to kwestia podwójnego zwalniania jakiejś pamięci, ale nie wydaje mi się. W planach mam napisanie areny pamięci (nie jestem pewien czy po polsku tak będzie "memory arena") i używanie "placement new" wszędzie. Wtedy będę mógł dokładnie prześledzić co i kiedy się alokuje, zwalnia itd. Może pomoże.
Szkoda, ja do dziś nie wiem jak się po polsku odmienia Lua (d:Luji,c:Luje,b:Luję?:) czy może jak "Lła"?
Ja po prostu nie odmieniam ;-) Podobnie jak IKEA.
Przy okazji pytanie, bo akurat siedzę teraz trochę w obsłudze wyjątków w C++ i w CoreCLR (open source .NET):
Jak rozwiązałeś problem "rozwijania stosu" - przywracania kontekstu miejsca, w którym łapiesz wyjątek?
~Marcin
Cwaniactwem. Maszyna ma tak naprawdę dwa stosy zamiast tylko jednego. Pierwszy jest zwykłym stosem wywołań funkcji, drugi stosem "wyłapywaczy".
Każdy wyłapywacz ma przypisaną ramkę ze stosu funkcji, oraz listę typów, które potrafi złapać. Kiedy rzucam wyjątek maszyna rejestruje go, i iteruje w górę stosu wyłapywaczy w poszukiwaniu wyłapywacza, który potrafi obsłużyć typ rzuconego obiektu (na tym etapie w ogóle nie ruszam stosu funkcji). Możliwe są dwa wyniki: albo jakiś wyłapywacz ma zarejestrowaną obsługę danego typu, albo skończy się stos wyłapywaczy.
Jeśli żaden wyłapywacz nie jest w stanie obsłużyć rzuconego obiektu następuje przerwanie działania programu. W takim wypadku nastąpi wygenerowanie informacji o fakcie, że nie udało się złapać rzuconego obiektu (informacja zawiera typ i wartość niewyłapanego obiektu, stack trace, stan rejestrów w ostatniej ramce oraz stan licznika instrukcji).
Jeśli któryś wyłapywacz jest w stanie obsłużyć rzucony obiekt, maszyna zaczyna modyfikować stos wywołań (można to zrobić, bo skoro wyjątek został obsłużony to istniejąca historia wywołań nie będzie potrzeba do wygenerowania stack trace). W tym celu CPU pobiera adres ramki na stosie wywołań dla której został zarejestrowany wyłapywacz, i tak długo usuwa ramki ze stosu, aż nie trafi na "tą jedyną". Kiedy już ją znajdzie, ustawia zestawy rejestów na znajdujące się w tej ramce i wznawia działanie od adresu instrukcji, pod którym znajduje się blok obsługujący dany typ wyjątku.