rochus-keller / Oberon

Oberon parser, code model & browser, compiler and IDE with debugger, and an implementation of the Oberon+ programming language
GNU General Public License v2.0
464 stars 30 forks source link

Problem with code generation for nested procedures #54

Closed wrightsl closed 8 months ago

wrightsl commented 8 months ago

If there is any code in the CheckLiteral procedure it generates illegal IL code. TestScanner.txt

rochus-keller commented 8 months ago

Thanks for the report. I can reproduce the issue. I also noticed that if you use the declaration PROCEDURE (VAR scan:ScannerDesc) NextToken*(VAR sym: INTEGER); instead of PROCEDURE (scan:Scanner) NextToken*(VAR sym: INTEGER); the issue doesn't occur.

The non-local access concept seems to be confused by the receiver which is a special parameter. Let me check this.

rochus-keller commented 8 months ago

Meanwhile I was able to isolate and solve the issue.

It turned out to be an interesting problem, and surprisingly you are again the first to trigger it. In my code I usually declare receivers as var parameters, which might be an explanation. The exception was issued due to a speciality of the Mono engine, which apparently forbids to take the address of the "this" hidden parameter of a method (I didn't find any indication in the ISO 23271 standard that this should be not allowed). I implement non-local access by hidden additional VAR parameters; if you thus use the receiver in a local procedure, up to now the address of the receiver was fetched using the ldarga IL operator and passed as an (additional) argument, which triggered the Mono exception.

I now added additional conditions to assure that a pointer receiver is always passed as a value parameter, which avoids the Mono exception. At this occasion I also added a check to avoid assigning to a pointer receiver, or passing a pointer receiver to a var parameter, which also try to get the address of "this".

Your code doesn't crash anymore with these fixes, but I will run my test set now and then commit the fixes and later upload a new pre-compiled version for Linux x64.

rochus-keller commented 8 months ago

The commit is up: https://github.com/rochus-keller/Oberon/commit/7c1feb4d8908cb751d4b6fb640cfb05048e5f6bc and also the precompiled x64 Linux version: http://software.rochus-keller.ch/OberonIDE_linux_x86_64.tar.gz.

wrightsl commented 8 months ago

Thanks again for your quick response, it helps me a lot.