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