0.3 Updates

Brian Rice water at tunes.org
Sun Jul 18 12:47:47 PDT 2004


On Jul 18, 2004, at 11:02 AM, Jaco van der Merwe wrote:

> Hi Brian
>
> I've posted the following response to the 0.3 alpha release to the 
> Slate
> mailing list from my yahoo account, jjnvdm at yahoo.co.uk. Note that this
> account is still awaiting subscription approval to the Slate mailing 
> list,
> so the message must first be approved by the moderator, but I thought 
> you
> may want to have a look at it before then. I use the yahoo account for
> posting to lists in order to avoid the evil of spam and keep this one 
> clean.
>
> Regards
> Jaco van der Merwe

Hello! I am not the moderator, but if it takes too long I can prod the 
administrator to approve you.

> I've been following the Slate project with great interest. With the 
> recent
> announcement of the 0.3 alpha release I downloaded all the sources. I 
> use
> mostly Windows XP as my OS, so I tried to compile and run Slate 0.3 
> alpha on
> Windows, albeit without success. Below I provide a summary of my 
> experiences
> and some of the issues I identified. I am not sure whether 
> cross-compiler,
> or even cross-platform capabilities are a focus of the Slate project, 
> but I
> would really like to be able to use Slate on Windows, and maybe later 
> on
> other platforms like QNX, or even handhelds. I would gladly assist in 
> making
> Slate compile and work on Windows using the Visual C++ compiler. 
> However, in
> order to do that I would have to understand the inner workings of the 
> VM
> better, and some differences between GCC and Visual C++ (as per my 
> questions
> below).

Excellent, thanks for the feedback here...

> My first attempt to compile and run Slate on Windows was by using 
> MINGW 3.2
> (as embedded in Dev-C++ 4.9.8.0). The sources compiled without 
> problems, but
> when I ran the executable it crashed soon after calling the
> PSInterpreter_interpret() function from the main() function in the file
> "boot.c". I still need to spend time to find out exactly where this 
> occurs.

Another user of ours with MINGW 3.2 has also encountered this problem, 
but is not experienced with a C debugger, so further information would 
be helpful.

> In order to find the source of this crash I then tried to compile the
> sources with the Microsoft Visual C++ 7.1 compiler, hereafer called VC,
> which provides really good debugging facilities on Windows, especially 
> with
> program crashes. On a program crash the VC debugger breaks directly 
> into the
> source code at the point where the crash occurred. This process of 
> trying to
> compile slate using the VC compiler highlighted some cross-compiler
> problems, as well as a few other issues in the Slate source code. Here 
> they
> are:
>
>
> A)------
>
> The "vm.h" and "vm.c" files define a number of inline C functions 
> using the
> "inline" modifier. However, this is not a standard C keyword and the VC
> compiler did not understand that. The "inline" keyword is specific to 
> the
> GCC compiler. The VC equivalent to that is "_inline". In order to make 
> the
> code compile on several compilers I'd suggest using an INLINE macro
> definition that checks the compiler being used and then defines it to 
> either
> "inline" or "_inline", or whatever else other compilers need. The 
> predefined
> macro that identifies the VC compiler is "_MSC_VER".

Okay, we can add that macro in another header for such compatibility 
issues.

> B)------
>
> The VC compiler also choked on the definition of the following two 
> structs:
>
> struct RoleTable {
>    struct ObjectHeader header;
>    struct Map * map;
>    ObjectPointer traits;
>    ObjectPointer elements[0];
>    struct RoleEntry roles[0];
> };
>
> struct SlotTable {
>    struct ObjectHeader header;
>    struct Map * map;
>    ObjectPointer traits;
>    ObjectPointer elements[0];
>    struct SlotEntry slots[0];
> };
>
> The VC compiler allows unsized or zero-sized arrays as the last member 
> in a
> struct definition. However, the definition above declares two 
> zero-sized
> arrays as the final members of the struct. I understand the usage of a
> single unsized array at the end of a struct, but I don't understand 
> how the
> above definitions are supposed to work. Maybe it is something specific 
> to
> the GCC compiler? In order to make the code compile I changed the
> definitions of
>
>    ObjectPointer elements[0];
>
> to
>
>    ObjectPointer * elements;
>
> in both struct definitions, but I'm sure that the semantics is not the 
> same
> and therefore the code will not run :-( I would appreciate it if 
> anyone can
> explain to me what the two zero-sized arrays at the end of a struct 
> means in
> GCC. Then I can maybe find a way to accomplish the same in VC.

Okay, this is definitely a weird little case, and I'm not sure of the 
answer. Maybe Lee has something to add here.

> C)------
> C.1)---
> The file "vm.c" does not include the file "vm.h", but instead contains 
> its
> own defininitions of everything it requires, which looks almost like a
> carbon copy of "vm.h". The result is that most of the definitions in 
> "vm.h"
> are duplicated in "vm.c". Is there a reason for doing it this way? Why 
> not
> just include the file "vm.h" in "vm.c"? While trying to get the code to
> compile I had to make changes to the same definitions in two places, 
> which
> is not good for maintainable code.

Well, er, it's not supposed to be maintained or even edited, actually. 
vm.c and vm.h are generated automatically from Slate code in 
src/mobius/vm/ (or bootstrap/mobius/vm/ actually). Our ultimate goal is 
to bypass C entirely with a direct compiler, but this work is not 
nearly complete yet.

However, this is a good idea to keep things separate, and is an 
artifact of our conservative process of how we have built up these 
files.

> C.2)---
> The file "vm.h" contains many static inline function definitions. What 
> is
> the purpose of putting static function definitions in a header file,
> especially if the only file that seems to be using them is "vm.c"? Why 
> not
> keep these definitions local to the C file that uses them?

Because the VM is designed so that we can extend it with C code that 
gets contributed but is platform-dependent or at least not generatable 
from Slate, we need to export basic utilities to keep these external 
modules' code somewhat tractable with VM format and operational 
changes.

> C.3)---
> Several of the function implementations call functions that have not 
> been
> defined yet. In these cases the VC compiler assumes they are extern
> functions returning an int. This happens at the following locations:
>
> File: "vm.c"
>    line 743: error() undefined
>    line 1213: shrinkMemoryBy() undefined
>    line 2280: growMemoryBy() undefined
> File: "vm.h"
>    line 429: error() undefined
>    line 586: PSInterpreter_sendMessage_withOptionals_() undefined
>    line 612: PWord_copyWords_into_() undefined
> File: "file.c"
>    line 134: PSObjectHeap_sweep() undefined
>    line 136: PSObjectHeap_adjustAllOopsBy_() undefined

Again, this is an artifact of the fact that the C code is automatically 
generated from Slate code, and that we are not automatically performing 
an ordering by dependency. The code for the C translation is in 
src/mobius/c/ or bootstrap/mobius/c/.

> C.4)---
> I notice that all the primitives that implement math functions like 
> sin,
> cos, log, etc., cast their double results to floats. There is a 
> possible
> loss of data here. For example, see the function _primitive55() which
> contains the following line of code:
>
>    *((float *) PSObject_arrayElements(z)) = (sin (a));
>
> The same happens in all the other primitives for math functions. Are 
> the
> real-valued types in Slate always floats, or can they be doubles as 
> well?
> I'd prefer them to be doubles as far as possible.

We don't support doubles yet; we probably will later on. This is an 
early release, and floating-point support is farther down the line than 
we are now.

> C.5)---
> In the file "file.c" the function PSObject_payloadSize(Object * obj) is
> called with a ByteArray* argument at lines 42 and 115. This may be a
> potentially invalid implicit cast.

Perhaps. Lee, any ideas?

> C.6)---
> In the file "file.c", line 136, the following function call is 
> performed:
>
>    PSObjectHeap_adjustAllOopsBy_ (CurrentMemory, - (unsigned)
> CurrentMemory -> memory);
>
> However, the signature of this function looks as follows:
>
>    unsigned long PSObjectHeap_adjustAllOopsBy_(struct ObjectHeap * h,
> unsigned long shiftAmountInBytes)
>
> Now this is the part that I don't understand. When the function call is
> performed, the 2nd argument is cast to an unsigned (int or long?), then
> negated, which makes it a negative integer, and then implicitly cast 
> to an
> unsigned long because that is the type of the 2nd argument. Is this 
> correct
> code?

Yeah, that does seem questionable. Lee?

> C.7)---
> Finally, if there are any implicit assumptions made in the code 
> regarding
> the byte-alignment and packing of struct members, then I'd like to see 
> them
> made explicit. This will greatly assist in making the code compile on 
> more
> compilers.

I hope there isn't.

> Regards
> Jaco van der Merwe

Thanks again.

--
Brian T. Rice
LOGOS Research and Development
http://tunes.org/~water/




More information about the Slate mailing list