titzer / virgil

A fast and lightweight native programming language
1.2k stars 42 forks source link

`System.puts` at compile time causes compilation to fail on native target (linux) compiler #107

Closed mosheduminer closed 1 year ago

mosheduminer commented 1 year ago

I was going through this part of the tutorial, and discovered what appears to be a bug in the native compiler (for linux). Running v3c-x86-linux Hello.v3 on a file with this code works:

component ComponentInit {
    var a: byte = init();
    def init() -> byte {
        return 'a';
    }
    def main() {
        System.puts("Running.\n");
    }
}

But crashes on this code:

component ComponentInit {
    var a: byte = init();
    def init() -> byte {
        System.puts("Initializing.\n");
        return 'a';
    }
    def main() {
        System.puts("Running.\n");
    }
}

But virgil compile Hello.v3 still works fine, although the native compiler crashes.

The stack trace is:

$ v3c-x86-linux Hello.v3
[Hello.v3 @ 1:11] ExceptionInInitialization: !EvalUnimplemented: PtrAtContents
        in NativeFileStream.puts() [/home/moshe/virgil/virgil/rt/native/NativeFileStream.v3 @ 29:43]
        in System.puts() [/home/moshe/virgil/virgil/rt/x86-linux/System.v3 @ 95:25]
        in ComponentInit.init() [Hello.v3 @ 4:20]
        in ComponentInit.new() [Hello.v3 @ 2:23]

This is after pulling the latest main (this commit for reference), and running aeneas bootstrap.

Let me know if you need any other information.

titzer commented 1 year ago

Thanks for the report. It's a poorly documented issue. Basically, some target constructs (like Pointer.atContents and Linux.syscall) are not available at compile-time, because the compiler may not even be running on the same target, i.e. cross-compiling. This program hits Pointer.atContents because it's running against the System implementation in rt/x86-64-linux.

I think someone else has hit this one in the tutorial before and I should probably fix the tutorial program. It only (accidentally) works with v3c-jar because of the way the compiler resolves the System component differs between native targets (where System is just code in rt/x86-linux) and the JVM (where System is a built-in).

mosheduminer commented 1 year ago

Makes sense, I suspected something like that would be the issue. So I guess it's just a documentation issue then.

It's useful in the tutorial though, because it demonstrates visually that some code is running at compile time. I think it would be best to leave a note that it is just for demonstration, and not to be relied upon outside the JVM.

titzer commented 1 year ago

I've updated the documentation, it should be a lot clearer now.