AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte RUTIS Engine (Scripting) [WinCE spinnt]
Thema durchsuchen
Ansicht
Themen-Optionen

RUTIS Engine (Scripting) [WinCE spinnt]

Ein Thema von olee · begonnen am 14. Jun 2009 · letzter Beitrag vom 20. Aug 2010
Antwort Antwort
Seite 11 von 11   « Erste     91011   
Benutzerbild von olee
olee
Registriert seit: 16. Feb 2008
DIES IST DIE ALTE VERSION VON RUTIS
Die neue Version gibts hier: RUTIS v2
----------------------------------------------

Hi,
Hier möchte ich euch eines meiner größten Projekte vorstellen.

RUTIS

Die "RunTime Script Engine" (RUTIS Engine) dient dazu, Scripte zur Laufzeit zu compilieren und auszuführen, um z.B. Die Funktionen von Programmen zu verändern, ohne diese neu zu compilieren.
Durch eine sehr hohe Geschwindigkeit lassen sich sogar ganze Programme allein mit einem solchen Script erstellen.
Die RUTIS Engine kann mehrere Compiler unterstützen wobei der Standardcompiler mit einem Delphi/Pascal Syntax arbeitet.

- - - HINWEIS: INFOS ETWAS VERALTET - WERDEN BEI GELEGENHEIT KORRIGIERT - - -
RUTIS bietet eine große Funktionsvielfalt:
  • Globale sowie lokale Variablen
  • Verschachtelbare Funktionen und Methoden, die auch rekursive Algorithmen lösen können.
  • Beliebige Deklaration von Records
  • Unterstützung von Pointern und Arrays
  • Einfache Verknüpfung von Hostprogramm und Script mittels speziellen, beliebig erstellbaren Verbindungsfunktionen.
  • NEU: Methode-Variablen (bisher jedoch nur parameterlose Prozeduren)
  • NEU: Formular Interface, wodurch sich ganze Anwendungen mit GUI erstellen lassen!
  • NEU: Aufruf von DLL-Funktionen über die deklaration im Script als 'external' ! (Hier ein DANKE an 'Astat')
  • uvm.
Das sollte vorerst an Informationen reichen.

RUTIS PROJEKTSEITE (Downloads, Infos usw.)
SVN-Portal: http://www.xp-dev.com/sc/77518


INFO : RUTIS unterliegt einer Creative Commons BY-NC-SA (DE) Lizenz
INFO 2: Die nachfolgenden Links könnten des öfteren nicht funktionieren, da sie nach jedem neuen Upload ungültig werden. Auf der Projektseite dagegen sollten
die Downloadlinks immer funktionieren. Ich entschuldige mich hier auch für eine solche Faulheit, die Links nur selten zu aktualisieren ^^
RUTIS Setup 1,04 MB RUTIS (zip) 1,28 MB RUTIS (Source) 2,08 MB


MFG
Codename: Performancepumpe

Geändert von olee (20. Mai 2011 um 04:50 Uhr)
 
Benutzerbild von olee
olee

 
Turbo Delphi für Win32
 
#101
  Alt 7. Mai 2010, 21:22
Genau dieses "misaligned data" hab ich auch als Fehler bekommen ab und zu...

Aber was soll man da dann nur machen....

Es scheint so als bleibt mir nichts anderes übrig, als alle Daten auzurichten...

Aber was mich wundert ist, das das Problem auch auf dem emulierten WinCe auftritt

Ich werde es weiterhin versuchen.

bisher hab ichs eh durch ausrichten der Daten soweit zum laufen gebracht.

Nur...
was mache ich dann mit packed records?????

Fragen über Fragen

MFG
Björn Zeutzheim
  Mit Zitat antworten Zitat
Namenloser

 
FreePascal / Lazarus
 
#102
  Alt 7. Mai 2010, 21:24
Zitat von olee:
1.) Ich hab doch gesagt wie das beim Stream läuft:
Es werden x Bytes von A nach B kopiert - also alle Bytes einzeln.
Das funktioniert auch bei meinem Stack ja problemlos.
Das heißt, solange du nur einzelne Bytes abrufst, funktioniert alles? Das deutet dann wohl darauf hin, dass für jeden Datentyp das "Raster" ein Vielfaches der Größe des Datentyps beträgt. [edit]okay, anscheinend ist es dich immer 32 bit, laut Poelsers Link)[/edit] Ich fürchte fast, gegen solche hardwareseitigen Einschränkungen wirst du nicht viel machen können. Entweder du kopierst die Bytes einzeln, oder du musst irgendwie dein Stackformat so verändern, dass es ins Raster passt. Ich würde es zunächst mal mit der ersten Variante probieren, um zu schauen wie schnell oder langsam es wirklich ist, bzw. ob es überhaupt einen nennenswerten Unterschied macht. [edit] Hast du es mal mit dem auf der verlinkten Seite beschriebenen unaligned-Keyword probiert?[/edit]
Zitat von olee:
2.) Wenn z.B. mehr Variablen angelegt werden oder eine Funktion sich sehr oft rekursiv aufruft, so muss der Stack vergrößert werden.
Und das passiert bei Speicherbereichen normalerweise über ein ReallocMem.
Lässt der Speicher sich aber an seinem aktuellen Speicherort nicht mehr weiter vergrößern, so muss der ja verschoben und sein inhalt kopiert werden. Das darf aber in RUTIS nicht passieren.
Das passiert bei Arrays aber auch. Würde es denn aber nicht reichen, einfach eine maximale Stackgröße festzulegen? Ist in "echt" doch auch so - deswegen gibt es ja auch einen Stacküberlauf, wenn du eine Funktion zu oft rekursiv aufrufst. Alternativ könntest du den Stack natürlich dynamisch in der Größe verändern, aber dann müsstest du bei jeder Größenänderung alle gespeicherten Adressen anpassen. Das gilt aber wie gesagt unabhängig davon, ob du die Speicherbereiche über Arrays, Streams oder sontwie alloziierst.
  Mit Zitat antworten Zitat
Benutzerbild von olee
olee

 
Turbo Delphi für Win32
 
#103
  Alt 7. Mai 2010, 22:00
Mein Stack hat eine halb-feste Größe.

Während der Ausführung reserviert meine Stack-Class Speicherblöcke mit einer
beim Erstellen des Stacks vorgegebenen Blockgröße.

Deswegen muss eine Adresse (als Pointer) auf eine Variable im Stack auch über die Array-Property
Data[<Stack-Adresse>] ausgewertet werden.
Diese Funktion prüft, auf welchem Stack-Block die gewünchte Adresse liegt
und gibt das entsprechende Ergebnis zurück.

Aber dieses unaligned_Keyword scheint genau das zu sein, was ich brauchte.

Ich werde dennoch (der Geschwindigkeit wegen) versuchen, die Variablen weitestgehend am Raster auszurichten.

Es stellt sich mir jetzt nur die Frage, was schneller ist:

Entweder immer mit unaligned auf die Werte zugreifen, oder vorher eine Prüfung durchführen, ob die Variable auf dem Raster liegt und dem entsprechend unaligned verwenden oder nicht.

Ich schätze aber 1. ist schneller, da unaligned bei schon ausgerichteten Werten wohl nix macht.

EDIT:
VERDAMMT ich glaubs nicht!
Das funktioniert so wirklich!!!!
VIELEN DANK das war eine große Hilfe!!

Ich werde nun mal sehen wie ich das auf die Reihe krige.
Am meisten Kopfschmerzen bereitet mir nun die Frage, wie ich das nutzen kann, ohne das sich das Projekt nicht mehr mit Borland-Delphi kompilieren lässt.
{$Ifdef WinCe} überall einzubauen wäre eine riesige Arbeit.
Vielleicht ließe sich ja sowas mit einer Funktion realisieren, die sich je nach WinCe oder nicht-WinCe unterscheidet.
Gibt es da nicht auch so was wie Inline-Funktionen, sodass ich das ganze nutzen kann, ohne eine Menge calls?
Leider kenne ich mich mit diesem inline nicht aus.

EDIT-2:
Mir ist gerade aufgefallen, das das doch einigermaßen geht:
Indem ich das so schreibe:
Delphi-Quellcode:
  {$ifdef WinCE}unaligned{$endif}(PCardinal(@Data[adr])^) := val;
  unaligned(PCardinal(@Data[adr])^) := val; //So sähe es mit WinCe aus -> lässt sich kompilieren
  (PCardinal(@Data[adr])^) := val; //So sähe es ohne WinCe aus -> die Klammern stören Delphi ja nicht
Das solle nicht dermaßen viel arbeit sein.

MFG und VIELEN DANK für die Hilfe (vor allem @Poelser)
Björn Zeutzheim
  Mit Zitat antworten Zitat
Benutzerbild von olee
olee

 
Turbo Delphi für Win32
 
#104
  Alt 7. Mai 2010, 22:23
Das ist aber sehr schade...

Delphi kommt mit meinem ganannten Beispiel dort nicht zurecht.

Wenn ich so etwas wie
(PCardinal(@Data[adr])^) := val; schreibe sagt der: "[Pascal Fehler]: E2064 Der linken Seite kann nichts zugewiesen werden"

Also bleibt mir da fast nur noch eine Variante mit dem inline oder ich muss das ganze dann so schreiben:

{$ifdef WinCE}unaligned({$endif}PCardinal(@Data[adr])^{$ifdef WinCE}){$endif} := val;

EDIT:
Gute Neuigkeiten!

Das mit der inline-Funktion funktioniert gut (zumindest beim auslesen von Werten):
Delphi-Quellcode:
function GetPCardinal(const Adr: PCardinal): Cardinal; inline;
begin
  {$ifdef WinCE}
  Result := unaligned(Adr^);
  {$else WinCE}
  Result := Adr^;
  {$endif}
end;

Function TRutisStack.PopCardinal : Cardinal;
Begin
  //So sah die alte Zeile aus:
  Result := PCardinal(Data[Top - 4])^;

  //Und so die neue
  Result := GetPCardinal(Data[Top - 4]); //Die neue Anweisung, die am ende dennoch die
                                          //gleichen Assembler-Befehle ergibt dank inline
  Pop(4);
End;
MFG
Björn Zeutzheim
  Mit Zitat antworten Zitat
mastaraymond
 
#105
  Alt 20. Aug 2010, 18:07
Hallo,

Meiner Deutsch ist nicht so gut, aber ich darf etwas fragen. Kannst du dieser patch anbringen?

grüße,

Raymond

Delphi-Quellcode:
Index: RUTIS_Classes.pas
===================================================================
--- RUTIS_Classes.pas   (revision 23)
+++ RUTIS_Classes.pas   (working copy)
@@ -134,6 +134,7 @@
     //================================================
     Property CompilerError : Boolean Read GetCompilerError;
     Property Error : ERutisCompilerError Read fCompilerError;
+   Property ScriptError : Boolean Read fScriptError
   End;
 
   TRutisCompiler = Class
@@ -1466,7 +1467,7 @@
 Begin
   Result := (Address < 0) or (Address > ScriptData.Stack.Top);
   If Result Then
- ScriptMessage('Address Error (Address ID = ' + IntToStr(Address) + ')');
+ ScriptMessage('Address Error (Address ID = ' + IntToStr(Address) + ')', etRuntimeError);
 End;
 
 Function TRutisEngineBase.GetStackLvlAddress(Address, Level : Integer) : Integer;
Index: Rutis_Engine.pas
===================================================================
--- Rutis_Engine.pas   (revision 23)
+++ Rutis_Engine.pas   (working copy)
@@ -308,7 +308,7 @@
   fLastAdress := Pointer(ScriptData.Stack.ReadCardinal(src));
   If GetExtAddrRange(fLastAdress) = -1 Then
   Begin
- ScriptMessage('Address Error');
+ ScriptMessage('Address Error', etRuntimeError);
     exit;
   End;
 
@@ -320,7 +320,7 @@
   fLastAdress := Pointer(ScriptData.Stack.ReadCardinal(ScriptData.Stack.Top - 4));
   If GetExtAddrRange(fLastAdress) = -1 Then
   Begin
- ScriptMessage('Address Error');
+ ScriptMessage('Address Error', etRuntimeError);
     exit;
   End;
 End;
@@ -1088,7 +1088,7 @@
 Begin
   If ScriptData.CurrCmd.P1 <= 0 Then
   Begin
- ScriptMessage('Error - OpEnumToSet');
+ ScriptMessage('Error - OpEnumToSet',etRuntimeError);
     exit;
   End;
   bit := ScriptData.Stack.PopByte;
@@ -1649,7 +1649,7 @@
     intDouble : Val2 := ScriptData.Stack.PopDouble;
     intExtended : Val2 := ScriptData.Stack.PopExtended;
   Else
- ScriptMessage('Comparison Error');
+ ScriptMessage('Comparison Error',etRuntimeError);
   End;
 
   Case TRutisIntType(ScriptData.CurrCmd.P2) Of
@@ -1669,7 +1669,7 @@
     intDouble : Val1 := ScriptData.Stack.PopDouble;
     intExtended : Val1 := ScriptData.Stack.PopExtended;
   Else
- ScriptMessage('Comparison Error');
+ ScriptMessage('Comparison Error',etRuntimeError);
   End;
 
   Case TOperatorCode(ScriptData.CurrCmd.P1) Of

Geändert von mkinzler (20. Aug 2010 um 18:14 Uhr) Grund: Code-Tag durch Delphi-Tag ersetzt
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 11 von 11   « Erste     91011   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:36 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz