IF-Forum

» IF-Forum - Autorencafé - Schreiben! - Compiler-Probleme mit Infix
AntwortenNeues ThemaNeue Umfrage

Compiler-Probleme mit Infix

Geschrieben um 15:59 am 01.06.2006 | Zitat | Editieren | Löschen
ChristianB
Mitglied
Retired Gumby
Beiträge: 1062

Hallo, Inform-Profis,

ich möchte die Infix-Verben benutzen und habe sie mit !% -X nebst !% $MAX_LABELS=1500 eingebunden (der Default von 1000 war zu klein und der Compiler hat das auch entsprechend angemeckert und einen Vorschlag zur Abhilfe gegeben). Leider funktioniert Infix hier jetzt nur im Nicht-Strict-Mode, wenn der Strict-Mode aktiviert ist, dann bekomme ich folgende Fehlermeldung:

Inform 6.31:

<veneer routine 'RT__ChPrintO'>(1): Fatal Error: Branch out of range:

divide routine up?

Ich benutze den Compiler Inform 6.31, bei 6.30 gab es aber dasselbe Problem. Mein Quelltext ist zurzeit 119 K groß inklusive der eingebundenen Erweiterungen, dazu kommen noch die aktuellen deform-Libs. Woran kann es liegen, und wie komme ich trotzdem noch in den Genuss der Infix-Verben im Strict-Modus? Wer weiß es, wer weiß es?

Viele Grüße, CB

Geschrieben um 23:23 am 02.06.2006 | Zitat | Editieren | Löschen
Sophie
Mitglied
Bachelor Gumby
Beiträge: 61

Hi Christian,

Ich hab da keine Probleme. Ich hab es mit folgenden Switches versucht:


!% -XDSds

!% -v8

!% $MAX_VERBS=200

!% $MAX_LABELS=1200

!% $MAX_EXPRESSION_NODES=224

Meine Dateien haben insgesamt 384125 Bytes:


total 812

-rw-r--r--   1 monkey   apes     3901 Dec 12 23&#58;46 marray.h

-rw-rw-rw-   1 monkey   apes   317462 Jun  2 22&#58;49 inseln.inf

-rw-r--r--   1 monkey   apes    48086 May 28 00&#58;01 kapitel5.inf

-rw-r--r--   1 monkey   apes     7852 Jan  8 21&#58;05 phredoo.h

-rw-r--r--   1 monkey   apes     6824 May 28 20&#58;48 unterwasser.inf

Zu groß kanns also nicht sein.

Und die Compilerstatistik schaut aus wie folgt:


cp *.inf ../inseln_bak/

inform inseln.inf

Inform 6.31 for BeOS &#40;10th Feb 2006&#41;

In&#58; 13 source code files             17585 syntactic lines

 23186 textual lines                892522 characters &#40;ISO 8859-1 Latin1&#41;

Allocated&#58;

  1883 symbols &#40;maximum 6400&#41;     1075379 bytes of memory

Out&#58;   Version 8 "Extended" story file 1.060602 &#40;421K long&#41;&#58;

    18 classes &#40;maximum 64&#41;          316 objects &#40;maximum 511&#41;

   153 global vars &#40;maximum 233&#41;    4641 variable/array space &#40;maximum 10000&#41;

   159 verbs &#40;maximum 200&#41;          1151 dictionary entries &#40;maximum 1300&#41;

   584 grammar lines &#40;version 2&#41;    1489 grammar tokens &#40;unlimited&#41;

   158 actions &#40;maximum 200&#41;          32 attributes &#40;maximum 48&#41;

    56 common props &#40;maximum 62&#41;      58 individual props &#40;unlimited&#41;

291914 characters used in text    235876 bytes compressed &#40;rate 0.808&#41;

     0 abbreviations &#40;maximum 64&#41;    977 routines &#40;unlimited&#41;

 37974 instructions of Z-code      11528 sequence points

 41704 bytes readable memory used &#40;maximum 65536&#41;

430624 bytes used in Z-machine     93664 bytes free in Z-machine

Completed in 1 seconds

(Das ist ein bisschen unschön formatiert.)

Hast du es schon mit -v8 versucht? Obwohl man da eine andere Meldung kriegt, wenn v5 nicht mehr ausreicht. Kurz gesagt, keine Ahnung. ;-) (Übrigens hab ich normalerweise nur -X, und D und S nicht aktiviert, D ist automatisch dabei, und S weiß ich nicht.)

Geschrieben um 22:10 am 06.06.2006 | Zitat | Editieren | Löschen
ChristianB
Mitglied
Retired Gumby
Beiträge: 1062

Hallo, Sophie,

vielen Dank für deine Tipps. Ich habe alles durchprobiert und letzten Endes festgestellt, dass es nicht an den Switches liegt.

Denn wenn ich mindestens eines der Arrays CompoundHeads oder CompundTails verwende, dann gibt es die oben beschriebene Fehlermeldung. Mit dem Synonyms-Array funktioniert es. Aber schon ein einziger Eintrag in CompundHeads oder -Tails, z.B.



    "stahl"     0

    ;```

reicht aus, um den Compiler in Hinblick auf Infix im Strict-Mode zu verwirren. Ist doch seltsam.

Grüße, CB
Geschrieben um 08:26 am 07.06.2006 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

ChristianB:

Ist doch seltsam.

Allerdings. An der Definition des Feldes kann es nicht liegen, denn obwohl die Compound-Felder Mischfelder (d.h. Felder mit gemischten Datentypen) sind, sind sie doch für Inform ein ganz normales Feld.

Je nachdem, ob die Compound-Felder definiert sind oder nicht, wird allerdings Code kompiliert oder nicht, das passiert mit #ifdefs in German.h.

Die RT__-Routinen gehören zur Runtime Veneer*. Das sind unsichtbare Routinen, die im strikten Modus zusätzliche Abfragen einbauen um zu verhindern, dass die z-Maschine abstürzt. Die Zeile


     x = 2 / y;

würde also im strikten Mosus nicht in die z-Code-Anweisung


    @div 2 x -> x;

übersetzt, sondern in eine Runtime-Routine, die dann etwa so aussehen könnte:


    &#91; RT__Divide x y;

        if &#40;y == 0&#41; &#123;

            print "&#91;*** Programming Error&#58;

                Division by Zero. ***&#93;^";

            return 0;

        &#125;

        @div x / y -> sp;

        @ret_popped;

    &#93;;

In dieser Routine wird also überprüft, ob der Nenner Null ist. Im strikten Modus kommt dann der Programmfehler, das Programm läuft dann aber weiter. Im laxen (oder wie der nicht-strikte Modus heißt) Modus würde es einen Laufzeitfehler in der z-Maschine geben, der zum Abruch des Spiels führt.

Neben arithmetischen Funktionen @div und @mod wird beim Feldzugriff mit -> und --> und bei Routinen für Objekte mit Runtime-Veneer-Routinen gearbeitet. Bei den Anweisungen für Objekte ist es meist illegal nothing anstelle eines Objekts zu übergeben, weil, wie das DM4 nicht müde wird zu betonen, nothing kein Objekt ist. (Was ein bisschen blöd ist. Wieso kann ich zum Beispiel nicht "move apple to nothing" sagen, sondern muss "remove apple" benutzen?)

Die Routine RT__ChPrintO() wird bei der Ausgabe des Objektnamens mit (object) verwendet. Diese Printing Rule gibt den String aus, der im Kopf eines Objekts als Name definiert wurde.

Eigenartigerweise wird diese Regel innerhalb der Compound-#ifdefs nicht benutzt, und sie kommt auch woanders vor, zum Beispiel in PSN__ (Print Short Name). Auch kann ich nicht erkennen, dass in den Compound-Blöcken irgend eine anderes Feature verwendet wird, das woanders nicht vorkommt.

Meine Vermutung ist nämlich: Durch das Einbinden von CompoundHeads bzw. -Tails wird irgendeine Runtime-Routine definiert, die dann das ganze Runtime-System durcheinanderbringt. In einem Programm, in dem "(object) x" nicht vorkommt, muss auch keine Routine RT__ChPrintO im Runtime Veneer definiert werden, genauso für jedes andere Feature.

Die einzige Syntax, bei der ich mir vorstellen kann, dass innerhalb der Compound-Blöcke RT-Routinen erzeugt werden, sind die Lesezugriffe auf das Feld mit -->. Aber das ist nicht Neuses, denn dass wird bereits an x Stellen getan, auch für tables. (Ich kann mir denken, dass tables, strings, ->, --> und Buffer verschiedene RT-Routinen haben.)

Routinen, die aus dem Block heraus aufgerufen werden, wie LTI_Insert oder Tokenise__ können eigentlich nichts damit zu tun haben, denn sie wurden ja bereits erfolgreich definiert.

Dass es bei den Synonymen keinen Unterschied macht, liegt daran, dass der Synonymcode in jedem Fall erzeugt wird, da es bereits vordefinierte Synonyme gibt ("ins", "am" usw.).

Okay, viel geschrieben, nichts erreicht. Aber vielleicht gibt dir das ja einen Hinweis. (Wenn du möchtest, kannst du einmal Compound-Heads definieren und Stück für Stück Zeilen aus dem Block #ifdef CompoundHeads auskommentieren. Vielleicht bringt uns das weiter.)

Geschrieben um 12:50 am 08.06.2006 | Zitat | Editieren | Löschen
ChristianB
Mitglied
Retired Gumby
Beiträge: 1062

Martin, vielen Dank. Mit den die CompoundHeads- und –Tails betreffenden #Ifdef-Blöcken in German.h scheint es nicht unmittelbar etwas zu tun zu haben. Ich habe dann meinen Code nach und nach verkleinert und irgendwann war ein Punkt erreicht, an dem alles wieder normal funktionierte. Es spielte dabei keine Rolle, welche Art Code man herausnimmt, Objekte, Routinen, Verben etc., es scheint lediglich um die Datenmenge zu gehen (im Quelltext oder in der vom Compiler erzeugten Datei?). Wenn sich der Code gerade mal so eben mit Infix im Strict Mode compilieren lässt, dann ist die erzeugte Spieldatei 196 KB groß, also verdächtig nah an 200. Ist das vielleicht ein Limit für oder von irgendetwas, das auch in v8 noch gilt?

Geschrieben um 14:58 am 08.06.2006 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

ChristianB:

Ich habe dann meinen Code nach und nach verkleinert und irgendwann war ein Punkt erreicht, an dem alles wieder normal funktionierte. Es spielte dabei keine Rolle, welche Art Code man herausnimmt, Objekte, Routinen, Verben etc., es scheint lediglich um die Datenmenge zu gehen (im Quelltext oder in der vom Compiler erzeugten Datei?) Hmmm. Ich vermute, dass Infix für jede Datenstruktur im Programm (Objekt, Klasse, Feld, usw.) eigene Daten erzeugt, und so das Spiel einfach schneller wächst. Außerdem muss ja auch irgendwo noch der Parser für die Inform-Syntax hineinpassen. Und die Break- und Watchpoints für den Debugger.

ChristianB:

Wenn sich der Code gerade mal so eben mit Infix im Strict Mode compilieren lässt, dann ist die erzeugte Spieldatei 196 KB groß, also verdächtig nah an 200. Ist das vielleicht ein Limit für oder von irgendetwas, das auch in v8 noch gilt? Nein. Das absolute Limit für v5 sind 256, für v8 512 Kilobyte. Was aber Probleme bereiten könnte, ist die Größes des dynamischen Speichers, also des Speichers, der mit Inform-Zahlen addressierbar ist, und der muss kleiner sein als 64 KB oder 65536 Bytes. In diesem Bereich sind alle Objektdefinitionen, globale Variablen, Felder und auch das Wörterbuch abgelegt.

Alles was nach dem dynamischen Speicher in der Spieldatei folgt, sind Routinen und Texte, die nicht direkt durch Inform-Zahlen referenziert werden. (Sondern durch 4 bzw. 8 mal eine Inform-Zahl. So ergeben sich die absoluten Limits von 4 64K (256, v5) und 8 64K (512K, v8). "Dynamischer Speicher" ist auch nicht das richtige Wort, denn ein Teil des mit 16-Bit-Zahlen adressierbaren Speichers ist statisch, wie zum Beispiel das Wörterbuch.)

Abschnitt 45 im DM2 beschreibt einige Strategien, um Daten aus dem dynamischen Speicherbereich auszulagern.

Du kannst einmal deine Kompilationen mit und ohne Infix mit der Option -z laufen lassen. Diese Option druckt dir eine Memory Map aus, die genau zeigt, welcher Bereich der Spieldatei - Objekte, Objekteigenschaften, Felddefinitionen, usw. - wieviel Speicher benötigt. Im direkten Vergleich müsste man doch sehen können, wo Infix draufschlägt. (Du solltest aber keine Angst vor Hexadezimalzahlen haben :-)

Einen Überblick über den Speicherhunger von Inform in verschiedenen Modi gibt es im Inform FAQ, eine Übersicht über die Debug-Optionen in InfLight.

Geschrieben um 19:34 am 08.06.2006 | Zitat | Editieren | Löschen
Sophie
Mitglied
Bachelor Gumby
Beiträge: 61

Ich hab einmal so zum Spaß versucht, den zitierten Code mit CompoundHeads in meine Datei einzufügen, aber wie ihr ja schon festgestellt habt, macht das keinen Unterschied.

An der Größe kann's wie gesagt wohl kaum liegen, denn meine Spieldatei ist über 400k groß.

Wegen limits, verwende -s, dann bekommst du so eine Statistik, wie ich sie oben zitiert habe, da kannst du auch sehen, wieviel readable memory verwendet wird. Aber ich nehme an, wenn das nicht ausreicht, wird der Compiler das wohl sagen.

Hast du schon versucht, nachdem du jetzt stückweise Code rausgenommen hast, ihn wieder stückweise reinzugeben? Oder ist es egal, was du dazugibst, und es funktioniert nicht mehr?

Geschrieben um 16:41 am 09.06.2006 | Zitat | Editieren | Löschen
ChristianB
Mitglied
Retired Gumby
Beiträge: 1062

Ich blick nicht mehr durch: es kommt doch darauf an, was ich aus dem Code herausnehme. Ich bin jetzt an einem Punkt angelangt, wo alles bestens funktioniert. Wenn ich auch nur eine kleine Mini-Routine hinzufüge, dann geht’s nicht mehr. Aber die Anzahl der Routinen ist doch unbegrenzt, wenn ich das richtig verstanden habe, oder nicht?

Hier mal die Statistik (vorsichtshalber in v8) von dem Zustand, wo noch alles in Butter ist.



&#91;Including EZDOORS&#93;

&#91;Including NEWLIB&#93;

&#91;Including LOCKSMITH&#93;

&#91;Including SMARTCANTGO&#93;

&#91;Including NEWVERBS&#93;

In&#58; 14 source code files             14936 syntactic lines

 18351 textual lines                622881 characters &#40;ISO 8859-1 Latin1&#41;

Allocated&#58;

  1706 symbols &#40;maximum 10000&#41;       1013003 bytes of memory

Out&#58;   Version 8 "Extended" story file 1.060609 &#40;241K long&#41;&#58;

    16 classes &#40;maximum 64&#41;            106 objects &#40;maximum 639&#41;

   158 global vars &#40;maximum 233&#41;      4500 variable/array space &#40;maximum 10000&#41;

   172 verbs &#40;maximum 200&#41;            1065 dictionary entries &#40;maximum 2000&#41;

   686 grammar lines &#40;version 2&#41;      1831 grammar tokens &#40;unlimited&#41;

   172 actions &#40;maximum 500&#41;            35 attributes &#40;maximum 48&#41;

    57 common props &#40;maximum 62&#41;        57 individual props &#40;unlimited&#41;

 89663 characters used in text       80992 bytes compressed &#40;rate 0.903&#41;

     0 abbreviations &#40;maximum 64&#41;      696 routines &#40;unlimited&#41;

 32738 instructions of Z-code         9321 sequence points

 32080 bytes readable memory used &#40;maximum 65536&#41;

246368 bytes used in Z-machine      277920 bytes free in Z-machine

Completed in 0 seconds```

So. Und wenn ich jetzt mal testhalber so etwas wie

```&#91; InformDoesntLikeMe;

    print_ret "Keiner hat mich lieb.";

&#93;;```

im Code hinzufüge, dann bringt das Informs Hormonhaushalt total durcheinander. Ich geb’s auf. Vielen Dank für Eure Mühe!
Geschrieben um 13:39 am 10.06.2006 | Zitat | Editieren | Löschen
Sophie
Mitglied
Bachelor Gumby
Beiträge: 61

Ja, die Anzahl der Routinen ist nicht nur unbegrenzt, du hast auch weniger als ich.

Ich glaub, die einzige Möglichkeit, herauszufinden, was nicht passt, ist, inform mit asm_trace_level = 4 zu kompilieren, und dann zu schauen, an welcher Routine es scheitert.

Wenn das bei dir nicht geht, kannst du mir gerne deinen Quellcode schicken, und ich könnte nachschauen.

Geschrieben um 14:00 am 10.06.2006 | Zitat | Editieren | Löschen
Sophie
Mitglied
Bachelor Gumby
Beiträge: 61

Ich seh grad, das geht auch mit 'inform -a' für asm_trace_level 1 und 'inform -t' für asm_trace_level 2, aber interessant wird's erst bei 4.

Geschrieben um 11:29 am 14.06.2006 | Zitat | Editieren | Löschen
ChristianB
Mitglied
Retired Gumby
Beiträge: 1062

Vor uns haben sich schon andere mit dieser seltsamen Fehlermeldung beschäftigt:

http://www.inform-fiction.org/patches/C63003.html

Der Lösungsvorschlag übersteigt allerdings meine momentanen Möglichkeiten.

Geschrieben um 11:47 am 14.06.2006 | Zitat | Editieren | Löschen
Sophie
Mitglied
Bachelor Gumby
Beiträge: 61

Ah, das ist gut zu wissen. Ich hab mir schon gedacht, dass das Problem ganz wo anders liegt, als es aussieht.

Jetzt musst du nur noch jemanden finden, der dir Inform mit dieser Änderung neu kompiliert, wenn du das selber nicht kannst. Ich hab leider nur so einen cygwin-Compiler. Ich glaub, da brauchst du cygwin für alles, was man mit dem kompiliert.

Geschrieben um 14:36 am 15.06.2006 | Zitat | Editieren | Löschen
ChristianB
Mitglied
Retired Gumby
Beiträge: 1062

Tja, mein C-Compiler und ich, wir haben uns schon lange nicht mehr sehr weit weg vom Hallo-Welt-Niveau bewegt, aber ich denke ich krieg das hin, jetzt nachdem ich mir den Patch genauer angesehen habe...

Nochmals ein großes Dankeschön.

Edit: Prima Patch! Jetzt funktioniert alles.

AntwortenNeues ThemaNeue Umfrage
Powered by Spam Board SVN © 2007 - 2021
Impressum / Datenschutz