Spivoxity / obc-3

Oxford Oberon-2 compiler
38 stars 7 forks source link

Receive Internal compiler error: Can't pass VParam when #29

Closed ghost closed 4 years ago

ghost commented 4 years ago

Ubuntu 20.04 x64 using versions 3.1.1 and 3.2alpha :

Oxford Oberon-2 compiler driver version 3.1.1 [build unknown]
Oxford Oberon-2 compiler version 3.1.1 [build unknown]
Oxford Oberon-2 linker version 3.1.1 [build unknown]
Oxford Oberon-2 runtime system version 3.1.1 [build unknown] (JIT)
Oxford Oberon-2 library version 3.1.1 [build unknown]
Oxford Oberon-2 compiler driver version 3.2alpha [build git-1a8940cd851e]
Oxford Oberon-2 compiler version 3.2alpha [build git-1a8940cd851e]
Oxford Oberon-2 linker version 3.2alpha [build git-1a8940cd851e]
Oxford Oberon-2 runtime system version 3.2alpha [build git-1a8940cd851e] (JIT)
Oxford Oberon-2 library version 3.2alpha [build git-1a8940cd851e]

Attempting to compile the file linked to below errors on the specified line. See the full error message below.

https://github.com/octave-syndicate/obc-3-sockets/blob/b0a4d258d8c12fdce36144d15187c55e165bf48b/sockets.mod#L82

obc -c sockets.mod
"sockets.mod", line 3: warning -- SYSTEM is imported but never used
> IMPORT SYSTEM;
>        ^^^^^^

"sockets.mod", line 82: warning -- Bind is declared but not used or exported
>    PROCEDURE Bind(sockfd: LONGINT; VAR addr: SockAddr; addrlen: LONGINT):INTEGER IS "bind";
>              ^^^^
*** Oxford Oberon-2 compiler version 3.2alpha
*** Internal compiler error: Can't pass VParam
*** (This message should never be displayed: it may
***   indicate a bug in the Oberon compiler.
***   Please save your program as evidence and report
***   the error at 'https://bitbucket.org/Spivey/obc-3/issues'
***   or by e-mail to 'mike@cs.ox.ac.uk'.)
make: *** [Makefile:2: all] Error 1
Spivoxity commented 4 years ago

Dear R. Wise,

You are using the non-standard language extension that allows Oberon code to call primitives written in C. This is likely to be implemented and tested only as far as is needed to implement the standard library. In this case, you have fallen over the restriction that neither value nor VAR parameters of record type can be passed across the interface, simply because some easy code is missing from the compiler's code generator. If you are going to try making a socket library, then I will add the few things that are needed: are you content to compile OBC from github source for the purpose? If so, I'll make a feature branch from R3.1 for you.

We'll have to decide on the correspondence between Oberon and C semantics when records are passed. I suggest that for value parameters, the address of the record is passed, so the C routine will have a parameter declared with "struct foo *p". For VAR parameters of record type, Oberon normally passes both a record address and a descriptor to allow subtyping: for these, I suggest making only the record address accessible from C.

Some remarks (if I may) about your skeleton interface to sockets. The type INTEGER in OBC is always 32 bits, so it corresponds to int on all platforms of interest; LONGINT has 64 bits, and SHORTINT 16. So an appropriate heading for BIND will us INTEGER not LONGINT throughout. For network addresses, I suggest using the extensible record feature of Oberon to allow multiple subtypes of a common 'abstract' address type without the need for casting. I think that will fit in with the assumptions made by the standard sockets library.

Best wishes,

-- Mike

ghost commented 4 years ago

I do think your wonderful compiler deserves a socket library and am looking forward to the project. I've successfully compiled OBC from source.

Of course, please feel absolutely free to offer whatever remarks, suggestions, or critiques you are inclined to share. As a neophyte to Oberon programming I will defer to your decisions and try to keep everything conceptually aligned with your vision of how the final result should look.

(Just as a quick aside, it seems Ubuntu 20.04 Focal updated their version of libffi to 7. To overcome this blocker I downloaded the libffi6 library from the previous Xenial 19.10 release.)

Spivoxity commented 4 years ago

For rel-3.1.2, I added records to the types that can be passed to primitives, integrating with FFI. Value and VAR parameters have much the same effect from the C side: the actual paramter is the address of the record, but with the expectation in the case of a value parameter that the function will not alter the record, and will access only fields belonging to the parameter type, not to subtypes. For VAR parameters, only the record address is accessible to the C function, and not the descriptor that Oberon passes with the record. Nevertheless, VAR paremeters should be used to signal either that the function will modify the record, or that fields dynamic subtypes are accessed.

This enhancement is now available at the tip of the rel-3.1 branch; it should build with no warnings on Ubuntu 20.04 with libffi7.