From jay.krell at cornell.edu Tue Mar 5 06:33:13 2013 From: jay.krell at cornell.edu (Jay K) Date: Tue, 5 Mar 2013 05:33:13 +0000 Subject: [M3devel] cg.declare_subrange should pass on cgtype Message-ID: cg.declare_subrange should include the cgtype the frontend is going to use for the type. I'm pretty darn certain of this. Otherwise a backend very might want/need to duplicate the logic in m3front/types/SubrangeType.m3 SetRep. The logic isn't that complicated, but really, declare_subrange should take the information. I intend to write and commit that either tonight or within a week. I assume this is ok..as I'm pretty certain of it.. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Tue Mar 5 06:56:39 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 5 Mar 2013 16:56:39 +1100 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: References: Message-ID: Isn?t it already there (implicitly) in the bitsize to be used to represent the range? The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64). The backend is supposed to respect the bitsize. So, why do you need to duplicate that information? On Mar 5, 2013, at 4:33 PM, Jay K wrote: > cg.declare_subrange should include the cgtype the frontend > is going to use for the type. > > > I'm pretty darn certain of this. > > > Otherwise a backend very might want/need to duplicate > the logic in m3front/types/SubrangeType.m3 SetRep. > > The logic isn't that complicated, but really, declare_subrange > should take the information. > > I intend to write and commit that either tonight or within a week. > I assume this is ok..as I'm pretty certain of it.. > > > - Jay > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Tue Mar 5 07:29:34 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 5 Mar 2013 17:29:34 +1100 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com> References: <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com> Message-ID: Signedness should be irrelevant. It is only the storage that is specified by this. The interpretation of the bits, including signed/unsigned, is in the operations performed on those bits. e.g., load 8 bits sign extended. Why do you need to know the signedness? Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Mobile +1 765 427 5484 On Mar 5, 2013, at 5:21 PM, Jay wrote: > Close, but also signedness. > > - Jay > > On Mar 4, 2013, at 9:56 PM, Tony Hosking wrote: > >> Isn?t it already there (implicitly) in the bitsize to be used to represent the range? >> The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64). >> The backend is supposed to respect the bitsize. >> So, why do you need to duplicate that information? >> >> On Mar 5, 2013, at 4:33 PM, Jay K wrote: >> >>> cg.declare_subrange should include the cgtype the frontend >>> is going to use for the type. >>> >>> >>> I'm pretty darn certain of this. >>> >>> >>> Otherwise a backend very might want/need to duplicate >>> the logic in m3front/types/SubrangeType.m3 SetRep. >>> >>> The logic isn't that complicated, but really, declare_subrange >>> should take the information. >>> >>> I intend to write and commit that either tonight or within a week. >>> I assume this is ok..as I'm pretty certain of it.. >>> >>> >>> - Jay >>> >>> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Tue Mar 5 07:21:25 2013 From: jay.krell at cornell.edu (Jay) Date: Mon, 4 Mar 2013 22:21:25 -0800 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: References: Message-ID: <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com> Close, but also signedness. - Jay On Mar 4, 2013, at 9:56 PM, Tony Hosking wrote: > Isn?t it already there (implicitly) in the bitsize to be used to represent the range? > The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64). > The backend is supposed to respect the bitsize. > So, why do you need to duplicate that information? > > On Mar 5, 2013, at 4:33 PM, Jay K wrote: > >> cg.declare_subrange should include the cgtype the frontend >> is going to use for the type. >> >> >> I'm pretty darn certain of this. >> >> >> Otherwise a backend very might want/need to duplicate >> the logic in m3front/types/SubrangeType.m3 SetRep. >> >> The logic isn't that complicated, but really, declare_subrange >> should take the information. >> >> I intend to write and commit that either tonight or within a week. >> I assume this is ok..as I'm pretty certain of it.. >> >> >> - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Tue Mar 5 14:30:08 2013 From: jay.krell at cornell.edu (Jay) Date: Tue, 5 Mar 2013 05:30:08 -0800 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: References: <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com> Message-ID: I want to view the value in a debugger. Without having to cast it. By your reasoning, for record fields, among float, double, int32, int64, uint32, uint64, we'd only need 2. We want strong accurate types in "declare", not just operations like "add". Declare_subrange: is there a point to domain_type? I.e. how about declare_subrange(cgtype, min, max)? I'd have to see if cm3cg and then m3gdb use it. - Jay On Mar 4, 2013, at 10:29 PM, Tony Hosking wrote: > Signedness should be irrelevant. > It is only the storage that is specified by this. > The interpretation of the bits, including signed/unsigned, is in the operations performed on those bits. > e.g., load 8 bits sign extended. > > Why do you need to know the signedness? > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Mobile +1 765 427 5484 > > > > > > On Mar 5, 2013, at 5:21 PM, Jay wrote: > >> Close, but also signedness. >> >> - Jay >> >> On Mar 4, 2013, at 9:56 PM, Tony Hosking wrote: >> >>> Isn?t it already there (implicitly) in the bitsize to be used to represent the range? >>> The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64). >>> The backend is supposed to respect the bitsize. >>> So, why do you need to duplicate that information? >>> >>> On Mar 5, 2013, at 4:33 PM, Jay K wrote: >>> >>>> cg.declare_subrange should include the cgtype the frontend >>>> is going to use for the type. >>>> >>>> >>>> I'm pretty darn certain of this. >>>> >>>> >>>> Otherwise a backend very might want/need to duplicate >>>> the logic in m3front/types/SubrangeType.m3 SetRep. >>>> >>>> The logic isn't that complicated, but really, declare_subrange >>>> should take the information. >>>> >>>> I intend to write and commit that either tonight or within a week. >>>> I assume this is ok..as I'm pretty certain of it.. >>>> >>>> >>>> - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Mar 7 03:50:25 2013 From: jay.krell at cornell.edu (Jay K) Date: Thu, 7 Mar 2013 02:50:25 +0000 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: References: , , <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com>, , Message-ID: For now I'll just check if min < 0, like cm3cg does. m3gdb does not appear to use or parse out domain_typeid. domain_typeid doesn't seem needed. I think this stuff was clearly done slightly incorrectly in the first place. Not a huge mistake. There is also wierdness imho around empty subranges. i.e. it is an unobvious language detail. If it were up to me, [10..0] would either be illegal, OR would be the same as [0..10], OR would contain the same elements as [0..10] but would iterate in reverse FOR i := FIRST([10..0]) TO LAST([10..0]) would be equivalent to FOR i := 10 to 0 BY -1. However, it not any of those. It is legal and "empty". The FOR loop, I believe, never runs. NUMBER of such an array is 0. - Jay From: jay.krell at cornell.edu Date: Tue, 5 Mar 2013 05:30:08 -0800 To: hosking at cs.purdue.edu CC: m3devel at elegosoft.com; jay.krell at cornell.edu Subject: Re: [M3devel] cg.declare_subrange should pass on cgtype I want to view the value in a debugger. Without having to cast it. By your reasoning, for record fields, among float, double, int32, int64, uint32, uint64, we'd only need 2. We want strong accurate types in "declare", not just operations like "add". Declare_subrange: is there a point to domain_type? I.e. how about declare_subrange(cgtype, min, max)? I'd have to see if cm3cg and then m3gdb use it. - Jay On Mar 4, 2013, at 10:29 PM, Tony Hosking wrote: Signedness should be irrelevant. It is only the storage that is specified by this.The interpretation of the bits, including signed/unsigned, is in the operations performed on those bits.e.g., load 8 bits sign extended. Why do you need to know the signedness? Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAMobile +1 765 427 5484 On Mar 5, 2013, at 5:21 PM, Jay wrote:Close, but also signedness. - Jay On Mar 4, 2013, at 9:56 PM, Tony Hosking wrote: Isn?t it already there (implicitly) in the bitsize to be used to represent the range?The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64).The backend is supposed to respect the bitsize.So, why do you need to duplicate that information? On Mar 5, 2013, at 4:33 PM, Jay K wrote:cg.declare_subrange should include the cgtype the frontend is going to use for the type. I'm pretty darn certain of this. Otherwise a backend very might want/need to duplicate the logic in m3front/types/SubrangeType.m3 SetRep. The logic isn't that complicated, but really, declare_subrange should take the information. I intend to write and commit that either tonight or within a week. I assume this is ok..as I'm pretty certain of it.. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Mar 7 09:05:43 2013 From: jay.krell at cornell.edu (Jay K) Date: Thu, 7 Mar 2013 08:05:43 +0000 Subject: [M3devel] funding for one full time developer? Message-ID: So...crazy self-serving question..is there enough interest and commercial use of Modula-3..such as to fund Modula-3 development? One full time developer? Me? I realize Critical Mass already tried. I do quite enjoy working on this stuff, but I don't have enough time for it. :( Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From wagner at elego.de Thu Mar 7 13:49:50 2013 From: wagner at elego.de (Olaf Wagner) Date: Thu, 7 Mar 2013 13:49:50 +0100 Subject: [M3devel] funding for one full time developer? In-Reply-To: References: Message-ID: <20130307134950.96fff38a.wagner@elego.de> On Thu, 7 Mar 2013 08:05:43 +0000 Jay K wrote: > So...crazy self-serving question..is there enough > interest and commercial use of Modula-3..such > as to fund Modula-3 development? One full time developer? Me? > > I realize Critical Mass already tried. > > I do quite enjoy working on this stuff, but I don't have enough time for it. :( Elego has never been able to find any customer willing to pay some money for M3 support or M3-related work. From a commercial point of view, our M3 engagement hasn't been a huge success ;-) I love the language and I'd really like to see it more widely used, but I'm afraid there won't be enough interest. Olaf -- Olaf Wagner -- elego Software Solutions GmbH -- http://www.elegosoft.com Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 Gesch?ftsf?hrer: Michael Diers, Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From dabenavidesd at yahoo.es Sat Mar 9 19:46:49 2013 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sat, 9 Mar 2013 18:46:49 +0000 (GMT) Subject: [M3devel] funding for one full time developer? In-Reply-To: <20130307134950.96fff38a.wagner@elego.de> Message-ID: <1362854809.42539.YahooMailClassic@web133101.mail.ir2.yahoo.com> Hi all: I disagree, there are commercial projects and industrial research projects using it, problem is normally are industrial TOP secrets. Nobody else means anymore I don't agree. Thing is normally they use their in-house compiler, Elego could find the tool chain set to sell to a given company but that company might have the most part of it already. If all projects were open I'm sure M3 will be much an open place to have experience on. I would go to work in a research project for veryfing compiler strategy for TOP industries consortium. But we would need big hackers as you and brilliant minds as Hendrik, perhaps, maybe some spot for me there, but don't count with me. Research labs were the main development sandbox for Modula-3 and continue to be for years to come. Thanks in advance --- El jue, 7/3/13, Olaf Wagner escribi?: De: Olaf Wagner Asunto: Re: [M3devel] funding for one full time developer? Para: "Jay K" CC: "m3devel" Fecha: jueves, 7 de marzo, 2013 07:49 On Thu, 7 Mar 2013 08:05:43 +0000 Jay K wrote: > So...crazy self-serving question..is there enough > interest and commercial use of Modula-3..such > as to fund Modula-3 development? One full time developer? Me? > > I realize Critical Mass already tried. > > I do quite enjoy working on this stuff, but I don't have enough time for it. :( Elego has never been able to find any customer willing to pay some money for M3 support or M3-related work. >From a commercial point of view, our M3 engagement hasn't been a huge success ;-) I love the language and I'd really like to see it more widely used, but I'm afraid there won't be enough interest. Olaf -- Olaf Wagner -- elego Software Solutions GmbH -- http://www.elegosoft.com ? ? ? ? ? ? ???Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96? mobile: +49 177 2345 869? fax: +49 30 23 45 86 95 Gesch?ftsf?hrer: Michael Diers, Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 -------------- next part -------------- An HTML attachment was scrubbed... URL: From rcolebur at SCIRES.COM Tue Mar 12 03:25:01 2013 From: rcolebur at SCIRES.COM (Coleburn, Randy) Date: Tue, 12 Mar 2013 02:25:01 +0000 Subject: [M3devel] funding for one full time developer? Message-ID: <0BB8FA59C2932741A3A2941A8B9D8BFF0C252968@ATLEX04-SRV.SCIRES.LOCAL> My company was one of the first customers for Critical Mass. We also funded some development of custom modules. I'm still a huge fan of the Modula-3 language and it is my first choice for any software development task. Alas, I don't get paid to do much software development anymore, so most of my work these days is for my own purposes, and support of prior projects. Regards, Randy Coleburn -----Original Message----- From: Olaf Wagner [mailto:wagner at elego.de] Sent: Thursday, March 07, 2013 7:50 AM To: Jay K Cc: m3devel Subject: EXT:Re: [M3devel] funding for one full time developer? On Thu, 7 Mar 2013 08:05:43 +0000 Jay K wrote: > So...crazy self-serving question..is there enough interest and > commercial use of Modula-3..such as to fund Modula-3 development? One > full time developer? Me? > > I realize Critical Mass already tried. > > I do quite enjoy working on this stuff, but I don't have enough time > for it. :( Elego has never been able to find any customer willing to pay some money for M3 support or M3-related work. >From a commercial point of view, our M3 engagement hasn't been a huge success ;-) I love the language and I'd really like to see it more widely used, but I'm afraid there won't be enough interest. Olaf -- Olaf Wagner -- elego Software Solutions GmbH -- http://www.elegosoft.com Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 Gesch?ftsf?hrer: Michael Diers, Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Tue Mar 12 06:31:13 2013 From: jay.krell at cornell.edu (Jay K) Date: Tue, 12 Mar 2013 05:31:13 +0000 Subject: [M3devel] load and store should take TypeUID parameters Message-ID: load and store should take TypeUID parameters There are multiple reasons for this. Given: TYPE Color = {Red,Blue}; PROCEDURE P1() = VAR v1 := Color.Red; BEGIN END P1; I would like to generate: preamble in all files: typedef unsigned char UINT8; typedef unsigned short UINT16; typedef unsigned int UINT32; typedef unsigned long long UINT64; (This is not quite right.) #if __GNUC__ /* >= ? */ #define M3_ENUM_SIZE #define M3_ENUM_MODE8 __attribute__((__mode__(__QI__))) #define M3_ENUM_MODE16 __attribute__((__mode__(__HI__))) #define M3_ENUM_MODE32 __attribute__((__mode__(__SI__))) #define M3_ENUM_MODE64 __attribute__((__mode__(__DI__))) #else #define M3_ENUM_MODE8 /* nothing */ #define M3_ENUM_MODE16 /* nothing */ #define M3_ENUM_MODE32 /* nothing */ #define M3_ENUM_MODE64 /* nothing */ #endif #if _MSC_VER >= 1400 && defined(__cplusplus) #define M3_ENUM_SIZE #define M3_ENUM_BASE8 : UINT8 #define M3_ENUM_BASE16 : UINT16 #define M3_ENUM_BASE32 : UINT32 #define M3_ENUM_BASE64 : UINT64 #else #define M3_ENUM_BASE8 /* nothing */ #define M3_ENUM_BASE16 /* nothing */ #define M3_ENUM_BASE32 /* nothing */ #define M3_ENUM_BASE64 /* nothing */ #endif and then: given TypeUID = 123 // declare enum #if M3_ENUM_SIZE M3_ENUM_MODE8 enum M123 M3_ENUM_MODE8 { M123_Red, M123_Blue, M123_Green }; #else typedef UINT8 M123; #define M123_Red ((M123)0) #define M123_Blue ((M123)1) #define M123_Green ((M123)2) #endif // declare typename typedef M123 Color; // smart compiler recognizes left and right are enums perhaps and therefore: #define Color_Red M123_Red #define Color_Blue M123_Blue #define Color_Green M123_Green Color v1 = M123_Red; or perhaps: Color v1 = Color_Red; or perhaps merely: Color v1 = (Color)0; and really, ideally NOT Color v1; *(UINT8*)&v1 = (UINT8)0; The readability of the right hand side isn't the most critical. What is more critical is the readability of v1 in a debugger. The last form is what we are stuck with. Similarly, given: PROCEDURE P2(VAR a: INTEGER); PROCEDURE P3(VAR a: INTEGER) = BEGIN P2(b); END P3; I want: void P2(INTEGER* a); void P3(INTEGER* a) { P2(a); } no casts. Today, I make all pointers "ADDRESS" which is void* or char*. I don't remember all the reasons why. I guess I should just get over the cast happiness and ugly C implied by using C as a backend. But I do want things to look right in a debugger. I'll iterate more..later... - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael.anderson at elegosoft.com Wed Mar 13 12:10:30 2013 From: michael.anderson at elegosoft.com (Michael Anderson) Date: Wed, 13 Mar 2013 12:10:30 +0100 Subject: [M3devel] [elego Server Maintenance 13.03.2013 21:30] Message-ID: <51405EA6.6010700@elegosoft.com> Hello, On Wednesday, March 13 at 9:30 PM, we will perform scheduled maintenance on our servers. The following sites will be affected: mail.elegosoft.com gitolite.elegosoft.com servicedesk-intern.elegosoft.com cm3-bugs.elegosoft.com projects.elegosoft.com plane.elego.de Brief interruptions of service may occur. Expected duration: 120 Min. We apologize for any inconvenience. - the elego Admins am Mittwoch, den 13.03, werden ab 21.30 Uhr planm??ige Wartungsma?nahmen an unseren Servern durchgef?hrt. Folgende Dienste werden davon betroffen: mail.elegosoft.com gitolite.elegosoft.com servicedesk-intern.elegosoft.com cm3-bugs.elegosoft.com projects.elegosoft.com plane.elego.de Es kann zur kurzzeitigen Unterbrechung mancher Dienste kommen. Voraussichtliche Dauer der Wartung: 120 Min. Wir bitten um Verst?ndnis. - die elego Admins -- Michael Anderson IT Services & Support elego Software Solutions GmbH Gustav-Meyer-Allee 25 Building 12.3 (BIG) room 227 13355 Berlin, Germany phone +49 30 23 45 86 96 michael.anderson at elegosoft.com fax +49 30 23 45 86 95 http://www.elegosoft.com Geschaeftsfuehrer: Olaf Wagner, Sitz Berlin Amtsgericht Berlin-Charlottenburg, HRB 77719, USt-IdNr: DE163214194 From dragisha at m3w.org Sun Mar 17 00:34:58 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sun, 17 Mar 2013 00:34:58 +0100 Subject: [M3devel] Interfacing to OSX Core Foundation classes Message-ID: <00DDEDB6-B1B6-45AF-9C97-62E86CD76011@m3w.org> To resolve an issue with a project, I need to wrap few functions from Security framework on OSX Lion. I have no experience on this level with OSX programming. I did a lot of such work on Linux and Windows, and all I needed there is to match signatures of functions, structure of types, and refer m3makefile to right libraries. Also, I did similar work for various non-framework libraries on OSX, and it is Unix all the way. Anyone with CF/framework related experience? Do I need some special voodoo for handling various CF opaque objects or they are simple addresses? TIA, dd -- Divided by a common language Dragi?a Duri? dragisha at m3w.org -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 495 bytes Desc: Message signed with OpenPGP using GPGMail URL: From jay.krell at cornell.edu Sun Mar 17 07:22:27 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 17 Mar 2013 06:22:27 +0000 Subject: [M3devel] unresponsiveness to control-c and control-z Message-ID: cm3's unresponsiveness to control-c and control-z, and slowness exiting from assertion failures, is a significant drain on my time. I don't know if it is Darwin specific, with its direct suspension, or if all cm3 targets have this behavior. But it really needs to be fixed. Perhaps cooperative suspend is the answer. But I'd like it fixed soon. Please. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Sun Mar 17 15:12:07 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sun, 17 Mar 2013 15:12:07 +0100 Subject: [M3devel] Interfacing to OSX Core Foundation classes In-Reply-To: <91C3D6A3-39E1-4387-B16B-1E3CEACA8FA4@gmail.com> References: <00DDEDB6-B1B6-45AF-9C97-62E86CD76011@m3w.org> <91C3D6A3-39E1-4387-B16B-1E3CEACA8FA4@gmail.com> Message-ID: <0D261766-55B8-4468-BDE2-CADA4A1BAE4D@m3w.org> After a hint from Anthony, and a share of mining, mostly due to being first-time OSX Doc Miner :), here comes result. Example code: == CoureFoundation.i3 == INTERFACE CoreFoundation; IMPORT Ctypes; TYPE TypeRef = ADDRESS; DataRef = ADDRESS; AllocatorRef = ADDRESS; Index = Ctypes.long_int; <* EXTERNAL CFRelease *> PROCEDURE Release(cf: TypeRef); <* EXTERNAL CFDataCreate *> PROCEDURE DataCreate(allocator: AllocatorRef; bytes: Ctypes.void_star; length: Index): DataRef; (* Not exactly CF, but I can split later, if need be to grow this *) END CoreFoundation. == m3makefile == ? proc use_framework(FW) is configure_c_compiler() SYSTEM_CC = SYSTEM_CC & " -framework " & FW end if equal(TARGET, "AMD64_DARWIN") use_framework("CoreFoundation") use_framework("Security") ... === I named things like this so I can "IMPORT CoreFoundation AS CF" later and use names like CF.Release(). Hope it saves few hours to somebody else :). -- Divided by a common language Dragi?a Duri? dragisha at m3w.org On Mar 17, 2013, at 3:37 AM, Antony Hosking wrote: > Should be simple addresses. > > > On Mar 16, 2013, at 6:34 PM, Dragi?a Duri? wrote: > >> To resolve an issue with a project, I need to wrap few functions from Security framework on OSX Lion. I have no experience on this level with OSX programming. >> >> I did a lot of such work on Linux and Windows, and all I needed there is to match signatures of functions, structure of types, and refer m3makefile to right libraries. Also, I did similar work for various non-framework libraries on OSX, and it is Unix all the way. >> >> Anyone with CF/framework related experience? Do I need some special voodoo for handling various CF opaque objects or they are simple addresses? >> >> TIA, >> dd >> >> -- >> Divided by a common language >> >> Dragi?a Duri? >> dragisha at m3w.org >> >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Sun Mar 17 16:24:55 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sun, 17 Mar 2013 16:24:55 +0100 Subject: [M3devel] Interfacing to OSX Core Foundation classes In-Reply-To: <52ED640E-5B43-428E-8186-7C8C7BBBF64B@darko.org> References: <00DDEDB6-B1B6-45AF-9C97-62E86CD76011@m3w.org> <91C3D6A3-39E1-4387-B16B-1E3CEACA8FA4@gmail.com> <0D261766-55B8-4468-BDE2-CADA4A1BAE4D@m3w.org> <52ED640E-5B43-428E-8186-7C8C7BBBF64B@darko.org> Message-ID: <93E972AD-5AC4-45DE-947F-FBC89E392E6E@m3w.org> My problem did not involve Objective-C, just C API's, CoreFoundation and Security were involved. I took only what I needed. Your Carbon interface is welcome - I would like to learn more about topic, as I never know when I will need it. I like to be prepared! :) Thanks in advance, dd -- Divided by a common language Dragi?a Duri? dragisha at m3w.org On Mar 17, 2013, at 4:05 PM, Darko wrote: > But what about creating objects and calling methods, or whatever they're called in Objective-C? > > Also be aware if you want to use any structures from the older interfaces and Carbon they have byte alignment and must be declared specially. I have an interface file for most Carbon stuff, but it's a bit large at 3.2MB (~500KB compressed). I can mail it if you need it. > > > On Mar 17, 2013, at 7:12 AM, Dragi?a Duri? wrote: > >> After a hint from Anthony, and a share of mining, mostly due to being first-time OSX Doc Miner :), here comes result. Example code: >> >> == CoureFoundation.i3 == >> INTERFACE CoreFoundation; >> >> IMPORT Ctypes; >> >> TYPE >> TypeRef = ADDRESS; >> DataRef = ADDRESS; >> AllocatorRef = ADDRESS; >> Index = Ctypes.long_int; >> >> <* EXTERNAL CFRelease *> >> PROCEDURE Release(cf: TypeRef); >> >> <* EXTERNAL CFDataCreate *> >> PROCEDURE DataCreate(allocator: AllocatorRef; bytes: Ctypes.void_star; length: Index): DataRef; >> >> (* Not exactly CF, but I can split later, if need be to grow this >> *) >> >> END CoreFoundation. >> == m3makefile == >> ? >> proc use_framework(FW) is >> configure_c_compiler() >> SYSTEM_CC = SYSTEM_CC & " -framework " & FW >> end >> >> if equal(TARGET, "AMD64_DARWIN") >> use_framework("CoreFoundation") >> use_framework("Security") >> ... >> === >> >> I named things like this so I can "IMPORT CoreFoundation AS CF" later and use names like CF.Release(). >> >> Hope it saves few hours to somebody else :). >> -- >> Divided by a common language >> >> Dragi?a Duri? >> dragisha at m3w.org >> >> >> >> >> On Mar 17, 2013, at 3:37 AM, Antony Hosking wrote: >> >>> Should be simple addresses. >>> >>> >>> On Mar 16, 2013, at 6:34 PM, Dragi?a Duri? wrote: >>> >>>> To resolve an issue with a project, I need to wrap few functions from Security framework on OSX Lion. I have no experience on this level with OSX programming. >>>> >>>> I did a lot of such work on Linux and Windows, and all I needed there is to match signatures of functions, structure of types, and refer m3makefile to right libraries. Also, I did similar work for various non-framework libraries on OSX, and it is Unix all the way. >>>> >>>> Anyone with CF/framework related experience? Do I need some special voodoo for handling various CF opaque objects or they are simple addresses? >>>> >>>> TIA, >>>> dd >>>> >>>> -- >>>> Divided by a common language >>>> >>>> Dragi?a Duri? >>>> dragisha at m3w.org >>>> >>>> >>>> >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From darko at darko.org Sun Mar 17 16:05:57 2013 From: darko at darko.org (Darko) Date: Sun, 17 Mar 2013 08:05:57 -0700 Subject: [M3devel] Interfacing to OSX Core Foundation classes In-Reply-To: <0D261766-55B8-4468-BDE2-CADA4A1BAE4D@m3w.org> References: <00DDEDB6-B1B6-45AF-9C97-62E86CD76011@m3w.org> <91C3D6A3-39E1-4387-B16B-1E3CEACA8FA4@gmail.com> <0D261766-55B8-4468-BDE2-CADA4A1BAE4D@m3w.org> Message-ID: <52ED640E-5B43-428E-8186-7C8C7BBBF64B@darko.org> But what about creating objects and calling methods, or whatever they're called in Objective-C? Also be aware if you want to use any structures from the older interfaces and Carbon they have byte alignment and must be declared specially. I have an interface file for most Carbon stuff, but it's a bit large at 3.2MB (~500KB compressed). I can mail it if you need it. On Mar 17, 2013, at 7:12 AM, Dragi?a Duri? wrote: > After a hint from Anthony, and a share of mining, mostly due to being first-time OSX Doc Miner :), here comes result. Example code: > > == CoureFoundation.i3 == > INTERFACE CoreFoundation; > > IMPORT Ctypes; > > TYPE > TypeRef = ADDRESS; > DataRef = ADDRESS; > AllocatorRef = ADDRESS; > Index = Ctypes.long_int; > > <* EXTERNAL CFRelease *> > PROCEDURE Release(cf: TypeRef); > > <* EXTERNAL CFDataCreate *> > PROCEDURE DataCreate(allocator: AllocatorRef; bytes: Ctypes.void_star; length: Index): DataRef; > > (* Not exactly CF, but I can split later, if need be to grow this > *) > > END CoreFoundation. > == m3makefile == > ? > proc use_framework(FW) is > configure_c_compiler() > SYSTEM_CC = SYSTEM_CC & " -framework " & FW > end > > if equal(TARGET, "AMD64_DARWIN") > use_framework("CoreFoundation") > use_framework("Security") > ... > === > > I named things like this so I can "IMPORT CoreFoundation AS CF" later and use names like CF.Release(). > > Hope it saves few hours to somebody else :). > -- > Divided by a common language > > Dragi?a Duri? > dragisha at m3w.org > > > > > On Mar 17, 2013, at 3:37 AM, Antony Hosking wrote: > >> Should be simple addresses. >> >> >> On Mar 16, 2013, at 6:34 PM, Dragi?a Duri? wrote: >> >>> To resolve an issue with a project, I need to wrap few functions from Security framework on OSX Lion. I have no experience on this level with OSX programming. >>> >>> I did a lot of such work on Linux and Windows, and all I needed there is to match signatures of functions, structure of types, and refer m3makefile to right libraries. Also, I did similar work for various non-framework libraries on OSX, and it is Unix all the way. >>> >>> Anyone with CF/framework related experience? Do I need some special voodoo for handling various CF opaque objects or they are simple addresses? >>> >>> TIA, >>> dd >>> >>> -- >>> Divided by a common language >>> >>> Dragi?a Duri? >>> dragisha at m3w.org >>> >>> >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 05:56:59 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 04:56:59 +0000 Subject: [M3devel] layout of objects? Message-ID: layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 05:55:56 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 04:55:56 +0000 Subject: [M3devel] layout of objects? Message-ID: layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 06:50:23 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 01:50:23 -0400 Subject: [M3devel] layout of objects? In-Reply-To: References: Message-ID: <431DA224-01A8-4A56-A802-970B3424305A@cs.purdue.edu> header methods pointer fields If I recall correctly. Sent from my iPad On Mar 22, 2013, at 12:55 AM, Jay K wrote: > layout of objects? > > > > How are Modula-3 objects layed out? > i.e. "OBJECT"/"METHODS"/"OVERRIDES" > I skimmed m3front and it wasn't obvious. > > > > A common way for C++ "objects" to be layed out, > in the face of no RTTI and only single inheritance, > and virtual functions, is that a pointer to a record > of function pointers is first in the record. > > > Like this: > > > class Type > { > virtual void F1(); > virtual void F2(); > int data1; > int data2; > }; > > > ends up lik more this: > > > struct TypeFunctions > { > void (*F1)(Type*); > void (*F2)(Type*); > }; > > > struct Type > { > TypeFunctions* Functions; /* always first, > or at least a fixed offset, and located independent > of the size of the data; could also be at "-1" or such */. > int data1; > int data2; > }; > > > Type* x; > x->F1(); > > > => > x->Functions->F1(x); > > > Functions added in more derived types go at the end. > Ditto for data. > In the absence of multiple-inheritance and RTTI, it is simple and predictable. > (RTTI makes only small modifications.) > > > Looking through m3front, it wasn't at all obvious if it works this way. > > > I would like to declare something in C (or possibly C++, but not likely), > such that I might actually recognize the various low level operations > and "uncompile" it back to a typeful/typesafe form, like the above C++ > to C transform. > > > > I can't likely uncompile to C++ with virtual functions, > because the actual layout in C++ is not guaranteed. > > > > Granted, I am being lazy. > I should/could compile some small samples. > But I might not get the entire story that way. > > > > Thanks, > - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Fri Mar 22 07:34:32 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Fri, 22 Mar 2013 07:34:32 +0100 Subject: [M3devel] layout of objects? In-Reply-To: References: Message-ID: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote: > layout of objects? > > > > How are Modula-3 objects layed out? > i.e. "OBJECT"/"METHODS"/"OVERRIDES" > I skimmed m3front and it wasn't obvious. > > > > A common way for C++ "objects" to be layed out, > in the face of no RTTI and only single inheritance, > and virtual functions, is that a pointer to a record > of function pointers is first in the record. > > > Like this: > > > class Type > { > virtual void F1(); > virtual void F2(); > int data1; > int data2; > }; > > > ends up lik more this: > > > struct TypeFunctions > { > void (*F1)(Type*); > void (*F2)(Type*); > }; > > > struct Type > { > TypeFunctions* Functions; /* always first, > or at least a fixed offset, and located independent > of the size of the data; could also be at "-1" or such */. > int data1; > int data2; > }; > > > Type* x; > x->F1(); > > > => > x->Functions->F1(x); > > > Functions added in more derived types go at the end. > Ditto for data. > In the absence of multiple-inheritance and RTTI, it is simple and predictable. > (RTTI makes only small modifications.) > > > Looking through m3front, it wasn't at all obvious if it works this way. > > > I would like to declare something in C (or possibly C++, but not likely), > such that I might actually recognize the various low level operations > and "uncompile" it back to a typeful/typesafe form, like the above C++ > to C transform. > > > > I can't likely uncompile to C++ with virtual functions, > because the actual layout in C++ is not guaranteed. > > > > Granted, I am being lazy. > I should/could compile some small samples. > But I might not get the entire story that way. > > > > Thanks, > - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Fri Mar 22 07:40:23 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Fri, 22 Mar 2013 07:40:23 +0100 Subject: [M3devel] layout of objects? In-Reply-To: <431DA224-01A8-4A56-A802-970B3424305A@cs.purdue.edu> References: <431DA224-01A8-4A56-A802-970B3424305A@cs.purdue.edu> Message-ID: Yes, header too. And methods pointer is a structure from RT0 (methods and everything else). And data pointer program gets is address of first of fields. On Mar 22, 2013, at 6:50 AM, Tony Hosking wrote: > header > methods pointer > fields > > If I recall correctly. > > Sent from my iPad > > On Mar 22, 2013, at 12:55 AM, Jay K wrote: > >> layout of objects? >> >> >> >> How are Modula-3 objects layed out? >> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >> I skimmed m3front and it wasn't obvious. >> >> >> >> A common way for C++ "objects" to be layed out, >> in the face of no RTTI and only single inheritance, >> and virtual functions, is that a pointer to a record >> of function pointers is first in the record. >> >> >> Like this: >> >> >> class Type >> { >> virtual void F1(); >> virtual void F2(); >> int data1; >> int data2; >> }; >> >> >> ends up lik more this: >> >> >> struct TypeFunctions >> { >> void (*F1)(Type*); >> void (*F2)(Type*); >> }; >> >> >> struct Type >> { >> TypeFunctions* Functions; /* always first, >> or at least a fixed offset, and located independent >> of the size of the data; could also be at "-1" or such */. >> int data1; >> int data2; >> }; >> >> >> Type* x; >> x->F1(); >> >> >> => >> x->Functions->F1(x); >> >> >> Functions added in more derived types go at the end. >> Ditto for data. >> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >> (RTTI makes only small modifications.) >> >> >> Looking through m3front, it wasn't at all obvious if it works this way. >> >> >> I would like to declare something in C (or possibly C++, but not likely), >> such that I might actually recognize the various low level operations >> and "uncompile" it back to a typeful/typesafe form, like the above C++ >> to C transform. >> >> >> >> I can't likely uncompile to C++ with virtual functions, >> because the actual layout in C++ is not guaranteed. >> >> >> >> Granted, I am being lazy. >> I should/could compile some small samples. >> But I might not get the entire story that way. >> >> >> >> Thanks, >> - Jay >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 07:41:33 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 06:41:33 +0000 Subject: [M3devel] layout of objects? In-Reply-To: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> References: , <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: tangent: Shouldn't the methods and header/typeinfo be combined? Or is the header mutable and per-object? But, yeah, my point is more to understand, not to question or change. Thank you, - Jay From: dragisha at m3w.org Date: Fri, 22 Mar 2013 07:34:32 +0100 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] layout of objects? It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote:layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 07:44:37 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 01:44:37 -0500 Subject: [M3devel] layout of objects? In-Reply-To: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. Heap header is at -ADRSIZE(Header). The type information in RT0 is used to initialize the object instances. On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: > It's not m3front, it's RT0. > > First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. > > On Mar 22, 2013, at 5:56 AM, Jay K wrote: > >> layout of objects? >> >> >> >> How are Modula-3 objects layed out? >> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >> I skimmed m3front and it wasn't obvious. >> >> >> >> A common way for C++ "objects" to be layed out, >> in the face of no RTTI and only single inheritance, >> and virtual functions, is that a pointer to a record >> of function pointers is first in the record. >> >> >> Like this: >> >> >> class Type >> { >> virtual void F1(); >> virtual void F2(); >> int data1; >> int data2; >> }; >> >> >> ends up lik more this: >> >> >> struct TypeFunctions >> { >> void (*F1)(Type*); >> void (*F2)(Type*); >> }; >> >> >> struct Type >> { >> TypeFunctions* Functions; /* always first, >> or at least a fixed offset, and located independent >> of the size of the data; could also be at "-1" or such */. >> int data1; >> int data2; >> }; >> >> >> Type* x; >> x->F1(); >> >> >> => >> x->Functions->F1(x); >> >> >> Functions added in more derived types go at the end. >> Ditto for data. >> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >> (RTTI makes only small modifications.) >> >> >> Looking through m3front, it wasn't at all obvious if it works this way. >> >> >> I would like to declare something in C (or possibly C++, but not likely), >> such that I might actually recognize the various low level operations >> and "uncompile" it back to a typeful/typesafe form, like the above C++ >> to C transform. >> >> >> >> I can't likely uncompile to C++ with virtual functions, >> because the actual layout in C++ is not guaranteed. >> >> >> >> Granted, I am being lazy. >> I should/could compile some small samples. >> But I might not get the entire story that way. >> >> >> >> Thanks, >> - Jay >> > Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Fri Mar 22 08:06:53 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Fri, 22 Mar 2013 08:06:53 +0100 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: <9F41859D-4A58-4DEA-94AE-401B66DF4DE5@m3w.org> Relevant part is: LOOPHOLE(res - ADRSIZE(Header), RefHeader)^ := Header{typecode := def.typecode, dirty := TRUE}; So, there ia a header, where data is combined. dirty fields is for GC, and typecode is index into RT0 structures. -- Divided by a common language Dragi?a Duri? dragisha at m3w.org On Mar 22, 2013, at 7:44 AM, Tony Hosking wrote: > Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. > Heap header is at -ADRSIZE(Header). > The type information in RT0 is used to initialize the object instances. > > On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: > >> It's not m3front, it's RT0. >> >> First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. >> >> On Mar 22, 2013, at 5:56 AM, Jay K wrote: >> >>> layout of objects? >>> >>> >>> >>> How are Modula-3 objects layed out? >>> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >>> I skimmed m3front and it wasn't obvious. >>> >>> >>> >>> A common way for C++ "objects" to be layed out, >>> in the face of no RTTI and only single inheritance, >>> and virtual functions, is that a pointer to a record >>> of function pointers is first in the record. >>> >>> >>> Like this: >>> >>> >>> class Type >>> { >>> virtual void F1(); >>> virtual void F2(); >>> int data1; >>> int data2; >>> }; >>> >>> >>> ends up lik more this: >>> >>> >>> struct TypeFunctions >>> { >>> void (*F1)(Type*); >>> void (*F2)(Type*); >>> }; >>> >>> >>> struct Type >>> { >>> TypeFunctions* Functions; /* always first, >>> or at least a fixed offset, and located independent >>> of the size of the data; could also be at "-1" or such */. >>> int data1; >>> int data2; >>> }; >>> >>> >>> Type* x; >>> x->F1(); >>> >>> >>> => >>> x->Functions->F1(x); >>> >>> >>> Functions added in more derived types go at the end. >>> Ditto for data. >>> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >>> (RTTI makes only small modifications.) >>> >>> >>> Looking through m3front, it wasn't at all obvious if it works this way. >>> >>> >>> I would like to declare something in C (or possibly C++, but not likely), >>> such that I might actually recognize the various low level operations >>> and "uncompile" it back to a typeful/typesafe form, like the above C++ >>> to C transform. >>> >>> >>> >>> I can't likely uncompile to C++ with virtual functions, >>> because the actual layout in C++ is not guaranteed. >>> >>> >>> >>> Granted, I am being lazy. >>> I should/could compile some small samples. >>> But I might not get the entire story that way. >>> >>> >>> >>> Thanks, >>> - Jay >>> >> > > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Mobile +1 765 427 5484 > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 08:01:12 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 07:01:12 +0000 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org>, Message-ID: Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? PROCEDURE Compile (p: P) = VAR x := ObjectType.MethodOffset (p.holder); method: Method.Info; BEGIN Type.Compile (p.object); Method.SplitX (p.method, method); Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); IF (x >= 0) THEN INC (method.offset, x); ELSE (* runtime offset to methods *) Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); CG.Index_bytes (Target.Byte); END; CG.Boost_alignment (Target.Address.align); CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); CG.Boost_alignment (Target.Address.align); END Compile; "runtime offset to methods"? ObjectType.MethodOffset: PROCEDURE MethodOffset (t: Type.T): INTEGER = VAR p := Confirm (t); BEGIN IF (p = NIL) THEN RETURN Unknown_w_magic END; GetOffsets (p, use_magic := TRUE); RETURN p.methodOffset; END MethodOffset; PROCEDURE Confirm (t: Type.T): P = VAR info: Type.Info; BEGIN LOOP t := Type.CheckInfo (t, info); IF (info.class = Type.Class.Object) THEN RETURN t; ELSIF (info.class = Type.Class.Opaque) THEN t := Revelation.LookUp (t); ELSE RETURN NIL; END; END; END Confirm; ... - Jay Subject: Re: [M3devel] layout of objects? From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 01:44:37 -0500 CC: jay.krell at cornell.edu; m3devel at elegosoft.com To: dragisha at m3w.org Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields.Heap header is at -ADRSIZE(Header).The type information in RT0 is used to initialize the object instances. On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote:It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote:layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAMobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 09:08:04 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 03:08:04 -0500 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org>, Message-ID: x>=0 means a known constant method offset at compile time. Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can?t know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. On Mar 22, 2013, at 2:01 AM, Jay K wrote: > Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? > > > PROCEDURE Compile (p: P) = > VAR > x := ObjectType.MethodOffset (p.holder); > method: Method.Info; > BEGIN > Type.Compile (p.object); > Method.SplitX (p.method, method); > > Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); > IF (x >= 0) THEN > INC (method.offset, x); > ELSE (* runtime offset to methods *) > Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); > CG.Index_bytes (Target.Byte); > END; > CG.Boost_alignment (Target.Address.align); > CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); > CG.Boost_alignment (Target.Address.align); > END Compile; > > > "runtime offset to methods"? > ObjectType.MethodOffset: > > PROCEDURE MethodOffset (t: Type.T): INTEGER = > VAR p := Confirm (t); > BEGIN > IF (p = NIL) THEN RETURN Unknown_w_magic END; > GetOffsets (p, use_magic := TRUE); > RETURN p.methodOffset; > END MethodOffset; > > > PROCEDURE Confirm (t: Type.T): P = > VAR info: Type.Info; > BEGIN > LOOP > t := Type.CheckInfo (t, info); > IF (info.class = Type.Class.Object) THEN > RETURN t; > ELSIF (info.class = Type.Class.Opaque) THEN > t := Revelation.LookUp (t); > ELSE > RETURN NIL; > END; > END; > END Confirm; > > > ... > > > > - Jay > > > > > > Subject: Re: [M3devel] layout of objects? > From: hosking at cs.purdue.edu > Date: Fri, 22 Mar 2013 01:44:37 -0500 > CC: jay.krell at cornell.edu; m3devel at elegosoft.com > To: dragisha at m3w.org > > Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. > Heap header is at -ADRSIZE(Header). > The type information in RT0 is used to initialize the object instances. > > On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: > > It's not m3front, it's RT0. > > First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. > > On Mar 22, 2013, at 5:56 AM, Jay K wrote: > > layout of objects? > > > > How are Modula-3 objects layed out? > i.e. "OBJECT"/"METHODS"/"OVERRIDES" > I skimmed m3front and it wasn't obvious. > > > > A common way for C++ "objects" to be layed out, > in the face of no RTTI and only single inheritance, > and virtual functions, is that a pointer to a record > of function pointers is first in the record. > > > Like this: > > > class Type > { > virtual void F1(); > virtual void F2(); > int data1; > int data2; > }; > > > ends up lik more this: > > > struct TypeFunctions > { > void (*F1)(Type*); > void (*F2)(Type*); > }; > > > struct Type > { > TypeFunctions* Functions; /* always first, > or at least a fixed offset, and located independent > of the size of the data; could also be at "-1" or such */. > int data1; > int data2; > }; > > > Type* x; > x->F1(); > > > => > x->Functions->F1(x); > > > Functions added in more derived types go at the end. > Ditto for data. > In the absence of multiple-inheritance and RTTI, it is simple and predictable. > (RTTI makes only small modifications.) > > > Looking through m3front, it wasn't at all obvious if it works this way. > > > I would like to declare something in C (or possibly C++, but not likely), > such that I might actually recognize the various low level operations > and "uncompile" it back to a typeful/typesafe form, like the above C++ > to C transform. > > > > I can't likely uncompile to C++ with virtual functions, > because the actual layout in C++ is not guaranteed. > > > > Granted, I am being lazy. > I should/could compile some small samples. > But I might not get the entire story that way. > > > > Thanks, > - Jay > > > > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 17:13:44 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 16:13:44 +0000 Subject: [M3devel] layout of objects? In-Reply-To: References: , <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org>, , , , Message-ID: Are opaque types always revealed eventually? Or only sometimes? I'd like to generate structs and member references and not be adding offsets to pointers. For method calls and record field references. And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch of integers and no indication where the frontend got them from.. :( Thanks, - Jay From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 03:08:04 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] layout of objects? x>=0 means a known constant method offset at compile time.Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. On Mar 22, 2013, at 2:01 AM, Jay K wrote:Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? PROCEDURE Compile (p: P) = VAR x := ObjectType.MethodOffset (p.holder); method: Method.Info; BEGIN Type.Compile (p.object); Method.SplitX (p.method, method); Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); IF (x >= 0) THEN INC (method.offset, x); ELSE (* runtime offset to methods *) Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); CG.Index_bytes (Target.Byte); END; CG.Boost_alignment (Target.Address.align); CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); CG.Boost_alignment (Target.Address.align); END Compile; "runtime offset to methods"? ObjectType.MethodOffset: PROCEDURE MethodOffset (t: Type.T): INTEGER = VAR p := Confirm (t); BEGIN IF (p = NIL) THEN RETURN Unknown_w_magic END; GetOffsets (p, use_magic := TRUE); RETURN p.methodOffset; END MethodOffset; PROCEDURE Confirm (t: Type.T): P = VAR info: Type.Info; BEGIN LOOP t := Type.CheckInfo (t, info); IF (info.class = Type.Class.Object) THEN RETURN t; ELSIF (info.class = Type.Class.Opaque) THEN t := Revelation.LookUp (t); ELSE RETURN NIL; END; END; END Confirm; ... - Jay Subject: Re: [M3devel] layout of objects? From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 01:44:37 -0500 CC: jay.krell at cornell.edu; m3devel at elegosoft.com To: dragisha at m3w.org Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields.Heap header is at -ADRSIZE(Header).The type information in RT0 is used to initialize the object instances. On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote:It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote:layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAMobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 19:11:59 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 14:11:59 -0400 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: Every opaque type in a linkage must have only one revelation. Sent from my iPad On Mar 22, 2013, at 12:13 PM, Jay K wrote: > Are opaque types always revealed eventually? Or only sometimes? > I'd like to generate structs and member references and not be adding offsets to pointers. > For method calls and record field references. > And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch > of integers and no indication where the frontend got them from.. :( > > > Thanks, > - Jay > > > From: hosking at cs.purdue.edu > Date: Fri, 22 Mar 2013 03:08:04 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] layout of objects? > > x>=0 means a known constant method offset at compile time. > Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. > > On Mar 22, 2013, at 2:01 AM, Jay K wrote: > > Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? > > > PROCEDURE Compile (p: P) = > VAR > x := ObjectType.MethodOffset (p.holder); > method: Method.Info; > BEGIN > Type.Compile (p.object); > Method.SplitX (p.method, method); > > Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); > IF (x >= 0) THEN > INC (method.offset, x); > ELSE (* runtime offset to methods *) > Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); > CG.Index_bytes (Target.Byte); > END; > CG.Boost_alignment (Target.Address.align); > CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); > CG.Boost_alignment (Target.Address.align); > END Compile; > > > "runtime offset to methods"? > > ObjectType.MethodOffset: > > PROCEDURE MethodOffset (t: Type.T): INTEGER = > VAR p := Confirm (t); > BEGIN > IF (p = NIL) THEN RETURN Unknown_w_magic END; > GetOffsets (p, use_magic := TRUE); > RETURN p.methodOffset; > END MethodOffset; > > > PROCEDURE Confirm (t: Type.T): P = > VAR info: Type.Info; > BEGIN > LOOP > t := Type.CheckInfo (t, info); > IF (info.class = Type.Class.Object) THEN > RETURN t; > ELSIF (info.class = Type.Class.Opaque) THEN > t := Revelation.LookUp (t); > ELSE > RETURN NIL; > END; > END; > END Confirm; > > > ... > > > > - Jay > > > > > > Subject: Re: [M3devel] layout of objects? > From: hosking at cs.purdue.edu > Date: Fri, 22 Mar 2013 01:44:37 -0500 > CC: jay.krell at cornell.edu; m3devel at elegosoft.com > To: dragisha at m3w.org > > Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. > Heap header is at -ADRSIZE(Header). > The type information in RT0 is used to initialize the object instances. > > On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: > > It's not m3front, it's RT0. > > First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. > > On Mar 22, 2013, at 5:56 AM, Jay K wrote: > > layout of objects? > > > > How are Modula-3 objects layed out? > i.e. "OBJECT"/"METHODS"/"OVERRIDES" > I skimmed m3front and it wasn't obvious. > > > > A common way for C++ "objects" to be layed out, > in the face of no RTTI and only single inheritance, > and virtual functions, is that a pointer to a record > of function pointers is first in the record. > > > Like this: > > > class Type > { > virtual void F1(); > virtual void F2(); > int data1; > int data2; > }; > > > ends up lik more this: > > > struct TypeFunctions > { > void (*F1)(Type*); > void (*F2)(Type*); > }; > > > struct Type > { > TypeFunctions* Functions; /* always first, > or at least a fixed offset, and located independent > of the size of the data; could also be at "-1" or such */. > int data1; > int data2; > }; > > > Type* x; > x->F1(); > > > => > x->Functions->F1(x); > > > Functions added in more derived types go at the end. > Ditto for data. > In the absence of multiple-inheritance and RTTI, it is simple and predictable. > (RTTI makes only small modifications.) > > > Looking through m3front, it wasn't at all obvious if it works this way. > > > I would like to declare something in C (or possibly C++, but not likely), > such that I might actually recognize the various low level operations > and "uncompile" it back to a typeful/typesafe form, like the above C++ > to C transform. > > > > I can't likely uncompile to C++ with virtual functions, > because the actual layout in C++ is not guaranteed. > > > > Granted, I am being lazy. > I should/could compile some small samples. > But I might not get the entire story that way. > > > > Thanks, > - Jay > > > > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Mobile +1 765 427 5484 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 19:18:21 2013 From: jay.krell at cornell.edu (Jay) Date: Fri, 22 Mar 2013 11:18:21 -0700 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: <408C9E73-BD22-4457-9685-E661CF5A8401@gmail.com> Can it have zero revelations? Can you assist lazy me and suggest an accurate way to describe opaque types in a typeful way in C? Ultimate goal would be to get m3front & m3back optionally out of the business of computing offsets, instead using C structs and members and pointers and leave layout to the C compiler. Ultimately generating one architecture-independent, pointer-size-independent C. I understand there are multiple challenges here and eventually m3cg and m3front will need changes, to pass down more higher level information. - Jay On Mar 22, 2013, at 11:11 AM, Tony Hosking wrote: > Every opaque type in a linkage must have only one revelation. > > Sent from my iPad > > On Mar 22, 2013, at 12:13 PM, Jay K wrote: > >> Are opaque types always revealed eventually? Or only sometimes? >> I'd like to generate structs and member references and not be adding offsets to pointers. >> For method calls and record field references. >> And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch >> of integers and no indication where the frontend got them from.. :( >> >> >> Thanks, >> - Jay >> >> >> From: hosking at cs.purdue.edu >> Date: Fri, 22 Mar 2013 03:08:04 -0500 >> To: jay.krell at cornell.edu >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] layout of objects? >> >> x>=0 means a known constant method offset at compile time. >> Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. >> >> On Mar 22, 2013, at 2:01 AM, Jay K wrote: >> >> Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? >> >> >> PROCEDURE Compile (p: P) = >> VAR >> x := ObjectType.MethodOffset (p.holder); >> method: Method.Info; >> BEGIN >> Type.Compile (p.object); >> Method.SplitX (p.method, method); >> >> Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); >> IF (x >= 0) THEN >> INC (method.offset, x); >> ELSE (* runtime offset to methods *) >> Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); >> CG.Index_bytes (Target.Byte); >> END; >> CG.Boost_alignment (Target.Address.align); >> CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); >> CG.Boost_alignment (Target.Address.align); >> END Compile; >> >> >> "runtime offset to methods"? >> >> ObjectType.MethodOffset: >> >> PROCEDURE MethodOffset (t: Type.T): INTEGER = >> VAR p := Confirm (t); >> BEGIN >> IF (p = NIL) THEN RETURN Unknown_w_magic END; >> GetOffsets (p, use_magic := TRUE); >> RETURN p.methodOffset; >> END MethodOffset; >> >> >> PROCEDURE Confirm (t: Type.T): P = >> VAR info: Type.Info; >> BEGIN >> LOOP >> t := Type.CheckInfo (t, info); >> IF (info.class = Type.Class.Object) THEN >> RETURN t; >> ELSIF (info.class = Type.Class.Opaque) THEN >> t := Revelation.LookUp (t); >> ELSE >> RETURN NIL; >> END; >> END; >> END Confirm; >> >> >> ... >> >> >> >> - Jay >> >> >> >> >> >> Subject: Re: [M3devel] layout of objects? >> From: hosking at cs.purdue.edu >> Date: Fri, 22 Mar 2013 01:44:37 -0500 >> CC: jay.krell at cornell.edu; m3devel at elegosoft.com >> To: dragisha at m3w.org >> >> Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. >> Heap header is at -ADRSIZE(Header). >> The type information in RT0 is used to initialize the object instances. >> >> On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: >> >> It's not m3front, it's RT0. >> >> First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. >> >> On Mar 22, 2013, at 5:56 AM, Jay K wrote: >> >> layout of objects? >> >> >> >> How are Modula-3 objects layed out? >> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >> I skimmed m3front and it wasn't obvious. >> >> >> >> A common way for C++ "objects" to be layed out, >> in the face of no RTTI and only single inheritance, >> and virtual functions, is that a pointer to a record >> of function pointers is first in the record. >> >> >> Like this: >> >> >> class Type >> { >> virtual void F1(); >> virtual void F2(); >> int data1; >> int data2; >> }; >> >> >> ends up lik more this: >> >> >> struct TypeFunctions >> { >> void (*F1)(Type*); >> void (*F2)(Type*); >> }; >> >> >> struct Type >> { >> TypeFunctions* Functions; /* always first, >> or at least a fixed offset, and located independent >> of the size of the data; could also be at "-1" or such */. >> int data1; >> int data2; >> }; >> >> >> Type* x; >> x->F1(); >> >> >> => >> x->Functions->F1(x); >> >> >> Functions added in more derived types go at the end. >> Ditto for data. >> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >> (RTTI makes only small modifications.) >> >> >> Looking through m3front, it wasn't at all obvious if it works this way. >> >> >> I would like to declare something in C (or possibly C++, but not likely), >> such that I might actually recognize the various low level operations >> and "uncompile" it back to a typeful/typesafe form, like the above C++ >> to C transform. >> >> >> >> I can't likely uncompile to C++ with virtual functions, >> because the actual layout in C++ is not guaranteed. >> >> >> >> Granted, I am being lazy. >> I should/could compile some small samples. >> But I might not get the entire story that way. >> >> >> >> Thanks, >> - Jay >> >> >> >> >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Mobile +1 765 427 5484 >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 22:09:33 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 17:09:33 -0400 Subject: [M3devel] layout of objects? In-Reply-To: <408C9E73-BD22-4457-9685-E661CF5A8401@gmail.com> References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> <408C9E73-BD22-4457-9685-E661CF5A8401@gmail.com> Message-ID: <499B305B-B07F-40EB-9E77-2EE127BAEBDA@cs.purdue.edu> From the language spec: There are two kinds of revelations, partial and complete. A program can contain any number of partial revelations for an opaque type; it must contain exactly one complete revelation. Are you typing the method table as an array? Why not simply index the array? I don?t think there is any C type that natively captures the notion of opaque types. The whole point is that you don?t know all the parent types. But you do know that, given the offset of the opaque type?s methods in the method table, you can compute the offset of any given method. For example: TYPE T <: U; Without seeing the revelation of T there is no way to know what methods are inherited from everything between T and U. But, so long as at run time you are told the method offset of T?s methods in its method table then you can find any method defined in T at a known index from that offset. On Mar 22, 2013, at 2:18 PM, Jay wrote: > Can it have zero revelations? > > > Can you assist lazy me and suggest an accurate way to describe opaque types in a typeful way in C? > > > Ultimate goal would be to get m3front & m3back optionally out of the business of computing offsets, instead using C structs and members and pointers and leave layout to the C compiler. > Ultimately generating one architecture-independent, pointer-size-independent C. > > > I understand there are multiple challenges here and eventually m3cg and m3front will need changes, to pass down more higher level information. > > > - Jay > > On Mar 22, 2013, at 11:11 AM, Tony Hosking wrote: > >> Every opaque type in a linkage must have only one revelation. >> >> Sent from my iPad >> >> On Mar 22, 2013, at 12:13 PM, Jay K wrote: >> >>> Are opaque types always revealed eventually? Or only sometimes? >>> I'd like to generate structs and member references and not be adding offsets to pointers. >>> For method calls and record field references. >>> And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch >>> of integers and no indication where the frontend got them from.. :( >>> >>> >>> Thanks, >>> - Jay >>> >>> >>> From: hosking at cs.purdue.edu >>> Date: Fri, 22 Mar 2013 03:08:04 -0500 >>> To: jay.krell at cornell.edu >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] layout of objects? >>> >>> x>=0 means a known constant method offset at compile time. >>> Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. >>> >>> On Mar 22, 2013, at 2:01 AM, Jay K wrote: >>> >>> Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? >>> >>> >>> PROCEDURE Compile (p: P) = >>> VAR >>> x := ObjectType.MethodOffset (p.holder); >>> method: Method.Info; >>> BEGIN >>> Type.Compile (p.object); >>> Method.SplitX (p.method, method); >>> >>> Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); >>> IF (x >= 0) THEN >>> INC (method.offset, x); >>> ELSE (* runtime offset to methods *) >>> Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); >>> CG.Index_bytes (Target.Byte); >>> END; >>> CG.Boost_alignment (Target.Address.align); >>> CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); >>> CG.Boost_alignment (Target.Address.align); >>> END Compile; >>> >>> >>> "runtime offset to methods"? >>> >>> ObjectType.MethodOffset: >>> >>> PROCEDURE MethodOffset (t: Type.T): INTEGER = >>> VAR p := Confirm (t); >>> BEGIN >>> IF (p = NIL) THEN RETURN Unknown_w_magic END; >>> GetOffsets (p, use_magic := TRUE); >>> RETURN p.methodOffset; >>> END MethodOffset; >>> >>> >>> PROCEDURE Confirm (t: Type.T): P = >>> VAR info: Type.Info; >>> BEGIN >>> LOOP >>> t := Type.CheckInfo (t, info); >>> IF (info.class = Type.Class.Object) THEN >>> RETURN t; >>> ELSIF (info.class = Type.Class.Opaque) THEN >>> t := Revelation.LookUp (t); >>> ELSE >>> RETURN NIL; >>> END; >>> END; >>> END Confirm; >>> >>> >>> ... >>> >>> >>> >>> - Jay >>> >>> >>> >>> >>> >>> Subject: Re: [M3devel] layout of objects? >>> From: hosking at cs.purdue.edu >>> Date: Fri, 22 Mar 2013 01:44:37 -0500 >>> CC: jay.krell at cornell.edu; m3devel at elegosoft.com >>> To: dragisha at m3w.org >>> >>> Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. >>> Heap header is at -ADRSIZE(Header). >>> The type information in RT0 is used to initialize the object instances. >>> >>> On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: >>> >>> It's not m3front, it's RT0. >>> >>> First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. >>> >>> On Mar 22, 2013, at 5:56 AM, Jay K wrote: >>> >>> layout of objects? >>> >>> >>> >>> How are Modula-3 objects layed out? >>> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >>> I skimmed m3front and it wasn't obvious. >>> >>> >>> >>> A common way for C++ "objects" to be layed out, >>> in the face of no RTTI and only single inheritance, >>> and virtual functions, is that a pointer to a record >>> of function pointers is first in the record. >>> >>> >>> Like this: >>> >>> >>> class Type >>> { >>> virtual void F1(); >>> virtual void F2(); >>> int data1; >>> int data2; >>> }; >>> >>> >>> ends up lik more this: >>> >>> >>> struct TypeFunctions >>> { >>> void (*F1)(Type*); >>> void (*F2)(Type*); >>> }; >>> >>> >>> struct Type >>> { >>> TypeFunctions* Functions; /* always first, >>> or at least a fixed offset, and located independent >>> of the size of the data; could also be at "-1" or such */. >>> int data1; >>> int data2; >>> }; >>> >>> >>> Type* x; >>> x->F1(); >>> >>> >>> => >>> x->Functions->F1(x); >>> >>> >>> Functions added in more derived types go at the end. >>> Ditto for data. >>> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >>> (RTTI makes only small modifications.) >>> >>> >>> Looking through m3front, it wasn't at all obvious if it works this way. >>> >>> >>> I would like to declare something in C (or possibly C++, but not likely), >>> such that I might actually recognize the various low level operations >>> and "uncompile" it back to a typeful/typesafe form, like the above C++ >>> to C transform. >>> >>> >>> >>> I can't likely uncompile to C++ with virtual functions, >>> because the actual layout in C++ is not guaranteed. >>> >>> >>> >>> Granted, I am being lazy. >>> I should/could compile some small samples. >>> But I might not get the entire story that way. >>> >>> >>> >>> Thanks, >>> - Jay >>> >>> >>> >>> >>> >>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>> 305 N. University Street | West Lafayette | IN 47907 | USA >>> Mobile +1 765 427 5484 >>> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 22:29:07 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 21:29:07 +0000 Subject: [M3devel] layout of objects? In-Reply-To: <499B305B-B07F-40EB-9E77-2EE127BAEBDA@cs.purdue.edu> References: , <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org>, , , , , , <408C9E73-BD22-4457-9685-E661CF5A8401@gmail.com>, <499B305B-B07F-40EB-9E77-2EE127BAEBDA@cs.purdue.edu> Message-ID: I'd like to reference a member in a struct, a typed function pointer.I think I see your point though.Each partial revelation describes a subset of the methods.Almost like multiple inheritance, multiple vtables, but subsequences within one linear vtable.More later.. - Jay From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 17:09:33 -0400 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] layout of objects? From the language spec: There are two kinds of revelations, partial and complete. A program can contain any number of partial revelations for an opaque type; it must contain exactly one complete revelation. Are you typing the method table as an array?Why not simply index the array? I don't think there is any C type that natively captures the notion of opaque types.The whole point is that you don't know all the parent types.But you do know that, given the offset of the opaque type's methods in the method table, you can compute the offset of any given method. For example: TYPE T <: U; Without seeing the revelation of T there is no way to know what methods are inherited from everything between T and U.But, so long as at run time you are told the method offset of T's methods in its method table then you can find any method defined in T at a known index from that offset. On Mar 22, 2013, at 2:18 PM, Jay wrote:Can it have zero revelations? Can you assist lazy me and suggest an accurate way to describe opaque types in a typeful way in C? Ultimate goal would be to get m3front & m3back optionally out of the business of computing offsets, instead using C structs and members and pointers and leave layout to the C compiler.Ultimately generating one architecture-independent, pointer-size-independent C. I understand there are multiple challenges here and eventually m3cg and m3front will need changes, to pass down more higher level information. - Jay On Mar 22, 2013, at 11:11 AM, Tony Hosking wrote: Every opaque type in a linkage must have only one revelation. Sent from my iPad On Mar 22, 2013, at 12:13 PM, Jay K wrote: Are opaque types always revealed eventually? Or only sometimes? I'd like to generate structs and member references and not be adding offsets to pointers. For method calls and record field references. And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch of integers and no indication where the frontend got them from.. :( Thanks, - Jay From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 03:08:04 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] layout of objects? x>=0 means a known constant method offset at compile time.Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. On Mar 22, 2013, at 2:01 AM, Jay K wrote:Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? PROCEDURE Compile (p: P) = VAR x := ObjectType.MethodOffset (p.holder); method: Method.Info; BEGIN Type.Compile (p.object); Method.SplitX (p.method, method); Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); IF (x >= 0) THEN INC (method.offset, x); ELSE (* runtime offset to methods *) Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); CG.Index_bytes (Target.Byte); END; CG.Boost_alignment (Target.Address.align); CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); CG.Boost_alignment (Target.Address.align); END Compile; "runtime offset to methods"? ObjectType.MethodOffset: PROCEDURE MethodOffset (t: Type.T): INTEGER = VAR p := Confirm (t); BEGIN IF (p = NIL) THEN RETURN Unknown_w_magic END; GetOffsets (p, use_magic := TRUE); RETURN p.methodOffset; END MethodOffset; PROCEDURE Confirm (t: Type.T): P = VAR info: Type.Info; BEGIN LOOP t := Type.CheckInfo (t, info); IF (info.class = Type.Class.Object) THEN RETURN t; ELSIF (info.class = Type.Class.Opaque) THEN t := Revelation.LookUp (t); ELSE RETURN NIL; END; END; END Confirm; ... - Jay Subject: Re: [M3devel] layout of objects? From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 01:44:37 -0500 CC: jay.krell at cornell.edu; m3devel at elegosoft.com To: dragisha at m3w.org Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields.Heap header is at -ADRSIZE(Header).The type information in RT0 is used to initialize the object instances. On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote:It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote:layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAMobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 22:30:02 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 21:30:02 +0000 Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: <20130322194459.GE12913@tucnak.redhat.com> References: <20130322194459.GE12913@tucnak.redhat.com> Message-ID: Perhaps we should use this. I'm more inclined to work on the C backend though. - Jay > Date: Fri, 22 Mar 2013 20:44:59 +0100 > From: jakub at redhat.com > To: gcc-announce at gcc.gnu.org > Subject: GCC 4.8.0 Released > > Exactly one year after the last major GCC release has been announced, > celebrating the 26th anniversary of the GNU Compiler Collection, > the GCC development team announces a new major GCC release, 4.8.0. > > GCC 4.8.0 is a major release containing substantial new > functionality not available in GCC 4.7.x or previous GCC releases. > > GCC 4.8 features a new Local Register Allocator which replaces the 26 > years old reload pass and improves generated code quality on ia32 and > x86-64 targets. The C++ frontend and standard library have been > enhanced with various improvements for C++11 support not limited to C++11 > attribute syntax, thread_local or inheriting constructors support. > > AddressSanitizer and ThreadSanitizer instrumentation have been > added to detect heap, stack and global buffer overflows, uses after free > and data races. > > Many scalability bottle-necks have been removed from GCC optimization > passes, thus it is now possible to compile extremely large functions with > smaller memory consumption in less time. > > Extending the widest support for hardware architectures in the industry, > GCC 4.8 has gained support for the upcoming 64-bit ARM instruction set > architecture, AArch64. GCC 4.8 also features support for Hardware > Transactional Memory on the upcoming Intel Haswell CPU architecture. > The S/390 target now supports the zEC12 architecture. The ARM 32-bit > target has gained support for AArch32 ARM v8 ISA additions. > > See > > http://gcc.gnu.org/gcc-4.8/changes.html > > for more information about changes in GCC 4.8. > > This release is available from the FTP servers listed here: > > http://www.gnu.org/order/ftp.html > > The release is in gcc/gcc-4.8.0/ subdirectory. > > If you encounter difficulties using GCC 4.8, please do not contact me > directly. Instead, please visit http://gcc.gnu.org for information > about getting help. > > > Driving a leading free software project such as GNU Compiler Collection > would not be possible without support from its many contributors. > Not to only mention its developers but especially its regular testers > and users which contribute to its high quality. The list of individuals > is too large to thank individually! -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 22:56:00 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 17:56:00 -0400 Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: References: <20130322194459.GE12913@tucnak.redhat.com> Message-ID: In my opinion it would be better to work on an LLVM backend. On Mar 22, 2013, at 5:30 PM, Jay K wrote: > > > Perhaps we should use this. I'm more inclined to work on the C backend though. > > - Jay > > Date: Fri, 22 Mar 2013 20:44:59 +0100 > > From: jakub at redhat.com > > To: gcc-announce at gcc.gnu.org > > Subject: GCC 4.8.0 Released > > > > Exactly one year after the last major GCC release has been announced, > > celebrating the 26th anniversary of the GNU Compiler Collection, > > the GCC development team announces a new major GCC release, 4.8.0. > > > > GCC 4.8.0 is a major release containing substantial new > > functionality not available in GCC 4.7.x or previous GCC releases. > > > > GCC 4.8 features a new Local Register Allocator which replaces the 26 > > years old reload pass and improves generated code quality on ia32 and > > x86-64 targets. The C++ frontend and standard library have been > > enhanced with various improvements for C++11 support not limited to C++11 > > attribute syntax, thread_local or inheriting constructors support. > > > > AddressSanitizer and ThreadSanitizer instrumentation have been > > added to detect heap, stack and global buffer overflows, uses after free > > and data races. > > > > Many scalability bottle-necks have been removed from GCC optimization > > passes, thus it is now possible to compile extremely large functions with > > smaller memory consumption in less time. > > > > Extending the widest support for hardware architectures in the industry, > > GCC 4.8 has gained support for the upcoming 64-bit ARM instruction set > > architecture, AArch64. GCC 4.8 also features support for Hardware > > Transactional Memory on the upcoming Intel Haswell CPU architecture. > > The S/390 target now supports the zEC12 architecture. The ARM 32-bit > > target has gained support for AArch32 ARM v8 ISA additions. > > > > See > > > > http://gcc.gnu.org/gcc-4.8/changes.html > > > > for more information about changes in GCC 4.8. > > > > This release is available from the FTP servers listed here: > > > > http://www.gnu.org/order/ftp.html > > > > The release is in gcc/gcc-4.8.0/ subdirectory. > > > > If you encounter difficulties using GCC 4.8, please do not contact me > > directly. Instead, please visit http://gcc.gnu.org for information > > about getting help. > > > > > > Driving a leading free software project such as GNU Compiler Collection > > would not be possible without support from its many contributors. > > Not to only mention its developers but especially its regular testers > > and users which contribute to its high quality. The list of individuals > > is too large to thank individually! -------------- next part -------------- An HTML attachment was scrubbed... URL: From lemming at henning-thielemann.de Fri Mar 22 22:57:29 2013 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Fri, 22 Mar 2013 22:57:29 +0100 (CET) Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: References: <20130322194459.GE12913@tucnak.redhat.com> Message-ID: On Fri, 22 Mar 2013, Tony Hosking wrote: > In my opinion it would be better to work on an LLVM backend. Btw. does someone of you attend to the Euro-LLVM meeting 29-30th April? From jay.krell at cornell.edu Sat Mar 23 00:05:16 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 23:05:16 +0000 Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: References: <20130322194459.GE12913@tucnak.redhat.com>, , , Message-ID: I favor a C backend for a few reasons. - portability -- C supports more than LLVM, past and future I haven't been able to build LLVM on my old MacOSX. - a possible portable source distribution, like most software, but, granted, not like many compilers, and granted, while the C backend now works quite well, this problem still needs a lot of work - Not having to learn LLVM, resting on my C knowledge; might apply to others - LLVM might have the same m3gdb integration problem as C, no better, no worse On the other hand, LLVM is good for: - learn something new - resulting compiler will probably run faster - Jay > Date: Fri, 22 Mar 2013 22:57:29 +0100 > From: lemming at henning-thielemann.de > To: m3devel at elegosoft.com > Subject: Re: [M3devel] FW: GCC 4.8.0 Released > > > On Fri, 22 Mar 2013, Tony Hosking wrote: > > > In my opinion it would be better to work on an LLVM backend. > > Btw. does someone of you attend to the Euro-LLVM meeting 29-30th April? -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sat Mar 23 01:57:46 2013 From: jay.krell at cornell.edu (Jay K) Date: Sat, 23 Mar 2013 00:57:46 +0000 Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: References: <20130322194459.GE12913@tucnak.redhat.com>, , , , , , , Message-ID: (but, ps, for high-end full time wages I'd write an LLVM backend or port to gcc 4.8.0 or port the existing integrated x86 backend, or other, and be more flexible/open-minded. :) Yes I know that is kind of rude and against the spirit of things... ) - JayFrom: jay.krell at cornell.edu To: lemming at henning-thielemann.de; m3devel at elegosoft.com Date: Fri, 22 Mar 2013 23:05:16 +0000 Subject: Re: [M3devel] FW: GCC 4.8.0 Released I favor a C backend for a few reasons. - portability -- C supports more than LLVM, past and future I haven't been able to build LLVM on my old MacOSX. - a possible portable source distribution, like most software, but, granted, not like many compilers, and granted, while the C backend now works quite well, this problem still needs a lot of work - Not having to learn LLVM, resting on my C knowledge; might apply to others - LLVM might have the same m3gdb integration problem as C, no better, no worse On the other hand, LLVM is good for: - learn something new - resulting compiler will probably run faster - Jay > Date: Fri, 22 Mar 2013 22:57:29 +0100 > From: lemming at henning-thielemann.de > To: m3devel at elegosoft.com > Subject: Re: [M3devel] FW: GCC 4.8.0 Released > > > On Fri, 22 Mar 2013, Tony Hosking wrote: > > > In my opinion it would be better to work on an LLVM backend. > > Btw. does someone of you attend to the Euro-LLVM meeting 29-30th April? -------------- next part -------------- An HTML attachment was scrubbed... URL: From dabenavidesd at yahoo.es Sat Mar 23 16:19:26 2013 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sat, 23 Mar 2013 15:19:26 +0000 (GMT) Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: Message-ID: <1364051966.34337.YahooMailClassic@web133101.mail.ir2.yahoo.com> Hi : a bytecoded interpreter would make the trick to boot from m3c instead of using a compiler. Was natural choice in Pascal. Thanks in advance --- El vie, 22/3/13, Jay K escribi?: De: Jay K Asunto: Re: [M3devel] FW: GCC 4.8.0 Released Para: "Henning Thielemann" , "m3devel" Fecha: viernes, 22 de marzo, 2013 19:57 (but, ps,?for high-end full time?wages I'd write an LLVM backend or port to gcc 4.8.0 or port the existing integrated x86 backend, or other, and be more flexible/open-minded.?:) Yes I know that is kind of rude and against the spirit of things... ) ? ?- Jay From: jay.krell at cornell.edu To: lemming at henning-thielemann.de; m3devel at elegosoft.com Date: Fri, 22 Mar 2013 23:05:16 +0000 Subject: Re: [M3devel] FW: GCC 4.8.0 Released I?favor a C backend for a few reasons. ??-?portability -- C?supports more than LLVM, past and future ???? I haven't been able to build LLVM on my old MacOSX.? ??- a possible portable source?distribution, like most software, but,?granted, not like many compilers, and granted, while the C backend now works quite well, this problem still needs a lot of work ? -?Not having to learn LLVM, resting on my C knowledge; might apply to others ?? ? - LLVM might have the same?m3gdb integration problem as C, no better, no worse ? ? ? ?On the other hand, LLVM is good for: ?? - learn something new ?? - resulting compiler?will?probably run faster ? ? ?- Jay? > Date: Fri, 22 Mar 2013 22:57:29 +0100 > From: lemming at henning-thielemann.de > To: m3devel at elegosoft.com > Subject: Re: [M3devel] FW: GCC 4.8.0 Released > > > On Fri, 22 Mar 2013, Tony Hosking wrote: > > > In my opinion it would be better to work on an LLVM backend. > > Btw. does someone of you attend to the Euro-LLVM meeting 29-30th April? -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Mar 28 06:04:46 2013 From: jay.krell at cornell.edu (Jay K) Date: Thu, 28 Mar 2013 05:04:46 +0000 Subject: [M3devel] LLVM backend? Message-ID: I was thinking of looking into LLVM more. For selfish reasons -- resume growth, but no matter. 1) Tony, are you making progress? Should I wait? Collaberate? Go it alone? 2) An LLVM backend would I suspect have the same lack of m3gdb support as a C backend. Does that bother people?Actually I was just skimming "parse.c"..I don't remember exactly how I decided it is all a stabs-specific hack.Though, I do realize 1) typeids are encoded in identifier names, which certainly hurts debuggingw/o m3gdb 2) types aren't being described as they ought to be. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Mar 28 06:39:35 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 28 Mar 2013 16:39:35 +1100 Subject: [M3devel] LLVM backend? In-Reply-To: References: Message-ID: I am short of the time needed to make real progress. I am happy to collaborate even if only in an advisory role. I have some of the design written down, but other aspects in my head. For example, dealing with lexically scoped variables for nested functions requires capturing all the "escaping" variables (referenced by inner scope functions) into a properly typed "frame" structure, along with the static link, and whose pointer can be passed as the static link to inner scope functions. On Mar 28, 2013, at 4:04 PM, Jay K wrote: > I was thinking of looking into LLVM more. For selfish reasons -- resume growth, but no matter. > > 1) Tony, are you making progress? Should I wait? Collaberate? Go it alone? > 2) An LLVM backend would I suspect have the same lack of m3gdb support as a C backend. > Does that bother people? > Actually I was just skimming "parse.c"..I don't remember exactly how I decided it is all a stabs-specific hack. > Though, I do realize 1) typeids are encoded in identifier names, which certainly hurts debugging > w/o m3gdb 2) types aren't being described as they ought to be. > > - Jay > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Thu Mar 28 16:23:17 2013 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Thu, 28 Mar 2013 10:23:17 -0500 Subject: [M3devel] LLVM backend? In-Reply-To: References: Message-ID: <51546065.5030709@lcwb.coop> On 03/28/2013 12:04 AM, Jay K wrote: > I was thinking of looking into LLVM more. For selfish reasons -- resume growth, but no matter. > > 1) Tony, are you making progress? Should I wait? Collaberate? Go it alone? (Jay, I reversed the order of your paragraphs here, because my responses make more sense in that order.) > Actually I was just skimming "parse.c"..I don't remember exactly how I decided it is all a stabs-specific hack. > Though, I do realize 1) typeids are encoded in identifier names, which certainly hurts debugging > w/o m3gdb 2) types aren't being described as they ought to be. > Yes, it is very much a hack. For one thing, stabs itself is something of a hack. For another, a lot of the fields of stabs info are really treated as just containers for some extremely Modula-3-specific info, that, to be fair, isn't provided for in any reasonable way by true stabs. Meanwhile, some true stabs stuff is produced too, but not used in m3gdb, because it isn't quite right or helpful. parse.c and m3gdb are highly coupled by all this. Stock gdb's code to read stabs is augmented by tons of stuff to further decode the M3-specific info inserted by parse.c, and tons more to interpret it. Moreover, debug info and code to be translated effectively become diverging streams in parse.c, notwithstanding the fact that they are often interspersed. This makes it very difficult for debug info to reflect anything gcc does to the code. I believe the stabs info is mostly or entirely untouched after parse.c, though I haven't ever thoroughly vetted this. One specific place where this particularly hurts right now is with nonlocal references, static links, etc. With the advent of tree-nested.c, in later gcc versions, the runtime storage model is drastically reworked in gcc, after the stabs has already been produced. That seriously broke a lot of stuff I had working in m3gdb. I have dabbled with Mickey- Mouse schemes to emit purely additional stabs info in tree-nested.c, without changing what was already there, then have m3gdb use it to selectively override the earlier-produced stabs. I never finished this, and have only limited confidence it is even feasible. > 2) An LLVM backend would I suspect have the same lack of m3gdb support as a C backend. > Does that bother people? LLVM has a lot of already provided support for dwarf debug info, keeping it together with code, and helping to transform it in parallel with code, when optimizations, etc., are done. Meanwhile, dwarf itself is vastly more complete and appears to me, from superficial study, to be capable of representing all, or certainly most, of what is needed for good Modula-3 debugging. For these two reasons, I think LLVM plus dwarf present by far the best method to support a nice language-specific debugging experience, while leaving massive kludges behind. This is one big reason why I support an LLVM back end. It would indeed require significant work to get debug support. But it would be so much easier and far more pleasant than the alternatives. That includes even the alternative of further fixing the existing m3gdb/gcc, which still needs perhaps as much additional work as has already gone into it. I am attached to it only because it now provides a lot more function than anything else we have (and which I use a lot). Mucking around in M3ified stabs is, for me, strictly a destination, not a journey. So, the short answer is, it bothers me less than any other option. From jay.krell at cornell.edu Fri Mar 29 17:09:09 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 29 Mar 2013 16:09:09 +0000 Subject: [M3devel] LLVM backend? In-Reply-To: <51546065.5030709@lcwb.coop> References: , <51546065.5030709@lcwb.coop> Message-ID: This doesn't completely make sense to me. But it is kind of what I expected and desire. The debug format isn't the point. parse.c should have no knowledge of dwarf vs. stabs vs. coff vs. xcoff vs. codeview vs. vms vs. anything else. It just happens that the authors found a private channel in stabs. Ideally any debug format used by any C compiler can fully describe C, and Modula-3. The way it (any gcc frontend) is supposed to work is you describe the types using a compiler-internal form, and that gets translated into whatever the user requests that is supported. The primary limit as to what gcc can do is probably the object file format. Any backend without a private channel to the debugger, i.e. the C backend as well as an LLVM backend, will have degraded debugging. Perhaps a private channel can be found either way though. Like, gcc does have this "tfile" thing where after compilation, a separate tool goes over the .S file and makes changes. Ideally we don't have intermediate .S files though. Now, on Windows, for cdb/ntsd/windbg/kd, you can write debugger plugins. .dlls loaded by the debugger that have full access to symbols. They are often very helpful, and would surely help here. I do wonder if it is worth changing TEXT for debuggability. Like, say, to always be flat, no trees, and always nul terminated: (actually I'd always write two zero bytes, in case of viewing the ascii as unicode) #define TEXT_FLAGS_UNICODE (0x00000001) #define TEXT_FLAGS_CONSTANT (0x00000002) typedef struct { size_t flags; size_t length; union { char* ascii; wchar_t* unicode; } data; } *TEXT; ? If we had merely that -- a more debugger/C-idiomatic representation for TEXT, would m3gdb's advantages decline significantly? I'd also be open to just plain typedef char* TEXT; UTF8 encoded. Text.Length is slow, and Text.Concat also slower. But ideally we'd store the length. The length could also be stored before the string. On Windows, "BSTR"s work this way. i.e. it is viable and practical and in wide use. Also, MFC/ATL CStringW/CStringA do this: typedef struct { wchar_t* data; } CStringW; typedef struct { char* data; } CStringA; and then have an entire small struct before the data. It holdes, as I recall, at least the length and a reference count. The strings are reference counted and copy-on-write. It is a nice implementation, but it isn't quite relevant here, since our TEXTs are immutable and garbage collected. The point is though, putting a struct in front of a char*/wchar_t* is viable. As long as the garbage collector doesn't get confused. Anyway, I think I'll start augmenting M3C.m3 to start writing .ll files also. We'll see how that goes. I realize it isn't the ideal path. Wrt nested variables/functions, I make a transform in the C backend. The LLVM backend will need to make a similar transform. I think the frontend should be willing/able to do this transform. It would likely help. - Jay > Date: Thu, 28 Mar 2013 10:23:17 -0500 > From: rodney_bates at lcwb.coop > To: m3devel at elegosoft.com > Subject: Re: [M3devel] LLVM backend? > > > > On 03/28/2013 12:04 AM, Jay K wrote: > > I was thinking of looking into LLVM more. For selfish reasons -- resume growth, but no matter. > > > > 1) Tony, are you making progress? Should I wait? Collaberate? Go it alone? > > (Jay, I reversed the order of your paragraphs here, because my responses make more sense in that order.) > > > Actually I was just skimming "parse.c"..I don't remember exactly how I decided it is all a stabs-specific hack. > > Though, I do realize 1) typeids are encoded in identifier names, which certainly hurts debugging > > w/o m3gdb 2) types aren't being described as they ought to be. > > > > Yes, it is very much a hack. For one thing, stabs itself is something of a hack. For another, > a lot of the fields of stabs info are really treated as just containers for some extremely > Modula-3-specific info, that, to be fair, isn't provided for in any reasonable way by > true stabs. Meanwhile, some true stabs stuff is produced too, but not used in m3gdb, because > it isn't quite right or helpful. parse.c and m3gdb are highly coupled by all this. Stock gdb's > code to read stabs is augmented by tons of stuff to further decode the M3-specific info > inserted by parse.c, and tons more to interpret it. > > Moreover, debug info and code to be translated effectively become diverging streams in > parse.c, notwithstanding the fact that they are often interspersed. This makes it very > difficult for debug info to reflect anything gcc does to the code. I believe the stabs > info is mostly or entirely untouched after parse.c, though I haven't ever thoroughly > vetted this. > > One specific place where this particularly hurts right now is with nonlocal references, > static links, etc. With the advent of tree-nested.c, in later gcc versions, the runtime > storage model is drastically reworked in gcc, after the stabs has already been produced. > That seriously broke a lot of stuff I had working in m3gdb. I have dabbled with Mickey- > Mouse schemes to emit purely additional stabs info in tree-nested.c, without changing what > was already there, then have m3gdb use it to selectively override the earlier-produced > stabs. I never finished this, and have only limited confidence it is even feasible. > > > 2) An LLVM backend would I suspect have the same lack of m3gdb support as a C backend. > > Does that bother people? > > LLVM has a lot of already provided support for dwarf debug info, keeping it together with code, > and helping to transform it in parallel with code, when optimizations, etc., are done. > Meanwhile, dwarf itself is vastly more complete and appears to me, from superficial study, > to be capable of representing all, or certainly most, of what is needed for good Modula-3 debugging. > For these two reasons, I think LLVM plus dwarf present by far the best method to support > a nice language-specific debugging experience, while leaving massive kludges behind. > > This is one big reason why I support an LLVM back end. It would indeed require significant > work to get debug support. But it would be so much easier and far more pleasant than > the alternatives. That includes even the alternative of further fixing the existing m3gdb/gcc, > which still needs perhaps as much additional work as has already gone into it. I am > attached to it only because it now provides a lot more function than anything else > we have (and which I use a lot). Mucking around in M3ified stabs is, for me, strictly a > destination, not a journey. > > So, the short answer is, it bothers me less than any other option. > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dmuysers at hotmail.com Fri Mar 29 17:58:54 2013 From: dmuysers at hotmail.com (Dirk Muysers) Date: Fri, 29 Mar 2013 17:58:54 +0100 Subject: [M3devel] LLVM backend? In-Reply-To: References: , <51546065.5030709@lcwb.coop> Message-ID: For me, the best debugger architecture still remains the one designed by D.R.Hanson: http://research.microsoft.com/pubs/69690/tr-99-04.pdf platform-independent and easy to implement. From: Jay K Sent: Friday, March 29, 2013 5:09 PM To: Rodney M. Bates ; m3devel Subject: Re: [M3devel] LLVM backend? This doesn't completely make sense to me. But it is kind of what I expected and desire. The debug format isn't the point. parse.c should have no knowledge of dwarf vs. stabs vs. coff vs. xcoff vs. codeview vs. vms vs. anything else. It just happens that the authors found a private channel in stabs. Ideally any debug format used by any C compiler can fully describe C, and Modula-3. The way it (any gcc frontend) is supposed to work is you describe the types using a compiler-internal form, and that gets translated into whatever the user requests that is supported. The primary limit as to what gcc can do is probably the object file format. Any backend without a private channel to the debugger, i.e. the C backend as well as an LLVM backend, will have degraded debugging. Perhaps a private channel can be found either way though. Like, gcc does have this "tfile" thing where after compilation, a separate tool goes over the .S file and makes changes. Ideally we don't have intermediate .S files though. Now, on Windows, for cdb/ntsd/windbg/kd, you can write debugger plugins. .dlls loaded by the debugger that have full access to symbols. They are often very helpful, and would surely help here. I do wonder if it is worth changing TEXT for debuggability. Like, say, to always be flat, no trees, and always nul terminated: (actually I'd always write two zero bytes, in case of viewing the ascii as unicode) #define TEXT_FLAGS_UNICODE (0x00000001) #define TEXT_FLAGS_CONSTANT (0x00000002) typedef struct { size_t flags; size_t length; union { char* ascii; wchar_t* unicode; } data; } *TEXT; ? If we had merely that -- a more debugger/C-idiomatic representation for TEXT, would m3gdb's advantages decline significantly? I'd also be open to just plain typedef char* TEXT; UTF8 encoded. Text.Length is slow, and Text.Concat also slower. But ideally we'd store the length. The length could also be stored before the string. On Windows, "BSTR"s work this way. i.e. it is viable and practical and in wide use. Also, MFC/ATL CStringW/CStringA do this: typedef struct { wchar_t* data; } CStringW; typedef struct { char* data; } CStringA; and then have an entire small struct before the data. It holdes, as I recall, at least the length and a reference count. The strings are reference counted and copy-on-write. It is a nice implementation, but it isn't quite relevant here, since our TEXTs are immutable and garbage collected. The point is though, putting a struct in front of a char*/wchar_t* is viable. As long as the garbage collector doesn't get confused. Anyway, I think I'll start augmenting M3C.m3 to start writing .ll files also. We'll see how that goes. I realize it isn't the ideal path. Wrt nested variables/functions, I make a transform in the C backend. The LLVM backend will need to make a similar transform. I think the frontend should be willing/able to do this transform. It would likely help. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From dabenavidesd at yahoo.es Fri Mar 29 22:24:41 2013 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Fri, 29 Mar 2013 21:24:41 +0000 (GMT) Subject: [M3devel] LLVM backend? In-Reply-To: Message-ID: <1364592281.98024.YahooMailClassic@web172804.mail.ir2.yahoo.com> Hi all: Im starting to get nervous of so many things going on and Cm3 going anywhere. We need to release something rather sooner than later. Thanks in advance --- El vie, 29/3/13, Dirk Muysers escribi?: De: Dirk Muysers Asunto: Re: [M3devel] LLVM backend? Para: m3devel at elegosoft.com, "Jay K" Fecha: viernes, 29 de marzo, 2013 11:58 For me, the best debugger architecture still remains the one designed by D.R.Hanson: ? http://research.microsoft.com/pubs/69690/tr-99-04.pdf ? platform-independent and easy to implement. From: Jay K Sent: Friday, March 29, 2013 5:09 PM To: Rodney M. Bates ; m3devel Subject: Re: [M3devel] LLVM backend? This doesn't completely make sense to me. But it is kind of what I expected and desire. The debug format isn't the point. parse.c should have no knowledge of dwarf vs. stabs vs. coff vs. xcoff vs. codeview vs. vms vs. anything else. It just happens that the authors found a private channel in stabs. Ideally any debug format used by any C compiler can fully describe C, and Modula-3. The way it (any gcc frontend) is supposed to work is you describe the types using a compiler-internal form, and that gets translated into whatever the user requests that is supported. The primary limit as to what gcc can do is probably the object file format. Any backend without a private channel to the debugger, i.e. the C backend as well as an LLVM backend, will have degraded debugging. Perhaps a private channel can be found either way though. Like, gcc does have this "tfile" thing where after compilation, a separate tool goes over the .S file and makes changes. Ideally we don't have intermediate .S files though. Now, on Windows, for cdb/ntsd/windbg/kd, you can write debugger plugins. .dlls loaded by the debugger that have full access to symbols. They are often very helpful, and would surely help here. I do wonder if it is worth changing TEXT for debuggability. Like, say, to always be flat, no trees, and always nul terminated: (actually I'd always write two zero bytes, in case of viewing the ascii as unicode) #define TEXT_FLAGS_UNICODE (0x00000001) #define TEXT_FLAGS_CONSTANT (0x00000002) typedef struct { ??? size_t flags; ??? size_t length; ??? union { ??????? char* ascii; ??????? wchar_t* unicode; ??? } data; } *TEXT; ?? If we had merely that -- a more debugger/C-idiomatic representation for TEXT, would m3gdb's advantages decline significantly? I'd also be open to just plain typedef char* TEXT; UTF8 encoded. Text.Length is slow, and Text.Concat also slower. But ideally we'd store the length. The length could also be stored before the string. On Windows, "BSTR"s work this way. i.e. it is viable and practical and in wide use. Also, MFC/ATL CStringW/CStringA do this: typedef struct { ? wchar_t* data; } CStringW; typedef struct { ? char* data; } CStringA; and then have an entire small struct before the data. It holdes, as I recall, at least the length and a reference count. The strings are reference counted and copy-on-write. It is a nice implementation, but it isn't quite relevant here, since our TEXTs are immutable and garbage collected. The point is though, putting a struct in front of a char*/wchar_t* is viable. As long as the garbage collector doesn't get confused. Anyway, I think I'll start augmenting M3C.m3 to start writing .ll files also. We'll see how that goes. I realize it isn't the ideal path. Wrt nested variables/functions, I make a transform in the C backend. The LLVM backend will need to make a similar transform. I think the frontend should be willing/able to do this transform. It would likely help. ?- Jay ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Sat Mar 30 23:30:53 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sat, 30 Mar 2013 23:30:53 +0100 Subject: [M3devel] LLVM backend? In-Reply-To: <51546065.5030709@lcwb.coop> References: <51546065.5030709@lcwb.coop> Message-ID: I've also skimmed through DWARF last year or something like that? _It is_ more complete than stabs and while (esp m3gdb) stabs are mostly hiding and guarding data from compiler through optimizer and linker to debugger, DWARF is made to enable modification of debug info as code is modified (esp while being optimized). There is no order of magnitude big enough to express its advantage over hacked-in-stabs. -- Dragi?a Duri? dragisha at m3w.org On Mar 28, 2013, at 4:23 PM, Rodney M. Bates wrote: > LLVM has a lot of already provided support for dwarf debug info, keeping it together with code, > and helping to transform it in parallel with code, when optimizations, etc., are done. > Meanwhile, dwarf itself is vastly more complete and appears to me, from superficial study, > to be capable of representing all, or certainly most, of what is needed for good Modula-3 debugging. > For these two reasons, I think LLVM plus dwarf present by far the best method to support > a nice language-specific debugging experience, while leaving massive kludges behind. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Mar 31 01:38:59 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 31 Mar 2013 00:38:59 +0000 Subject: [M3devel] LLVM backend? In-Reply-To: References: , <51546065.5030709@lcwb.coop>, Message-ID: To be clear, changing cm3cg output dwarf is, well, the support is already there, cm3cg -gdwarf or whatever. That isn't the right thing to do though. The right thing is just cm3cg -g or -g2 or whatnot, and let the target-specific default be used. For example, on Darwin it is probably "xcoff", on Cygwin it is probably unfortunately stabs. The key is that we don't describe types in the backend. Our structs are just records with size and no fields, and member/field accesses are done by adding an offset and casting. I started fixing this. It is farther along in the C backend though. The solution isn't to write any code that knows about any debug format. - Jay From: dragisha at m3w.org Date: Sat, 30 Mar 2013 23:30:53 +0100 To: rodney_bates at lcwb.coop CC: m3devel at elegosoft.com Subject: Re: [M3devel] LLVM backend? I've also skimmed through DWARF last year or something like that. _It is_ more complete than stabs and while (esp m3gdb) stabs are mostly hiding and guarding data from compiler through optimizer and linker to debugger, DWARF is made to enable modification of debug info as code is modified (esp while being optimized). There is no order of magnitude big enough to express its advantage over hacked-in-stabs. --Dragi?a Duri?dragisha at m3w.org On Mar 28, 2013, at 4:23 PM, Rodney M. Bates wrote:LLVM has a lot of already provided support for dwarf debug info, keeping it together with code, and helping to transform it in parallel with code, when optimizations, etc., are done. Meanwhile, dwarf itself is vastly more complete and appears to me, from superficial study, to be capable of representing all, or certainly most, of what is needed for good Modula-3 debugging. For these two reasons, I think LLVM plus dwarf present by far the best method to support a nice language-specific debugging experience, while leaving massive kludges behind. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Mar 31 07:10:00 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 31 Mar 2013 05:10:00 +0000 Subject: [M3devel] opaque types again Message-ID: I don't understand opaque types. I do understand the notion of fully opaque types. That are fully revealed in one step. In C this is common: window.h struct Window_t; typedef struct Window_t Window_t; Window_t* Window_Create(); void Window_Show(Window_*t); void Window_Close(Window_*t); long Window_GetHeight(Window_*t); long Window_GetWidth(Window_*t); etc. window.c struct Window_t { ... } /* reveal */ Back to Modula-3... opaque types must be OBJECTs, right? 1. What do they provide vs. more derived types? INTERFACE Animal; TYPE T = OBJECT METHODS makeNoise(); END; INTERFACE AnimalImpl; TYPE T = Animal.T OBJECT METHODS private(); END; If I had an Animal.T and wanted to call private(), wouldn't I just NARROW it to AnimalImpl.T? Is the point that it is more efficient and avoids a runtime type check? INTERFACE Animal; TYPE Public = OBJECT METHODS makeNoise(); END; TYPE T <: Public; INTERFACE AnimalImpl; REVEAL Animal.T = Animal.Public OBJECT METHODS private(); END; ? This way I can import AnimalImpl and then just call private() without a NARROW? 2. Given that the final revelation must be a linear form of all the declared subtypes, I don't understand how the offset used by any module w/o a full revelation could be anything other than zero. I'd like to fully understand this, so I can make the C backend provide maximal type information. More pointers to structs, with members/fields, fewer untyped void*/char*. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Mar 31 08:12:12 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 31 Mar 2013 06:12:12 +0000 Subject: [M3devel] opaque types again In-Reply-To: References: Message-ID: The Green Book's explanation of Rd/Wr might have finally given me the clue I needed. Private <: ROOT; Public = Private OBJECT ... The private part is a prefix of the public part. I still don't see why this is useful, vs. more derived more private types, unless it is to safe runtime casts. I'm trying to put together a small sample to exercise opaque types..and I'm getting: *** *** runtime error: *** A compile-time type is missing. *** I wish it could say which type. :( - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Sun, 31 Mar 2013 05:10:00 +0000 Subject: [M3devel] opaque types again I don't understand opaque types. I do understand the notion of fully opaque types. That are fully revealed in one step. In C this is common: window.h struct Window_t; typedef struct Window_t Window_t; Window_t* Window_Create(); void Window_Show(Window_*t); void Window_Close(Window_*t); long Window_GetHeight(Window_*t); long Window_GetWidth(Window_*t); etc. window.c struct Window_t { ... } /* reveal */ Back to Modula-3... opaque types must be OBJECTs, right? 1. What do they provide vs. more derived types? INTERFACE Animal; TYPE T = OBJECT METHODS makeNoise(); END; INTERFACE AnimalImpl; TYPE T = Animal.T OBJECT METHODS private(); END; If I had an Animal.T and wanted to call private(), wouldn't I just NARROW it to AnimalImpl.T? Is the point that it is more efficient and avoids a runtime type check? INTERFACE Animal; TYPE Public = OBJECT METHODS makeNoise(); END; TYPE T <: Public; INTERFACE AnimalImpl; REVEAL Animal.T = Animal.Public OBJECT METHODS private(); END; ? This way I can import AnimalImpl and then just call private() without a NARROW? 2. Given that the final revelation must be a linear form of all the declared subtypes, I don't understand how the offset used by any module w/o a full revelation could be anything other than zero. I'd like to fully understand this, so I can make the C backend provide maximal type information. More pointers to structs, with members/fields, fewer untyped void*/char*. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Sun Mar 31 18:50:14 2013 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sun, 31 Mar 2013 11:50:14 -0500 Subject: [M3devel] opaque types again In-Reply-To: References: Message-ID: <51586946.6070703@lcwb.coop> On 03/31/2013 12:10 AM, Jay K wrote: > I don't understand opaque types. > It can be tricky. > > I do understand the notion of fully opaque types. That are fully revealed in one step. > In C this is common: > > > window.h > struct Window_t; > typedef struct Window_t Window_t; > Window_t* Window_Create(); > void Window_Show(Window_*t); > void Window_Close(Window_*t); > long Window_GetHeight(Window_*t); > long Window_GetWidth(Window_*t); > etc. > > window.c > struct Window_t { ... } /* reveal */ > > > Back to Modula-3... opaque types must be OBJECTs, right? > It's slightly more liberal than that. They can be any reference type, which includes object types and REF Mumble, for any Mumble. But since the subtype hierarchy has only two levels for REF types (REFANY and REF Mumble), you can only get fully opaque and fully revealed, as in the C example above. > > 1. What do they provide vs. more derived types? > > > INTERFACE Animal; > > TYPE T = OBJECT > METHODS > makeNoise(); > END; > > > INTERFACE AnimalImpl; > > TYPE T = Animal.T OBJECT > METHODS > private(); > END; > > > If I had an Animal.T and wanted to call private(), > wouldn't I just NARROW it to AnimalImpl.T? > If you allocate VAR V : Animal.T := NEW (Animal.T), the result has allocated type Animal.T, not AnimalImpl.T. So it has no method private, and even with AnimalImpl imported, trying to narrow it to AnimalImpl.T will suffer a runtime error. If you do it this way: VAR V : Animal.T := NEW (AnimalImpl.T), V still has static type Animal.T, but its runtime value is (for now, at least) an object with allocated type AnimalImpl.T, which has method private, and you can thus narrow it to AnimalImpl.T and call private. > > Is the point that it is more efficient and avoids > a runtime type check? > That's part of it. > > > INTERFACE Animal; > > TYPE Public = OBJECT > METHODS > makeNoise(); > END; > > TYPE T <: Public; > > INTERFACE AnimalImpl; > > REVEAL Animal.T = Animal.Public OBJECT > METHODS > private(); > END; > > Here, even in a context where it is not revealed, if you allocate VAR V : Animal.T := NEW (Animal.T), the allocated type has method private. Note that Animal.T here is the same type as AnimalImpl.T is in the first example. You just don't know all there is to know about what type that is. So the object still sits in the heap with all the fields and methods of the final type. If you import AnimalImpl, this gives more (static) information about the same type Animal.T instead of just a different type. So the revelation would make it statically legal to call V.private(), without needing a narrow and without a runtime check. It is statically known everywhere Animal is imported, that objects of Animal.T have all the properties of the final revealed type, even though it's not knowy what they all are. Of course, you could also do this: VAR W : Animal.Public := NEW (Animal.Public), and that would behave just like Animal.T of the first example, since those are the same type. Usually, you would probably not want to use Animal.Private in that way. It's something like a variation on the theme of an abstract supertype that you will never allocate. Sometimes I think it would help clarity if you could define a reference type as ABSTRACT, meaning it's illegal to allocate it. But that might open a can of worms in the language. Hmm, maybe I'll work on remembering to write (*ABSTRACT*) OBJECT ... I think I even did that once. > ? > This way I can import AnimalImpl and then just call private() > without a NARROW? > > Yes > > > > 2. Given that the final revelation must be a linear > form of all the declared subtypes, I don't understand > how the offset used by any module w/o a full revelation > could be anything other than zero. > Not sure this helps much, but a complication comes from the fact that you can declare a truly new subtype (not just reveal more about an existing opaque type), in a context where the opaque type is not fully revealed. IMPORT Animal (* The second version of Animal above. *) TYPE Cat = Animal.T OBJECT IsDeclawed : BOOLEAN END; The compiler will not know while separately compiling this, the offset, relative to Animal.T, where new fields of Cat will start. I have never examined the way this is implemented. I would think a typical linker's relocation or external symbol mechanism could be used to add to the offset, a component that is defined in another compilation. I think Tony understands how this is implemented. I have noted that compilations sometimes tell us they are recompiling some module because new opaque information has become available. > > I'd like to fully understand this, so I can make the C backend > provide maximal type information. More pointers to structs, with members/fields, > fewer untyped void*/char*. > If you are hoping to express Modula-3's actual static information hiding in C, I suspect that is a Quixotic quest. At the very least, you would have to replace what is really a flat struct with lots of nesting of structs for the different static visibility groups, which would just hurt readability elsewhere, in references to fields. By definition, it is a lower-level form of code here. I'd just arrange to get the full, flat struct available anywhere it is needed, and rely on the fact that the M3 front end will already have refused to pass down any references to fields that aren't statically legal in the M3 source code. There is certainly no need to get the C compiler to redundantly enforce this. > > Thanks, > - Jay > > From rodney_bates at lcwb.coop Sun Mar 31 19:40:23 2013 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sun, 31 Mar 2013 12:40:23 -0500 Subject: [M3devel] opaque types again --- A Correction In-Reply-To: <51586946.6070703@lcwb.coop> References: <51586946.6070703@lcwb.coop> Message-ID: <51587507.5020603@lcwb.coop> On 03/31/2013 11:50 AM, Rodney M. Bates wrote: > > > On 03/31/2013 12:10 AM, Jay K wrote: >> I don't understand opaque types. >> > > It can be tricky. > >> >> I do understand the notion of fully opaque types. That are fully revealed in one step. >> In C this is common: >> >> >> window.h >> struct Window_t; >> typedef struct Window_t Window_t; >> Window_t* Window_Create(); >> void Window_Show(Window_*t); >> void Window_Close(Window_*t); >> long Window_GetHeight(Window_*t); >> long Window_GetWidth(Window_*t); >> etc. >> >> window.c >> struct Window_t { ... } /* reveal */ >> >> >> Back to Modula-3... opaque types must be OBJECTs, right? >> > > It's slightly more liberal than that. They can be any reference type, which > includes object types and REF Mumble, for any Mumble. But since the subtype > hierarchy has only two levels for REF types (REFANY and REF Mumble), you can > only get fully opaque and fully revealed, as in the C example above. > >> >> 1. What do they provide vs. more derived types? >> >> >> INTERFACE Animal; >> >> TYPE T = OBJECT >> METHODS >> makeNoise(); >> END; >> >> >> INTERFACE AnimalImpl; >> >> TYPE T = Animal.T OBJECT >> METHODS >> private(); >> END; >> >> >> If I had an Animal.T and wanted to call private(), >> wouldn't I just NARROW it to AnimalImpl.T? >> > > If you allocate VAR V : Animal.T := NEW (Animal.T), the result has allocated type Animal.T, not AnimalImpl.T. > So it has no method private, and even with AnimalImpl imported, trying to narrow it to AnimalImpl.T will > suffer a runtime error. > > If you do it this way: VAR V : Animal.T := NEW (AnimalImpl.T), V still has static type Animal.T, but > its runtime value is (for now, at least) an object with allocated type AnimalImpl.T, which has method > private, and you can thus narrow it to AnimalImpl.T and call private. > >> >> Is the point that it is more efficient and avoids >> a runtime type check? >> > > That's part of it. > >> >> >> INTERFACE Animal; >> >> TYPE Public = OBJECT >> METHODS >> makeNoise(); >> END; >> >> TYPE T <: Public; >> >> INTERFACE AnimalImpl; >> >> REVEAL Animal.T = Animal.Public OBJECT >> METHODS >> private(); >> END; >> >> > > Here, even in a context where it is not revealed, if you allocate VAR V : Animal.T := NEW (Animal.T), > the allocated type has method private. Note that Animal.T here is the same type as AnimalImpl.T is > in the first example. You just don't know all there is to know about what type that is. > > So the object still sits in the heap with all the fields and methods of the final type. If you > import AnimalImpl, this gives more (static) information about the same type Animal.T instead of just > a different type. So the revelation would make it statically legal to call V.private(), without needing a > narrow and without a runtime check. It is statically known everywhere Animal is imported, that > objects of Animal.T have all the properties of the final revealed type, even though it's not knowy what > they all are. > > Of course, you could also do this: VAR W : Animal.Public := NEW (Animal.Public), and that would > behave just like Animal.T of the first example, since those are the same type. Usually, you would probably > not want to use Animal.Private in that way. It's something like a variation on the theme of an abstract Animal.Public > supertype that you will never allocate. > > Sometimes I think it would help clarity if you could define a reference type as ABSTRACT, meaning it's > illegal to allocate it. But that might open a can of worms in the language. Hmm, maybe I'll work on > remembering to write (*ABSTRACT*) OBJECT ... I think I even did that once. > >> ? >> This way I can import AnimalImpl and then just call private() >> without a NARROW? >> >> > > Yes > >> >> >> >> 2. Given that the final revelation must be a linear >> form of all the declared subtypes, I don't understand >> how the offset used by any module w/o a full revelation >> could be anything other than zero. >> > > Not sure this helps much, but a complication comes from the fact that you can declare a truly new subtype > (not just reveal more about an existing opaque type), in a context where the opaque type is not fully revealed. > > IMPORT Animal (* The second version of Animal above. *) > TYPE Cat = Animal.T OBJECT > IsDeclawed : BOOLEAN > END; > > The compiler will not know while separately compiling this, the offset, relative to Animal.T, where new fields of > Cat will start. I have never examined the way this is implemented. I would think a typical linker's relocation > or external symbol mechanism could be used to add to the offset, a component that is defined in another compilation. > I think Tony understands how this is implemented. I have noted that compilations sometimes tell us they are > recompiling some module because new opaque information has become available. > >> >> I'd like to fully understand this, so I can make the C backend >> provide maximal type information. More pointers to structs, with members/fields, >> fewer untyped void*/char*. >> > > If you are hoping to express Modula-3's actual static information hiding in C, I suspect that is a Quixotic quest. > At the very least, you would have to replace what is really a flat struct with lots of nesting of structs for > the different static visibility groups, which would just hurt readability elsewhere, in references to fields. > By definition, it is a lower-level form of code here. I'd just arrange to get the full, flat struct available > anywhere it is needed, and rely on the fact that the M3 front end will already have refused to pass down any > references to fields that aren't statically legal in the M3 source code. There is certainly no need to get > the C compiler to redundantly enforce this. > >> >> Thanks, >> - Jay >> >> > > From jay.krell at cornell.edu Sun Mar 31 21:54:28 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 31 Mar 2013 19:54:28 +0000 Subject: [M3devel] opaque types again --- A Correction In-Reply-To: <51587507.5020603@lcwb.coop> References: , <51586946.6070703@lcwb.coop>, <51587507.5020603@lcwb.coop> Message-ID: > If you allocate VAR V : Animal.T := NEW (Animal.T), > the result has allocated type Animal.T, not AnimalImpl.T. > So it has no method private, and even with AnimalImpl > imported, trying to narrow it to AnimalImpl.T will > suffer a runtime error. Sure, "creation is special" and "plain NEW doesn't necessarily suffice". One would have INTERFACE Animal or AnimalImpl; PROCEDURE Create(): Animal.T; MODULE AnimalImpl; PROCEDURE Create(): Animal.T = BEGIN RETURN NEW(AnimalTimpl.T); END Create; > I have noted that compilations sometimes tell us they are > recompiling some module because new opaque information has become available. Me too. And it appears this is an optional optimization. It initially compiles to something less efficient but correct. Then recompiles to something more efficient. > I'd just arrange to get the full, flat struct available anywhere it is needed If I can, then yes, agreed. I don't desire to hide information from the C compiler or debugger. In fact, there are related aspects of C++ that do hide too much from the debugger (e.g. COM -- all I can see in the debugger is the vtable and function pointers, instead of the debugger introspecting the most derived type and showing all the data members...) > I have never examined the way this is implemented. The generated C for my test case is surprising, very inefficient. In Main.m3 just to get the address of a.a involves like two lookups of static type data. What was the correction? Thanks, - Jay > Date: Sun, 31 Mar 2013 12:40:23 -0500 > From: rodney_bates at lcwb.coop > To: m3devel at elegosoft.com > Subject: Re: [M3devel] opaque types again --- A Correction > > > > On 03/31/2013 11:50 AM, Rodney M. Bates wrote: > > > > > > On 03/31/2013 12:10 AM, Jay K wrote: > >> I don't understand opaque types. > >> > > > > It can be tricky. > > > >> > >> I do understand the notion of fully opaque types. That are fully revealed in one step. > >> In C this is common: > >> > >> > >> window.h > >> struct Window_t; > >> typedef struct Window_t Window_t; > >> Window_t* Window_Create(); > >> void Window_Show(Window_*t); > >> void Window_Close(Window_*t); > >> long Window_GetHeight(Window_*t); > >> long Window_GetWidth(Window_*t); > >> etc. > >> > >> window.c > >> struct Window_t { ... } /* reveal */ > >> > >> > >> Back to Modula-3... opaque types must be OBJECTs, right? > >> > > > > It's slightly more liberal than that. They can be any reference type, which > > includes object types and REF Mumble, for any Mumble. But since the subtype > > hierarchy has only two levels for REF types (REFANY and REF Mumble), you can > > only get fully opaque and fully revealed, as in the C example above. > > > >> > >> 1. What do they provide vs. more derived types? > >> > >> > >> INTERFACE Animal; > >> > >> TYPE T = OBJECT > >> METHODS > >> makeNoise(); > >> END; > >> > >> > >> INTERFACE AnimalImpl; > >> > >> TYPE T = Animal.T OBJECT > >> METHODS > >> private(); > >> END; > >> > >> > >> If I had an Animal.T and wanted to call private(), > >> wouldn't I just NARROW it to AnimalImpl.T? > >> > > > > If you allocate VAR V : Animal.T := NEW (Animal.T), the result has allocated type Animal.T, not AnimalImpl.T. > > So it has no method private, and even with AnimalImpl imported, trying to narrow it to AnimalImpl.T will > > suffer a runtime error. > > > > If you do it this way: VAR V : Animal.T := NEW (AnimalImpl.T), V still has static type Animal.T, but > > its runtime value is (for now, at least) an object with allocated type AnimalImpl.T, which has method > > private, and you can thus narrow it to AnimalImpl.T and call private. > > > >> > >> Is the point that it is more efficient and avoids > >> a runtime type check? > >> > > > > That's part of it. > > > >> > >> > >> INTERFACE Animal; > >> > >> TYPE Public = OBJECT > >> METHODS > >> makeNoise(); > >> END; > >> > >> TYPE T <: Public; > >> > >> INTERFACE AnimalImpl; > >> > >> REVEAL Animal.T = Animal.Public OBJECT > >> METHODS > >> private(); > >> END; > >> > >> > > > > Here, even in a context where it is not revealed, if you allocate VAR V : Animal.T := NEW (Animal.T), > > the allocated type has method private. Note that Animal.T here is the same type as AnimalImpl.T is > > in the first example. You just don't know all there is to know about what type that is. > > > > So the object still sits in the heap with all the fields and methods of the final type. If you > > import AnimalImpl, this gives more (static) information about the same type Animal.T instead of just > > a different type. So the revelation would make it statically legal to call V.private(), without needing a > > narrow and without a runtime check. It is statically known everywhere Animal is imported, that > > objects of Animal.T have all the properties of the final revealed type, even though it's not knowy what > > they all are. > > > > Of course, you could also do this: VAR W : Animal.Public := NEW (Animal.Public), and that would > > behave just like Animal.T of the first example, since those are the same type. Usually, you would probably > > not want to use Animal.Private in that way. It's something like a variation on the theme of an abstract > Animal.Public > > supertype that you will never allocate. > > > > Sometimes I think it would help clarity if you could define a reference type as ABSTRACT, meaning it's > > illegal to allocate it. But that might open a can of worms in the language. Hmm, maybe I'll work on > > remembering to write (*ABSTRACT*) OBJECT ... I think I even did that once. > > > >> ? > >> This way I can import AnimalImpl and then just call private() > >> without a NARROW? > >> > >> > > > > Yes > > > >> > >> > >> > >> 2. Given that the final revelation must be a linear > >> form of all the declared subtypes, I don't understand > >> how the offset used by any module w/o a full revelation > >> could be anything other than zero. > >> > > > > Not sure this helps much, but a complication comes from the fact that you can declare a truly new subtype > > (not just reveal more about an existing opaque type), in a context where the opaque type is not fully revealed. > > > > IMPORT Animal (* The second version of Animal above. *) > > TYPE Cat = Animal.T OBJECT > > IsDeclawed : BOOLEAN > > END; > > > > The compiler will not know while separately compiling this, the offset, relative to Animal.T, where new fields of > > Cat will start. I have never examined the way this is implemented. I would think a typical linker's relocation > > or external symbol mechanism could be used to add to the offset, a component that is defined in another compilation. > > I think Tony understands how this is implemented. I have noted that compilations sometimes tell us they are > > recompiling some module because new opaque information has become available. > > > >> > >> I'd like to fully understand this, so I can make the C backend > >> provide maximal type information. More pointers to structs, with members/fields, > >> fewer untyped void*/char*. > >> > > > > If you are hoping to express Modula-3's actual static information hiding in C, I suspect that is a Quixotic quest. > > At the very least, you would have to replace what is really a flat struct with lots of nesting of structs for > > the different static visibility groups, which would just hurt readability elsewhere, in references to fields. > > By definition, it is a lower-level form of code here. I'd just arrange to get the full, flat struct available > > anywhere it is needed, and rely on the fact that the M3 front end will already have refused to pass down any > > references to fields that aren't statically legal in the M3 source code. There is certainly no need to get > > the C compiler to redundantly enforce this. > > > >> > >> Thanks, > >> - Jay > >> > >> > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Tue Mar 5 06:33:13 2013 From: jay.krell at cornell.edu (Jay K) Date: Tue, 5 Mar 2013 05:33:13 +0000 Subject: [M3devel] cg.declare_subrange should pass on cgtype Message-ID: cg.declare_subrange should include the cgtype the frontend is going to use for the type. I'm pretty darn certain of this. Otherwise a backend very might want/need to duplicate the logic in m3front/types/SubrangeType.m3 SetRep. The logic isn't that complicated, but really, declare_subrange should take the information. I intend to write and commit that either tonight or within a week. I assume this is ok..as I'm pretty certain of it.. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Tue Mar 5 06:56:39 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 5 Mar 2013 16:56:39 +1100 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: References: Message-ID: Isn?t it already there (implicitly) in the bitsize to be used to represent the range? The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64). The backend is supposed to respect the bitsize. So, why do you need to duplicate that information? On Mar 5, 2013, at 4:33 PM, Jay K wrote: > cg.declare_subrange should include the cgtype the frontend > is going to use for the type. > > > I'm pretty darn certain of this. > > > Otherwise a backend very might want/need to duplicate > the logic in m3front/types/SubrangeType.m3 SetRep. > > The logic isn't that complicated, but really, declare_subrange > should take the information. > > I intend to write and commit that either tonight or within a week. > I assume this is ok..as I'm pretty certain of it.. > > > - Jay > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Tue Mar 5 07:29:34 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 5 Mar 2013 17:29:34 +1100 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com> References: <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com> Message-ID: Signedness should be irrelevant. It is only the storage that is specified by this. The interpretation of the bits, including signed/unsigned, is in the operations performed on those bits. e.g., load 8 bits sign extended. Why do you need to know the signedness? Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Mobile +1 765 427 5484 On Mar 5, 2013, at 5:21 PM, Jay wrote: > Close, but also signedness. > > - Jay > > On Mar 4, 2013, at 9:56 PM, Tony Hosking wrote: > >> Isn?t it already there (implicitly) in the bitsize to be used to represent the range? >> The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64). >> The backend is supposed to respect the bitsize. >> So, why do you need to duplicate that information? >> >> On Mar 5, 2013, at 4:33 PM, Jay K wrote: >> >>> cg.declare_subrange should include the cgtype the frontend >>> is going to use for the type. >>> >>> >>> I'm pretty darn certain of this. >>> >>> >>> Otherwise a backend very might want/need to duplicate >>> the logic in m3front/types/SubrangeType.m3 SetRep. >>> >>> The logic isn't that complicated, but really, declare_subrange >>> should take the information. >>> >>> I intend to write and commit that either tonight or within a week. >>> I assume this is ok..as I'm pretty certain of it.. >>> >>> >>> - Jay >>> >>> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Tue Mar 5 07:21:25 2013 From: jay.krell at cornell.edu (Jay) Date: Mon, 4 Mar 2013 22:21:25 -0800 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: References: Message-ID: <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com> Close, but also signedness. - Jay On Mar 4, 2013, at 9:56 PM, Tony Hosking wrote: > Isn?t it already there (implicitly) in the bitsize to be used to represent the range? > The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64). > The backend is supposed to respect the bitsize. > So, why do you need to duplicate that information? > > On Mar 5, 2013, at 4:33 PM, Jay K wrote: > >> cg.declare_subrange should include the cgtype the frontend >> is going to use for the type. >> >> >> I'm pretty darn certain of this. >> >> >> Otherwise a backend very might want/need to duplicate >> the logic in m3front/types/SubrangeType.m3 SetRep. >> >> The logic isn't that complicated, but really, declare_subrange >> should take the information. >> >> I intend to write and commit that either tonight or within a week. >> I assume this is ok..as I'm pretty certain of it.. >> >> >> - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Tue Mar 5 14:30:08 2013 From: jay.krell at cornell.edu (Jay) Date: Tue, 5 Mar 2013 05:30:08 -0800 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: References: <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com> Message-ID: I want to view the value in a debugger. Without having to cast it. By your reasoning, for record fields, among float, double, int32, int64, uint32, uint64, we'd only need 2. We want strong accurate types in "declare", not just operations like "add". Declare_subrange: is there a point to domain_type? I.e. how about declare_subrange(cgtype, min, max)? I'd have to see if cm3cg and then m3gdb use it. - Jay On Mar 4, 2013, at 10:29 PM, Tony Hosking wrote: > Signedness should be irrelevant. > It is only the storage that is specified by this. > The interpretation of the bits, including signed/unsigned, is in the operations performed on those bits. > e.g., load 8 bits sign extended. > > Why do you need to know the signedness? > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Mobile +1 765 427 5484 > > > > > > On Mar 5, 2013, at 5:21 PM, Jay wrote: > >> Close, but also signedness. >> >> - Jay >> >> On Mar 4, 2013, at 9:56 PM, Tony Hosking wrote: >> >>> Isn?t it already there (implicitly) in the bitsize to be used to represent the range? >>> The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64). >>> The backend is supposed to respect the bitsize. >>> So, why do you need to duplicate that information? >>> >>> On Mar 5, 2013, at 4:33 PM, Jay K wrote: >>> >>>> cg.declare_subrange should include the cgtype the frontend >>>> is going to use for the type. >>>> >>>> >>>> I'm pretty darn certain of this. >>>> >>>> >>>> Otherwise a backend very might want/need to duplicate >>>> the logic in m3front/types/SubrangeType.m3 SetRep. >>>> >>>> The logic isn't that complicated, but really, declare_subrange >>>> should take the information. >>>> >>>> I intend to write and commit that either tonight or within a week. >>>> I assume this is ok..as I'm pretty certain of it.. >>>> >>>> >>>> - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Mar 7 03:50:25 2013 From: jay.krell at cornell.edu (Jay K) Date: Thu, 7 Mar 2013 02:50:25 +0000 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: References: , , <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com>, , Message-ID: For now I'll just check if min < 0, like cm3cg does. m3gdb does not appear to use or parse out domain_typeid. domain_typeid doesn't seem needed. I think this stuff was clearly done slightly incorrectly in the first place. Not a huge mistake. There is also wierdness imho around empty subranges. i.e. it is an unobvious language detail. If it were up to me, [10..0] would either be illegal, OR would be the same as [0..10], OR would contain the same elements as [0..10] but would iterate in reverse FOR i := FIRST([10..0]) TO LAST([10..0]) would be equivalent to FOR i := 10 to 0 BY -1. However, it not any of those. It is legal and "empty". The FOR loop, I believe, never runs. NUMBER of such an array is 0. - Jay From: jay.krell at cornell.edu Date: Tue, 5 Mar 2013 05:30:08 -0800 To: hosking at cs.purdue.edu CC: m3devel at elegosoft.com; jay.krell at cornell.edu Subject: Re: [M3devel] cg.declare_subrange should pass on cgtype I want to view the value in a debugger. Without having to cast it. By your reasoning, for record fields, among float, double, int32, int64, uint32, uint64, we'd only need 2. We want strong accurate types in "declare", not just operations like "add". Declare_subrange: is there a point to domain_type? I.e. how about declare_subrange(cgtype, min, max)? I'd have to see if cm3cg and then m3gdb use it. - Jay On Mar 4, 2013, at 10:29 PM, Tony Hosking wrote: Signedness should be irrelevant. It is only the storage that is specified by this.The interpretation of the bits, including signed/unsigned, is in the operations performed on those bits.e.g., load 8 bits sign extended. Why do you need to know the signedness? Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAMobile +1 765 427 5484 On Mar 5, 2013, at 5:21 PM, Jay wrote:Close, but also signedness. - Jay On Mar 4, 2013, at 9:56 PM, Tony Hosking wrote: Isn?t it already there (implicitly) in the bitsize to be used to represent the range?The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64).The backend is supposed to respect the bitsize.So, why do you need to duplicate that information? On Mar 5, 2013, at 4:33 PM, Jay K wrote:cg.declare_subrange should include the cgtype the frontend is going to use for the type. I'm pretty darn certain of this. Otherwise a backend very might want/need to duplicate the logic in m3front/types/SubrangeType.m3 SetRep. The logic isn't that complicated, but really, declare_subrange should take the information. I intend to write and commit that either tonight or within a week. I assume this is ok..as I'm pretty certain of it.. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Mar 7 09:05:43 2013 From: jay.krell at cornell.edu (Jay K) Date: Thu, 7 Mar 2013 08:05:43 +0000 Subject: [M3devel] funding for one full time developer? Message-ID: So...crazy self-serving question..is there enough interest and commercial use of Modula-3..such as to fund Modula-3 development? One full time developer? Me? I realize Critical Mass already tried. I do quite enjoy working on this stuff, but I don't have enough time for it. :( Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From wagner at elego.de Thu Mar 7 13:49:50 2013 From: wagner at elego.de (Olaf Wagner) Date: Thu, 7 Mar 2013 13:49:50 +0100 Subject: [M3devel] funding for one full time developer? In-Reply-To: References: Message-ID: <20130307134950.96fff38a.wagner@elego.de> On Thu, 7 Mar 2013 08:05:43 +0000 Jay K wrote: > So...crazy self-serving question..is there enough > interest and commercial use of Modula-3..such > as to fund Modula-3 development? One full time developer? Me? > > I realize Critical Mass already tried. > > I do quite enjoy working on this stuff, but I don't have enough time for it. :( Elego has never been able to find any customer willing to pay some money for M3 support or M3-related work. From a commercial point of view, our M3 engagement hasn't been a huge success ;-) I love the language and I'd really like to see it more widely used, but I'm afraid there won't be enough interest. Olaf -- Olaf Wagner -- elego Software Solutions GmbH -- http://www.elegosoft.com Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 Gesch?ftsf?hrer: Michael Diers, Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From dabenavidesd at yahoo.es Sat Mar 9 19:46:49 2013 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sat, 9 Mar 2013 18:46:49 +0000 (GMT) Subject: [M3devel] funding for one full time developer? In-Reply-To: <20130307134950.96fff38a.wagner@elego.de> Message-ID: <1362854809.42539.YahooMailClassic@web133101.mail.ir2.yahoo.com> Hi all: I disagree, there are commercial projects and industrial research projects using it, problem is normally are industrial TOP secrets. Nobody else means anymore I don't agree. Thing is normally they use their in-house compiler, Elego could find the tool chain set to sell to a given company but that company might have the most part of it already. If all projects were open I'm sure M3 will be much an open place to have experience on. I would go to work in a research project for veryfing compiler strategy for TOP industries consortium. But we would need big hackers as you and brilliant minds as Hendrik, perhaps, maybe some spot for me there, but don't count with me. Research labs were the main development sandbox for Modula-3 and continue to be for years to come. Thanks in advance --- El jue, 7/3/13, Olaf Wagner escribi?: De: Olaf Wagner Asunto: Re: [M3devel] funding for one full time developer? Para: "Jay K" CC: "m3devel" Fecha: jueves, 7 de marzo, 2013 07:49 On Thu, 7 Mar 2013 08:05:43 +0000 Jay K wrote: > So...crazy self-serving question..is there enough > interest and commercial use of Modula-3..such > as to fund Modula-3 development? One full time developer? Me? > > I realize Critical Mass already tried. > > I do quite enjoy working on this stuff, but I don't have enough time for it. :( Elego has never been able to find any customer willing to pay some money for M3 support or M3-related work. >From a commercial point of view, our M3 engagement hasn't been a huge success ;-) I love the language and I'd really like to see it more widely used, but I'm afraid there won't be enough interest. Olaf -- Olaf Wagner -- elego Software Solutions GmbH -- http://www.elegosoft.com ? ? ? ? ? ? ???Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96? mobile: +49 177 2345 869? fax: +49 30 23 45 86 95 Gesch?ftsf?hrer: Michael Diers, Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 -------------- next part -------------- An HTML attachment was scrubbed... URL: From rcolebur at SCIRES.COM Tue Mar 12 03:25:01 2013 From: rcolebur at SCIRES.COM (Coleburn, Randy) Date: Tue, 12 Mar 2013 02:25:01 +0000 Subject: [M3devel] funding for one full time developer? Message-ID: <0BB8FA59C2932741A3A2941A8B9D8BFF0C252968@ATLEX04-SRV.SCIRES.LOCAL> My company was one of the first customers for Critical Mass. We also funded some development of custom modules. I'm still a huge fan of the Modula-3 language and it is my first choice for any software development task. Alas, I don't get paid to do much software development anymore, so most of my work these days is for my own purposes, and support of prior projects. Regards, Randy Coleburn -----Original Message----- From: Olaf Wagner [mailto:wagner at elego.de] Sent: Thursday, March 07, 2013 7:50 AM To: Jay K Cc: m3devel Subject: EXT:Re: [M3devel] funding for one full time developer? On Thu, 7 Mar 2013 08:05:43 +0000 Jay K wrote: > So...crazy self-serving question..is there enough interest and > commercial use of Modula-3..such as to fund Modula-3 development? One > full time developer? Me? > > I realize Critical Mass already tried. > > I do quite enjoy working on this stuff, but I don't have enough time > for it. :( Elego has never been able to find any customer willing to pay some money for M3 support or M3-related work. >From a commercial point of view, our M3 engagement hasn't been a huge success ;-) I love the language and I'd really like to see it more widely used, but I'm afraid there won't be enough interest. Olaf -- Olaf Wagner -- elego Software Solutions GmbH -- http://www.elegosoft.com Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 Gesch?ftsf?hrer: Michael Diers, Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Tue Mar 12 06:31:13 2013 From: jay.krell at cornell.edu (Jay K) Date: Tue, 12 Mar 2013 05:31:13 +0000 Subject: [M3devel] load and store should take TypeUID parameters Message-ID: load and store should take TypeUID parameters There are multiple reasons for this. Given: TYPE Color = {Red,Blue}; PROCEDURE P1() = VAR v1 := Color.Red; BEGIN END P1; I would like to generate: preamble in all files: typedef unsigned char UINT8; typedef unsigned short UINT16; typedef unsigned int UINT32; typedef unsigned long long UINT64; (This is not quite right.) #if __GNUC__ /* >= ? */ #define M3_ENUM_SIZE #define M3_ENUM_MODE8 __attribute__((__mode__(__QI__))) #define M3_ENUM_MODE16 __attribute__((__mode__(__HI__))) #define M3_ENUM_MODE32 __attribute__((__mode__(__SI__))) #define M3_ENUM_MODE64 __attribute__((__mode__(__DI__))) #else #define M3_ENUM_MODE8 /* nothing */ #define M3_ENUM_MODE16 /* nothing */ #define M3_ENUM_MODE32 /* nothing */ #define M3_ENUM_MODE64 /* nothing */ #endif #if _MSC_VER >= 1400 && defined(__cplusplus) #define M3_ENUM_SIZE #define M3_ENUM_BASE8 : UINT8 #define M3_ENUM_BASE16 : UINT16 #define M3_ENUM_BASE32 : UINT32 #define M3_ENUM_BASE64 : UINT64 #else #define M3_ENUM_BASE8 /* nothing */ #define M3_ENUM_BASE16 /* nothing */ #define M3_ENUM_BASE32 /* nothing */ #define M3_ENUM_BASE64 /* nothing */ #endif and then: given TypeUID = 123 // declare enum #if M3_ENUM_SIZE M3_ENUM_MODE8 enum M123 M3_ENUM_MODE8 { M123_Red, M123_Blue, M123_Green }; #else typedef UINT8 M123; #define M123_Red ((M123)0) #define M123_Blue ((M123)1) #define M123_Green ((M123)2) #endif // declare typename typedef M123 Color; // smart compiler recognizes left and right are enums perhaps and therefore: #define Color_Red M123_Red #define Color_Blue M123_Blue #define Color_Green M123_Green Color v1 = M123_Red; or perhaps: Color v1 = Color_Red; or perhaps merely: Color v1 = (Color)0; and really, ideally NOT Color v1; *(UINT8*)&v1 = (UINT8)0; The readability of the right hand side isn't the most critical. What is more critical is the readability of v1 in a debugger. The last form is what we are stuck with. Similarly, given: PROCEDURE P2(VAR a: INTEGER); PROCEDURE P3(VAR a: INTEGER) = BEGIN P2(b); END P3; I want: void P2(INTEGER* a); void P3(INTEGER* a) { P2(a); } no casts. Today, I make all pointers "ADDRESS" which is void* or char*. I don't remember all the reasons why. I guess I should just get over the cast happiness and ugly C implied by using C as a backend. But I do want things to look right in a debugger. I'll iterate more..later... - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael.anderson at elegosoft.com Wed Mar 13 12:10:30 2013 From: michael.anderson at elegosoft.com (Michael Anderson) Date: Wed, 13 Mar 2013 12:10:30 +0100 Subject: [M3devel] [elego Server Maintenance 13.03.2013 21:30] Message-ID: <51405EA6.6010700@elegosoft.com> Hello, On Wednesday, March 13 at 9:30 PM, we will perform scheduled maintenance on our servers. The following sites will be affected: mail.elegosoft.com gitolite.elegosoft.com servicedesk-intern.elegosoft.com cm3-bugs.elegosoft.com projects.elegosoft.com plane.elego.de Brief interruptions of service may occur. Expected duration: 120 Min. We apologize for any inconvenience. - the elego Admins am Mittwoch, den 13.03, werden ab 21.30 Uhr planm??ige Wartungsma?nahmen an unseren Servern durchgef?hrt. Folgende Dienste werden davon betroffen: mail.elegosoft.com gitolite.elegosoft.com servicedesk-intern.elegosoft.com cm3-bugs.elegosoft.com projects.elegosoft.com plane.elego.de Es kann zur kurzzeitigen Unterbrechung mancher Dienste kommen. Voraussichtliche Dauer der Wartung: 120 Min. Wir bitten um Verst?ndnis. - die elego Admins -- Michael Anderson IT Services & Support elego Software Solutions GmbH Gustav-Meyer-Allee 25 Building 12.3 (BIG) room 227 13355 Berlin, Germany phone +49 30 23 45 86 96 michael.anderson at elegosoft.com fax +49 30 23 45 86 95 http://www.elegosoft.com Geschaeftsfuehrer: Olaf Wagner, Sitz Berlin Amtsgericht Berlin-Charlottenburg, HRB 77719, USt-IdNr: DE163214194 From dragisha at m3w.org Sun Mar 17 00:34:58 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sun, 17 Mar 2013 00:34:58 +0100 Subject: [M3devel] Interfacing to OSX Core Foundation classes Message-ID: <00DDEDB6-B1B6-45AF-9C97-62E86CD76011@m3w.org> To resolve an issue with a project, I need to wrap few functions from Security framework on OSX Lion. I have no experience on this level with OSX programming. I did a lot of such work on Linux and Windows, and all I needed there is to match signatures of functions, structure of types, and refer m3makefile to right libraries. Also, I did similar work for various non-framework libraries on OSX, and it is Unix all the way. Anyone with CF/framework related experience? Do I need some special voodoo for handling various CF opaque objects or they are simple addresses? TIA, dd -- Divided by a common language Dragi?a Duri? dragisha at m3w.org -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 495 bytes Desc: Message signed with OpenPGP using GPGMail URL: From jay.krell at cornell.edu Sun Mar 17 07:22:27 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 17 Mar 2013 06:22:27 +0000 Subject: [M3devel] unresponsiveness to control-c and control-z Message-ID: cm3's unresponsiveness to control-c and control-z, and slowness exiting from assertion failures, is a significant drain on my time. I don't know if it is Darwin specific, with its direct suspension, or if all cm3 targets have this behavior. But it really needs to be fixed. Perhaps cooperative suspend is the answer. But I'd like it fixed soon. Please. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Sun Mar 17 15:12:07 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sun, 17 Mar 2013 15:12:07 +0100 Subject: [M3devel] Interfacing to OSX Core Foundation classes In-Reply-To: <91C3D6A3-39E1-4387-B16B-1E3CEACA8FA4@gmail.com> References: <00DDEDB6-B1B6-45AF-9C97-62E86CD76011@m3w.org> <91C3D6A3-39E1-4387-B16B-1E3CEACA8FA4@gmail.com> Message-ID: <0D261766-55B8-4468-BDE2-CADA4A1BAE4D@m3w.org> After a hint from Anthony, and a share of mining, mostly due to being first-time OSX Doc Miner :), here comes result. Example code: == CoureFoundation.i3 == INTERFACE CoreFoundation; IMPORT Ctypes; TYPE TypeRef = ADDRESS; DataRef = ADDRESS; AllocatorRef = ADDRESS; Index = Ctypes.long_int; <* EXTERNAL CFRelease *> PROCEDURE Release(cf: TypeRef); <* EXTERNAL CFDataCreate *> PROCEDURE DataCreate(allocator: AllocatorRef; bytes: Ctypes.void_star; length: Index): DataRef; (* Not exactly CF, but I can split later, if need be to grow this *) END CoreFoundation. == m3makefile == ? proc use_framework(FW) is configure_c_compiler() SYSTEM_CC = SYSTEM_CC & " -framework " & FW end if equal(TARGET, "AMD64_DARWIN") use_framework("CoreFoundation") use_framework("Security") ... === I named things like this so I can "IMPORT CoreFoundation AS CF" later and use names like CF.Release(). Hope it saves few hours to somebody else :). -- Divided by a common language Dragi?a Duri? dragisha at m3w.org On Mar 17, 2013, at 3:37 AM, Antony Hosking wrote: > Should be simple addresses. > > > On Mar 16, 2013, at 6:34 PM, Dragi?a Duri? wrote: > >> To resolve an issue with a project, I need to wrap few functions from Security framework on OSX Lion. I have no experience on this level with OSX programming. >> >> I did a lot of such work on Linux and Windows, and all I needed there is to match signatures of functions, structure of types, and refer m3makefile to right libraries. Also, I did similar work for various non-framework libraries on OSX, and it is Unix all the way. >> >> Anyone with CF/framework related experience? Do I need some special voodoo for handling various CF opaque objects or they are simple addresses? >> >> TIA, >> dd >> >> -- >> Divided by a common language >> >> Dragi?a Duri? >> dragisha at m3w.org >> >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Sun Mar 17 16:24:55 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sun, 17 Mar 2013 16:24:55 +0100 Subject: [M3devel] Interfacing to OSX Core Foundation classes In-Reply-To: <52ED640E-5B43-428E-8186-7C8C7BBBF64B@darko.org> References: <00DDEDB6-B1B6-45AF-9C97-62E86CD76011@m3w.org> <91C3D6A3-39E1-4387-B16B-1E3CEACA8FA4@gmail.com> <0D261766-55B8-4468-BDE2-CADA4A1BAE4D@m3w.org> <52ED640E-5B43-428E-8186-7C8C7BBBF64B@darko.org> Message-ID: <93E972AD-5AC4-45DE-947F-FBC89E392E6E@m3w.org> My problem did not involve Objective-C, just C API's, CoreFoundation and Security were involved. I took only what I needed. Your Carbon interface is welcome - I would like to learn more about topic, as I never know when I will need it. I like to be prepared! :) Thanks in advance, dd -- Divided by a common language Dragi?a Duri? dragisha at m3w.org On Mar 17, 2013, at 4:05 PM, Darko wrote: > But what about creating objects and calling methods, or whatever they're called in Objective-C? > > Also be aware if you want to use any structures from the older interfaces and Carbon they have byte alignment and must be declared specially. I have an interface file for most Carbon stuff, but it's a bit large at 3.2MB (~500KB compressed). I can mail it if you need it. > > > On Mar 17, 2013, at 7:12 AM, Dragi?a Duri? wrote: > >> After a hint from Anthony, and a share of mining, mostly due to being first-time OSX Doc Miner :), here comes result. Example code: >> >> == CoureFoundation.i3 == >> INTERFACE CoreFoundation; >> >> IMPORT Ctypes; >> >> TYPE >> TypeRef = ADDRESS; >> DataRef = ADDRESS; >> AllocatorRef = ADDRESS; >> Index = Ctypes.long_int; >> >> <* EXTERNAL CFRelease *> >> PROCEDURE Release(cf: TypeRef); >> >> <* EXTERNAL CFDataCreate *> >> PROCEDURE DataCreate(allocator: AllocatorRef; bytes: Ctypes.void_star; length: Index): DataRef; >> >> (* Not exactly CF, but I can split later, if need be to grow this >> *) >> >> END CoreFoundation. >> == m3makefile == >> ? >> proc use_framework(FW) is >> configure_c_compiler() >> SYSTEM_CC = SYSTEM_CC & " -framework " & FW >> end >> >> if equal(TARGET, "AMD64_DARWIN") >> use_framework("CoreFoundation") >> use_framework("Security") >> ... >> === >> >> I named things like this so I can "IMPORT CoreFoundation AS CF" later and use names like CF.Release(). >> >> Hope it saves few hours to somebody else :). >> -- >> Divided by a common language >> >> Dragi?a Duri? >> dragisha at m3w.org >> >> >> >> >> On Mar 17, 2013, at 3:37 AM, Antony Hosking wrote: >> >>> Should be simple addresses. >>> >>> >>> On Mar 16, 2013, at 6:34 PM, Dragi?a Duri? wrote: >>> >>>> To resolve an issue with a project, I need to wrap few functions from Security framework on OSX Lion. I have no experience on this level with OSX programming. >>>> >>>> I did a lot of such work on Linux and Windows, and all I needed there is to match signatures of functions, structure of types, and refer m3makefile to right libraries. Also, I did similar work for various non-framework libraries on OSX, and it is Unix all the way. >>>> >>>> Anyone with CF/framework related experience? Do I need some special voodoo for handling various CF opaque objects or they are simple addresses? >>>> >>>> TIA, >>>> dd >>>> >>>> -- >>>> Divided by a common language >>>> >>>> Dragi?a Duri? >>>> dragisha at m3w.org >>>> >>>> >>>> >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From darko at darko.org Sun Mar 17 16:05:57 2013 From: darko at darko.org (Darko) Date: Sun, 17 Mar 2013 08:05:57 -0700 Subject: [M3devel] Interfacing to OSX Core Foundation classes In-Reply-To: <0D261766-55B8-4468-BDE2-CADA4A1BAE4D@m3w.org> References: <00DDEDB6-B1B6-45AF-9C97-62E86CD76011@m3w.org> <91C3D6A3-39E1-4387-B16B-1E3CEACA8FA4@gmail.com> <0D261766-55B8-4468-BDE2-CADA4A1BAE4D@m3w.org> Message-ID: <52ED640E-5B43-428E-8186-7C8C7BBBF64B@darko.org> But what about creating objects and calling methods, or whatever they're called in Objective-C? Also be aware if you want to use any structures from the older interfaces and Carbon they have byte alignment and must be declared specially. I have an interface file for most Carbon stuff, but it's a bit large at 3.2MB (~500KB compressed). I can mail it if you need it. On Mar 17, 2013, at 7:12 AM, Dragi?a Duri? wrote: > After a hint from Anthony, and a share of mining, mostly due to being first-time OSX Doc Miner :), here comes result. Example code: > > == CoureFoundation.i3 == > INTERFACE CoreFoundation; > > IMPORT Ctypes; > > TYPE > TypeRef = ADDRESS; > DataRef = ADDRESS; > AllocatorRef = ADDRESS; > Index = Ctypes.long_int; > > <* EXTERNAL CFRelease *> > PROCEDURE Release(cf: TypeRef); > > <* EXTERNAL CFDataCreate *> > PROCEDURE DataCreate(allocator: AllocatorRef; bytes: Ctypes.void_star; length: Index): DataRef; > > (* Not exactly CF, but I can split later, if need be to grow this > *) > > END CoreFoundation. > == m3makefile == > ? > proc use_framework(FW) is > configure_c_compiler() > SYSTEM_CC = SYSTEM_CC & " -framework " & FW > end > > if equal(TARGET, "AMD64_DARWIN") > use_framework("CoreFoundation") > use_framework("Security") > ... > === > > I named things like this so I can "IMPORT CoreFoundation AS CF" later and use names like CF.Release(). > > Hope it saves few hours to somebody else :). > -- > Divided by a common language > > Dragi?a Duri? > dragisha at m3w.org > > > > > On Mar 17, 2013, at 3:37 AM, Antony Hosking wrote: > >> Should be simple addresses. >> >> >> On Mar 16, 2013, at 6:34 PM, Dragi?a Duri? wrote: >> >>> To resolve an issue with a project, I need to wrap few functions from Security framework on OSX Lion. I have no experience on this level with OSX programming. >>> >>> I did a lot of such work on Linux and Windows, and all I needed there is to match signatures of functions, structure of types, and refer m3makefile to right libraries. Also, I did similar work for various non-framework libraries on OSX, and it is Unix all the way. >>> >>> Anyone with CF/framework related experience? Do I need some special voodoo for handling various CF opaque objects or they are simple addresses? >>> >>> TIA, >>> dd >>> >>> -- >>> Divided by a common language >>> >>> Dragi?a Duri? >>> dragisha at m3w.org >>> >>> >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 05:56:59 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 04:56:59 +0000 Subject: [M3devel] layout of objects? Message-ID: layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 05:55:56 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 04:55:56 +0000 Subject: [M3devel] layout of objects? Message-ID: layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 06:50:23 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 01:50:23 -0400 Subject: [M3devel] layout of objects? In-Reply-To: References: Message-ID: <431DA224-01A8-4A56-A802-970B3424305A@cs.purdue.edu> header methods pointer fields If I recall correctly. Sent from my iPad On Mar 22, 2013, at 12:55 AM, Jay K wrote: > layout of objects? > > > > How are Modula-3 objects layed out? > i.e. "OBJECT"/"METHODS"/"OVERRIDES" > I skimmed m3front and it wasn't obvious. > > > > A common way for C++ "objects" to be layed out, > in the face of no RTTI and only single inheritance, > and virtual functions, is that a pointer to a record > of function pointers is first in the record. > > > Like this: > > > class Type > { > virtual void F1(); > virtual void F2(); > int data1; > int data2; > }; > > > ends up lik more this: > > > struct TypeFunctions > { > void (*F1)(Type*); > void (*F2)(Type*); > }; > > > struct Type > { > TypeFunctions* Functions; /* always first, > or at least a fixed offset, and located independent > of the size of the data; could also be at "-1" or such */. > int data1; > int data2; > }; > > > Type* x; > x->F1(); > > > => > x->Functions->F1(x); > > > Functions added in more derived types go at the end. > Ditto for data. > In the absence of multiple-inheritance and RTTI, it is simple and predictable. > (RTTI makes only small modifications.) > > > Looking through m3front, it wasn't at all obvious if it works this way. > > > I would like to declare something in C (or possibly C++, but not likely), > such that I might actually recognize the various low level operations > and "uncompile" it back to a typeful/typesafe form, like the above C++ > to C transform. > > > > I can't likely uncompile to C++ with virtual functions, > because the actual layout in C++ is not guaranteed. > > > > Granted, I am being lazy. > I should/could compile some small samples. > But I might not get the entire story that way. > > > > Thanks, > - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Fri Mar 22 07:34:32 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Fri, 22 Mar 2013 07:34:32 +0100 Subject: [M3devel] layout of objects? In-Reply-To: References: Message-ID: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote: > layout of objects? > > > > How are Modula-3 objects layed out? > i.e. "OBJECT"/"METHODS"/"OVERRIDES" > I skimmed m3front and it wasn't obvious. > > > > A common way for C++ "objects" to be layed out, > in the face of no RTTI and only single inheritance, > and virtual functions, is that a pointer to a record > of function pointers is first in the record. > > > Like this: > > > class Type > { > virtual void F1(); > virtual void F2(); > int data1; > int data2; > }; > > > ends up lik more this: > > > struct TypeFunctions > { > void (*F1)(Type*); > void (*F2)(Type*); > }; > > > struct Type > { > TypeFunctions* Functions; /* always first, > or at least a fixed offset, and located independent > of the size of the data; could also be at "-1" or such */. > int data1; > int data2; > }; > > > Type* x; > x->F1(); > > > => > x->Functions->F1(x); > > > Functions added in more derived types go at the end. > Ditto for data. > In the absence of multiple-inheritance and RTTI, it is simple and predictable. > (RTTI makes only small modifications.) > > > Looking through m3front, it wasn't at all obvious if it works this way. > > > I would like to declare something in C (or possibly C++, but not likely), > such that I might actually recognize the various low level operations > and "uncompile" it back to a typeful/typesafe form, like the above C++ > to C transform. > > > > I can't likely uncompile to C++ with virtual functions, > because the actual layout in C++ is not guaranteed. > > > > Granted, I am being lazy. > I should/could compile some small samples. > But I might not get the entire story that way. > > > > Thanks, > - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Fri Mar 22 07:40:23 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Fri, 22 Mar 2013 07:40:23 +0100 Subject: [M3devel] layout of objects? In-Reply-To: <431DA224-01A8-4A56-A802-970B3424305A@cs.purdue.edu> References: <431DA224-01A8-4A56-A802-970B3424305A@cs.purdue.edu> Message-ID: Yes, header too. And methods pointer is a structure from RT0 (methods and everything else). And data pointer program gets is address of first of fields. On Mar 22, 2013, at 6:50 AM, Tony Hosking wrote: > header > methods pointer > fields > > If I recall correctly. > > Sent from my iPad > > On Mar 22, 2013, at 12:55 AM, Jay K wrote: > >> layout of objects? >> >> >> >> How are Modula-3 objects layed out? >> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >> I skimmed m3front and it wasn't obvious. >> >> >> >> A common way for C++ "objects" to be layed out, >> in the face of no RTTI and only single inheritance, >> and virtual functions, is that a pointer to a record >> of function pointers is first in the record. >> >> >> Like this: >> >> >> class Type >> { >> virtual void F1(); >> virtual void F2(); >> int data1; >> int data2; >> }; >> >> >> ends up lik more this: >> >> >> struct TypeFunctions >> { >> void (*F1)(Type*); >> void (*F2)(Type*); >> }; >> >> >> struct Type >> { >> TypeFunctions* Functions; /* always first, >> or at least a fixed offset, and located independent >> of the size of the data; could also be at "-1" or such */. >> int data1; >> int data2; >> }; >> >> >> Type* x; >> x->F1(); >> >> >> => >> x->Functions->F1(x); >> >> >> Functions added in more derived types go at the end. >> Ditto for data. >> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >> (RTTI makes only small modifications.) >> >> >> Looking through m3front, it wasn't at all obvious if it works this way. >> >> >> I would like to declare something in C (or possibly C++, but not likely), >> such that I might actually recognize the various low level operations >> and "uncompile" it back to a typeful/typesafe form, like the above C++ >> to C transform. >> >> >> >> I can't likely uncompile to C++ with virtual functions, >> because the actual layout in C++ is not guaranteed. >> >> >> >> Granted, I am being lazy. >> I should/could compile some small samples. >> But I might not get the entire story that way. >> >> >> >> Thanks, >> - Jay >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 07:41:33 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 06:41:33 +0000 Subject: [M3devel] layout of objects? In-Reply-To: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> References: , <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: tangent: Shouldn't the methods and header/typeinfo be combined? Or is the header mutable and per-object? But, yeah, my point is more to understand, not to question or change. Thank you, - Jay From: dragisha at m3w.org Date: Fri, 22 Mar 2013 07:34:32 +0100 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] layout of objects? It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote:layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 07:44:37 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 01:44:37 -0500 Subject: [M3devel] layout of objects? In-Reply-To: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. Heap header is at -ADRSIZE(Header). The type information in RT0 is used to initialize the object instances. On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: > It's not m3front, it's RT0. > > First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. > > On Mar 22, 2013, at 5:56 AM, Jay K wrote: > >> layout of objects? >> >> >> >> How are Modula-3 objects layed out? >> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >> I skimmed m3front and it wasn't obvious. >> >> >> >> A common way for C++ "objects" to be layed out, >> in the face of no RTTI and only single inheritance, >> and virtual functions, is that a pointer to a record >> of function pointers is first in the record. >> >> >> Like this: >> >> >> class Type >> { >> virtual void F1(); >> virtual void F2(); >> int data1; >> int data2; >> }; >> >> >> ends up lik more this: >> >> >> struct TypeFunctions >> { >> void (*F1)(Type*); >> void (*F2)(Type*); >> }; >> >> >> struct Type >> { >> TypeFunctions* Functions; /* always first, >> or at least a fixed offset, and located independent >> of the size of the data; could also be at "-1" or such */. >> int data1; >> int data2; >> }; >> >> >> Type* x; >> x->F1(); >> >> >> => >> x->Functions->F1(x); >> >> >> Functions added in more derived types go at the end. >> Ditto for data. >> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >> (RTTI makes only small modifications.) >> >> >> Looking through m3front, it wasn't at all obvious if it works this way. >> >> >> I would like to declare something in C (or possibly C++, but not likely), >> such that I might actually recognize the various low level operations >> and "uncompile" it back to a typeful/typesafe form, like the above C++ >> to C transform. >> >> >> >> I can't likely uncompile to C++ with virtual functions, >> because the actual layout in C++ is not guaranteed. >> >> >> >> Granted, I am being lazy. >> I should/could compile some small samples. >> But I might not get the entire story that way. >> >> >> >> Thanks, >> - Jay >> > Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Fri Mar 22 08:06:53 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Fri, 22 Mar 2013 08:06:53 +0100 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: <9F41859D-4A58-4DEA-94AE-401B66DF4DE5@m3w.org> Relevant part is: LOOPHOLE(res - ADRSIZE(Header), RefHeader)^ := Header{typecode := def.typecode, dirty := TRUE}; So, there ia a header, where data is combined. dirty fields is for GC, and typecode is index into RT0 structures. -- Divided by a common language Dragi?a Duri? dragisha at m3w.org On Mar 22, 2013, at 7:44 AM, Tony Hosking wrote: > Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. > Heap header is at -ADRSIZE(Header). > The type information in RT0 is used to initialize the object instances. > > On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: > >> It's not m3front, it's RT0. >> >> First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. >> >> On Mar 22, 2013, at 5:56 AM, Jay K wrote: >> >>> layout of objects? >>> >>> >>> >>> How are Modula-3 objects layed out? >>> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >>> I skimmed m3front and it wasn't obvious. >>> >>> >>> >>> A common way for C++ "objects" to be layed out, >>> in the face of no RTTI and only single inheritance, >>> and virtual functions, is that a pointer to a record >>> of function pointers is first in the record. >>> >>> >>> Like this: >>> >>> >>> class Type >>> { >>> virtual void F1(); >>> virtual void F2(); >>> int data1; >>> int data2; >>> }; >>> >>> >>> ends up lik more this: >>> >>> >>> struct TypeFunctions >>> { >>> void (*F1)(Type*); >>> void (*F2)(Type*); >>> }; >>> >>> >>> struct Type >>> { >>> TypeFunctions* Functions; /* always first, >>> or at least a fixed offset, and located independent >>> of the size of the data; could also be at "-1" or such */. >>> int data1; >>> int data2; >>> }; >>> >>> >>> Type* x; >>> x->F1(); >>> >>> >>> => >>> x->Functions->F1(x); >>> >>> >>> Functions added in more derived types go at the end. >>> Ditto for data. >>> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >>> (RTTI makes only small modifications.) >>> >>> >>> Looking through m3front, it wasn't at all obvious if it works this way. >>> >>> >>> I would like to declare something in C (or possibly C++, but not likely), >>> such that I might actually recognize the various low level operations >>> and "uncompile" it back to a typeful/typesafe form, like the above C++ >>> to C transform. >>> >>> >>> >>> I can't likely uncompile to C++ with virtual functions, >>> because the actual layout in C++ is not guaranteed. >>> >>> >>> >>> Granted, I am being lazy. >>> I should/could compile some small samples. >>> But I might not get the entire story that way. >>> >>> >>> >>> Thanks, >>> - Jay >>> >> > > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Mobile +1 765 427 5484 > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 08:01:12 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 07:01:12 +0000 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org>, Message-ID: Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? PROCEDURE Compile (p: P) = VAR x := ObjectType.MethodOffset (p.holder); method: Method.Info; BEGIN Type.Compile (p.object); Method.SplitX (p.method, method); Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); IF (x >= 0) THEN INC (method.offset, x); ELSE (* runtime offset to methods *) Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); CG.Index_bytes (Target.Byte); END; CG.Boost_alignment (Target.Address.align); CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); CG.Boost_alignment (Target.Address.align); END Compile; "runtime offset to methods"? ObjectType.MethodOffset: PROCEDURE MethodOffset (t: Type.T): INTEGER = VAR p := Confirm (t); BEGIN IF (p = NIL) THEN RETURN Unknown_w_magic END; GetOffsets (p, use_magic := TRUE); RETURN p.methodOffset; END MethodOffset; PROCEDURE Confirm (t: Type.T): P = VAR info: Type.Info; BEGIN LOOP t := Type.CheckInfo (t, info); IF (info.class = Type.Class.Object) THEN RETURN t; ELSIF (info.class = Type.Class.Opaque) THEN t := Revelation.LookUp (t); ELSE RETURN NIL; END; END; END Confirm; ... - Jay Subject: Re: [M3devel] layout of objects? From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 01:44:37 -0500 CC: jay.krell at cornell.edu; m3devel at elegosoft.com To: dragisha at m3w.org Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields.Heap header is at -ADRSIZE(Header).The type information in RT0 is used to initialize the object instances. On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote:It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote:layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAMobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 09:08:04 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 03:08:04 -0500 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org>, Message-ID: x>=0 means a known constant method offset at compile time. Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can?t know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. On Mar 22, 2013, at 2:01 AM, Jay K wrote: > Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? > > > PROCEDURE Compile (p: P) = > VAR > x := ObjectType.MethodOffset (p.holder); > method: Method.Info; > BEGIN > Type.Compile (p.object); > Method.SplitX (p.method, method); > > Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); > IF (x >= 0) THEN > INC (method.offset, x); > ELSE (* runtime offset to methods *) > Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); > CG.Index_bytes (Target.Byte); > END; > CG.Boost_alignment (Target.Address.align); > CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); > CG.Boost_alignment (Target.Address.align); > END Compile; > > > "runtime offset to methods"? > ObjectType.MethodOffset: > > PROCEDURE MethodOffset (t: Type.T): INTEGER = > VAR p := Confirm (t); > BEGIN > IF (p = NIL) THEN RETURN Unknown_w_magic END; > GetOffsets (p, use_magic := TRUE); > RETURN p.methodOffset; > END MethodOffset; > > > PROCEDURE Confirm (t: Type.T): P = > VAR info: Type.Info; > BEGIN > LOOP > t := Type.CheckInfo (t, info); > IF (info.class = Type.Class.Object) THEN > RETURN t; > ELSIF (info.class = Type.Class.Opaque) THEN > t := Revelation.LookUp (t); > ELSE > RETURN NIL; > END; > END; > END Confirm; > > > ... > > > > - Jay > > > > > > Subject: Re: [M3devel] layout of objects? > From: hosking at cs.purdue.edu > Date: Fri, 22 Mar 2013 01:44:37 -0500 > CC: jay.krell at cornell.edu; m3devel at elegosoft.com > To: dragisha at m3w.org > > Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. > Heap header is at -ADRSIZE(Header). > The type information in RT0 is used to initialize the object instances. > > On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: > > It's not m3front, it's RT0. > > First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. > > On Mar 22, 2013, at 5:56 AM, Jay K wrote: > > layout of objects? > > > > How are Modula-3 objects layed out? > i.e. "OBJECT"/"METHODS"/"OVERRIDES" > I skimmed m3front and it wasn't obvious. > > > > A common way for C++ "objects" to be layed out, > in the face of no RTTI and only single inheritance, > and virtual functions, is that a pointer to a record > of function pointers is first in the record. > > > Like this: > > > class Type > { > virtual void F1(); > virtual void F2(); > int data1; > int data2; > }; > > > ends up lik more this: > > > struct TypeFunctions > { > void (*F1)(Type*); > void (*F2)(Type*); > }; > > > struct Type > { > TypeFunctions* Functions; /* always first, > or at least a fixed offset, and located independent > of the size of the data; could also be at "-1" or such */. > int data1; > int data2; > }; > > > Type* x; > x->F1(); > > > => > x->Functions->F1(x); > > > Functions added in more derived types go at the end. > Ditto for data. > In the absence of multiple-inheritance and RTTI, it is simple and predictable. > (RTTI makes only small modifications.) > > > Looking through m3front, it wasn't at all obvious if it works this way. > > > I would like to declare something in C (or possibly C++, but not likely), > such that I might actually recognize the various low level operations > and "uncompile" it back to a typeful/typesafe form, like the above C++ > to C transform. > > > > I can't likely uncompile to C++ with virtual functions, > because the actual layout in C++ is not guaranteed. > > > > Granted, I am being lazy. > I should/could compile some small samples. > But I might not get the entire story that way. > > > > Thanks, > - Jay > > > > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 17:13:44 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 16:13:44 +0000 Subject: [M3devel] layout of objects? In-Reply-To: References: , <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org>, , , , Message-ID: Are opaque types always revealed eventually? Or only sometimes? I'd like to generate structs and member references and not be adding offsets to pointers. For method calls and record field references. And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch of integers and no indication where the frontend got them from.. :( Thanks, - Jay From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 03:08:04 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] layout of objects? x>=0 means a known constant method offset at compile time.Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. On Mar 22, 2013, at 2:01 AM, Jay K wrote:Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? PROCEDURE Compile (p: P) = VAR x := ObjectType.MethodOffset (p.holder); method: Method.Info; BEGIN Type.Compile (p.object); Method.SplitX (p.method, method); Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); IF (x >= 0) THEN INC (method.offset, x); ELSE (* runtime offset to methods *) Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); CG.Index_bytes (Target.Byte); END; CG.Boost_alignment (Target.Address.align); CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); CG.Boost_alignment (Target.Address.align); END Compile; "runtime offset to methods"? ObjectType.MethodOffset: PROCEDURE MethodOffset (t: Type.T): INTEGER = VAR p := Confirm (t); BEGIN IF (p = NIL) THEN RETURN Unknown_w_magic END; GetOffsets (p, use_magic := TRUE); RETURN p.methodOffset; END MethodOffset; PROCEDURE Confirm (t: Type.T): P = VAR info: Type.Info; BEGIN LOOP t := Type.CheckInfo (t, info); IF (info.class = Type.Class.Object) THEN RETURN t; ELSIF (info.class = Type.Class.Opaque) THEN t := Revelation.LookUp (t); ELSE RETURN NIL; END; END; END Confirm; ... - Jay Subject: Re: [M3devel] layout of objects? From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 01:44:37 -0500 CC: jay.krell at cornell.edu; m3devel at elegosoft.com To: dragisha at m3w.org Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields.Heap header is at -ADRSIZE(Header).The type information in RT0 is used to initialize the object instances. On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote:It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote:layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAMobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 19:11:59 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 14:11:59 -0400 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: Every opaque type in a linkage must have only one revelation. Sent from my iPad On Mar 22, 2013, at 12:13 PM, Jay K wrote: > Are opaque types always revealed eventually? Or only sometimes? > I'd like to generate structs and member references and not be adding offsets to pointers. > For method calls and record field references. > And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch > of integers and no indication where the frontend got them from.. :( > > > Thanks, > - Jay > > > From: hosking at cs.purdue.edu > Date: Fri, 22 Mar 2013 03:08:04 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] layout of objects? > > x>=0 means a known constant method offset at compile time. > Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. > > On Mar 22, 2013, at 2:01 AM, Jay K wrote: > > Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? > > > PROCEDURE Compile (p: P) = > VAR > x := ObjectType.MethodOffset (p.holder); > method: Method.Info; > BEGIN > Type.Compile (p.object); > Method.SplitX (p.method, method); > > Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); > IF (x >= 0) THEN > INC (method.offset, x); > ELSE (* runtime offset to methods *) > Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); > CG.Index_bytes (Target.Byte); > END; > CG.Boost_alignment (Target.Address.align); > CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); > CG.Boost_alignment (Target.Address.align); > END Compile; > > > "runtime offset to methods"? > > ObjectType.MethodOffset: > > PROCEDURE MethodOffset (t: Type.T): INTEGER = > VAR p := Confirm (t); > BEGIN > IF (p = NIL) THEN RETURN Unknown_w_magic END; > GetOffsets (p, use_magic := TRUE); > RETURN p.methodOffset; > END MethodOffset; > > > PROCEDURE Confirm (t: Type.T): P = > VAR info: Type.Info; > BEGIN > LOOP > t := Type.CheckInfo (t, info); > IF (info.class = Type.Class.Object) THEN > RETURN t; > ELSIF (info.class = Type.Class.Opaque) THEN > t := Revelation.LookUp (t); > ELSE > RETURN NIL; > END; > END; > END Confirm; > > > ... > > > > - Jay > > > > > > Subject: Re: [M3devel] layout of objects? > From: hosking at cs.purdue.edu > Date: Fri, 22 Mar 2013 01:44:37 -0500 > CC: jay.krell at cornell.edu; m3devel at elegosoft.com > To: dragisha at m3w.org > > Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. > Heap header is at -ADRSIZE(Header). > The type information in RT0 is used to initialize the object instances. > > On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: > > It's not m3front, it's RT0. > > First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. > > On Mar 22, 2013, at 5:56 AM, Jay K wrote: > > layout of objects? > > > > How are Modula-3 objects layed out? > i.e. "OBJECT"/"METHODS"/"OVERRIDES" > I skimmed m3front and it wasn't obvious. > > > > A common way for C++ "objects" to be layed out, > in the face of no RTTI and only single inheritance, > and virtual functions, is that a pointer to a record > of function pointers is first in the record. > > > Like this: > > > class Type > { > virtual void F1(); > virtual void F2(); > int data1; > int data2; > }; > > > ends up lik more this: > > > struct TypeFunctions > { > void (*F1)(Type*); > void (*F2)(Type*); > }; > > > struct Type > { > TypeFunctions* Functions; /* always first, > or at least a fixed offset, and located independent > of the size of the data; could also be at "-1" or such */. > int data1; > int data2; > }; > > > Type* x; > x->F1(); > > > => > x->Functions->F1(x); > > > Functions added in more derived types go at the end. > Ditto for data. > In the absence of multiple-inheritance and RTTI, it is simple and predictable. > (RTTI makes only small modifications.) > > > Looking through m3front, it wasn't at all obvious if it works this way. > > > I would like to declare something in C (or possibly C++, but not likely), > such that I might actually recognize the various low level operations > and "uncompile" it back to a typeful/typesafe form, like the above C++ > to C transform. > > > > I can't likely uncompile to C++ with virtual functions, > because the actual layout in C++ is not guaranteed. > > > > Granted, I am being lazy. > I should/could compile some small samples. > But I might not get the entire story that way. > > > > Thanks, > - Jay > > > > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Mobile +1 765 427 5484 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 19:18:21 2013 From: jay.krell at cornell.edu (Jay) Date: Fri, 22 Mar 2013 11:18:21 -0700 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: <408C9E73-BD22-4457-9685-E661CF5A8401@gmail.com> Can it have zero revelations? Can you assist lazy me and suggest an accurate way to describe opaque types in a typeful way in C? Ultimate goal would be to get m3front & m3back optionally out of the business of computing offsets, instead using C structs and members and pointers and leave layout to the C compiler. Ultimately generating one architecture-independent, pointer-size-independent C. I understand there are multiple challenges here and eventually m3cg and m3front will need changes, to pass down more higher level information. - Jay On Mar 22, 2013, at 11:11 AM, Tony Hosking wrote: > Every opaque type in a linkage must have only one revelation. > > Sent from my iPad > > On Mar 22, 2013, at 12:13 PM, Jay K wrote: > >> Are opaque types always revealed eventually? Or only sometimes? >> I'd like to generate structs and member references and not be adding offsets to pointers. >> For method calls and record field references. >> And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch >> of integers and no indication where the frontend got them from.. :( >> >> >> Thanks, >> - Jay >> >> >> From: hosking at cs.purdue.edu >> Date: Fri, 22 Mar 2013 03:08:04 -0500 >> To: jay.krell at cornell.edu >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] layout of objects? >> >> x>=0 means a known constant method offset at compile time. >> Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. >> >> On Mar 22, 2013, at 2:01 AM, Jay K wrote: >> >> Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? >> >> >> PROCEDURE Compile (p: P) = >> VAR >> x := ObjectType.MethodOffset (p.holder); >> method: Method.Info; >> BEGIN >> Type.Compile (p.object); >> Method.SplitX (p.method, method); >> >> Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); >> IF (x >= 0) THEN >> INC (method.offset, x); >> ELSE (* runtime offset to methods *) >> Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); >> CG.Index_bytes (Target.Byte); >> END; >> CG.Boost_alignment (Target.Address.align); >> CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); >> CG.Boost_alignment (Target.Address.align); >> END Compile; >> >> >> "runtime offset to methods"? >> >> ObjectType.MethodOffset: >> >> PROCEDURE MethodOffset (t: Type.T): INTEGER = >> VAR p := Confirm (t); >> BEGIN >> IF (p = NIL) THEN RETURN Unknown_w_magic END; >> GetOffsets (p, use_magic := TRUE); >> RETURN p.methodOffset; >> END MethodOffset; >> >> >> PROCEDURE Confirm (t: Type.T): P = >> VAR info: Type.Info; >> BEGIN >> LOOP >> t := Type.CheckInfo (t, info); >> IF (info.class = Type.Class.Object) THEN >> RETURN t; >> ELSIF (info.class = Type.Class.Opaque) THEN >> t := Revelation.LookUp (t); >> ELSE >> RETURN NIL; >> END; >> END; >> END Confirm; >> >> >> ... >> >> >> >> - Jay >> >> >> >> >> >> Subject: Re: [M3devel] layout of objects? >> From: hosking at cs.purdue.edu >> Date: Fri, 22 Mar 2013 01:44:37 -0500 >> CC: jay.krell at cornell.edu; m3devel at elegosoft.com >> To: dragisha at m3w.org >> >> Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. >> Heap header is at -ADRSIZE(Header). >> The type information in RT0 is used to initialize the object instances. >> >> On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: >> >> It's not m3front, it's RT0. >> >> First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. >> >> On Mar 22, 2013, at 5:56 AM, Jay K wrote: >> >> layout of objects? >> >> >> >> How are Modula-3 objects layed out? >> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >> I skimmed m3front and it wasn't obvious. >> >> >> >> A common way for C++ "objects" to be layed out, >> in the face of no RTTI and only single inheritance, >> and virtual functions, is that a pointer to a record >> of function pointers is first in the record. >> >> >> Like this: >> >> >> class Type >> { >> virtual void F1(); >> virtual void F2(); >> int data1; >> int data2; >> }; >> >> >> ends up lik more this: >> >> >> struct TypeFunctions >> { >> void (*F1)(Type*); >> void (*F2)(Type*); >> }; >> >> >> struct Type >> { >> TypeFunctions* Functions; /* always first, >> or at least a fixed offset, and located independent >> of the size of the data; could also be at "-1" or such */. >> int data1; >> int data2; >> }; >> >> >> Type* x; >> x->F1(); >> >> >> => >> x->Functions->F1(x); >> >> >> Functions added in more derived types go at the end. >> Ditto for data. >> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >> (RTTI makes only small modifications.) >> >> >> Looking through m3front, it wasn't at all obvious if it works this way. >> >> >> I would like to declare something in C (or possibly C++, but not likely), >> such that I might actually recognize the various low level operations >> and "uncompile" it back to a typeful/typesafe form, like the above C++ >> to C transform. >> >> >> >> I can't likely uncompile to C++ with virtual functions, >> because the actual layout in C++ is not guaranteed. >> >> >> >> Granted, I am being lazy. >> I should/could compile some small samples. >> But I might not get the entire story that way. >> >> >> >> Thanks, >> - Jay >> >> >> >> >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Mobile +1 765 427 5484 >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 22:09:33 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 17:09:33 -0400 Subject: [M3devel] layout of objects? In-Reply-To: <408C9E73-BD22-4457-9685-E661CF5A8401@gmail.com> References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> <408C9E73-BD22-4457-9685-E661CF5A8401@gmail.com> Message-ID: <499B305B-B07F-40EB-9E77-2EE127BAEBDA@cs.purdue.edu> From the language spec: There are two kinds of revelations, partial and complete. A program can contain any number of partial revelations for an opaque type; it must contain exactly one complete revelation. Are you typing the method table as an array? Why not simply index the array? I don?t think there is any C type that natively captures the notion of opaque types. The whole point is that you don?t know all the parent types. But you do know that, given the offset of the opaque type?s methods in the method table, you can compute the offset of any given method. For example: TYPE T <: U; Without seeing the revelation of T there is no way to know what methods are inherited from everything between T and U. But, so long as at run time you are told the method offset of T?s methods in its method table then you can find any method defined in T at a known index from that offset. On Mar 22, 2013, at 2:18 PM, Jay wrote: > Can it have zero revelations? > > > Can you assist lazy me and suggest an accurate way to describe opaque types in a typeful way in C? > > > Ultimate goal would be to get m3front & m3back optionally out of the business of computing offsets, instead using C structs and members and pointers and leave layout to the C compiler. > Ultimately generating one architecture-independent, pointer-size-independent C. > > > I understand there are multiple challenges here and eventually m3cg and m3front will need changes, to pass down more higher level information. > > > - Jay > > On Mar 22, 2013, at 11:11 AM, Tony Hosking wrote: > >> Every opaque type in a linkage must have only one revelation. >> >> Sent from my iPad >> >> On Mar 22, 2013, at 12:13 PM, Jay K wrote: >> >>> Are opaque types always revealed eventually? Or only sometimes? >>> I'd like to generate structs and member references and not be adding offsets to pointers. >>> For method calls and record field references. >>> And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch >>> of integers and no indication where the frontend got them from.. :( >>> >>> >>> Thanks, >>> - Jay >>> >>> >>> From: hosking at cs.purdue.edu >>> Date: Fri, 22 Mar 2013 03:08:04 -0500 >>> To: jay.krell at cornell.edu >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] layout of objects? >>> >>> x>=0 means a known constant method offset at compile time. >>> Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. >>> >>> On Mar 22, 2013, at 2:01 AM, Jay K wrote: >>> >>> Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? >>> >>> >>> PROCEDURE Compile (p: P) = >>> VAR >>> x := ObjectType.MethodOffset (p.holder); >>> method: Method.Info; >>> BEGIN >>> Type.Compile (p.object); >>> Method.SplitX (p.method, method); >>> >>> Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); >>> IF (x >= 0) THEN >>> INC (method.offset, x); >>> ELSE (* runtime offset to methods *) >>> Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); >>> CG.Index_bytes (Target.Byte); >>> END; >>> CG.Boost_alignment (Target.Address.align); >>> CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); >>> CG.Boost_alignment (Target.Address.align); >>> END Compile; >>> >>> >>> "runtime offset to methods"? >>> >>> ObjectType.MethodOffset: >>> >>> PROCEDURE MethodOffset (t: Type.T): INTEGER = >>> VAR p := Confirm (t); >>> BEGIN >>> IF (p = NIL) THEN RETURN Unknown_w_magic END; >>> GetOffsets (p, use_magic := TRUE); >>> RETURN p.methodOffset; >>> END MethodOffset; >>> >>> >>> PROCEDURE Confirm (t: Type.T): P = >>> VAR info: Type.Info; >>> BEGIN >>> LOOP >>> t := Type.CheckInfo (t, info); >>> IF (info.class = Type.Class.Object) THEN >>> RETURN t; >>> ELSIF (info.class = Type.Class.Opaque) THEN >>> t := Revelation.LookUp (t); >>> ELSE >>> RETURN NIL; >>> END; >>> END; >>> END Confirm; >>> >>> >>> ... >>> >>> >>> >>> - Jay >>> >>> >>> >>> >>> >>> Subject: Re: [M3devel] layout of objects? >>> From: hosking at cs.purdue.edu >>> Date: Fri, 22 Mar 2013 01:44:37 -0500 >>> CC: jay.krell at cornell.edu; m3devel at elegosoft.com >>> To: dragisha at m3w.org >>> >>> Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. >>> Heap header is at -ADRSIZE(Header). >>> The type information in RT0 is used to initialize the object instances. >>> >>> On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: >>> >>> It's not m3front, it's RT0. >>> >>> First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. >>> >>> On Mar 22, 2013, at 5:56 AM, Jay K wrote: >>> >>> layout of objects? >>> >>> >>> >>> How are Modula-3 objects layed out? >>> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >>> I skimmed m3front and it wasn't obvious. >>> >>> >>> >>> A common way for C++ "objects" to be layed out, >>> in the face of no RTTI and only single inheritance, >>> and virtual functions, is that a pointer to a record >>> of function pointers is first in the record. >>> >>> >>> Like this: >>> >>> >>> class Type >>> { >>> virtual void F1(); >>> virtual void F2(); >>> int data1; >>> int data2; >>> }; >>> >>> >>> ends up lik more this: >>> >>> >>> struct TypeFunctions >>> { >>> void (*F1)(Type*); >>> void (*F2)(Type*); >>> }; >>> >>> >>> struct Type >>> { >>> TypeFunctions* Functions; /* always first, >>> or at least a fixed offset, and located independent >>> of the size of the data; could also be at "-1" or such */. >>> int data1; >>> int data2; >>> }; >>> >>> >>> Type* x; >>> x->F1(); >>> >>> >>> => >>> x->Functions->F1(x); >>> >>> >>> Functions added in more derived types go at the end. >>> Ditto for data. >>> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >>> (RTTI makes only small modifications.) >>> >>> >>> Looking through m3front, it wasn't at all obvious if it works this way. >>> >>> >>> I would like to declare something in C (or possibly C++, but not likely), >>> such that I might actually recognize the various low level operations >>> and "uncompile" it back to a typeful/typesafe form, like the above C++ >>> to C transform. >>> >>> >>> >>> I can't likely uncompile to C++ with virtual functions, >>> because the actual layout in C++ is not guaranteed. >>> >>> >>> >>> Granted, I am being lazy. >>> I should/could compile some small samples. >>> But I might not get the entire story that way. >>> >>> >>> >>> Thanks, >>> - Jay >>> >>> >>> >>> >>> >>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>> 305 N. University Street | West Lafayette | IN 47907 | USA >>> Mobile +1 765 427 5484 >>> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 22:29:07 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 21:29:07 +0000 Subject: [M3devel] layout of objects? In-Reply-To: <499B305B-B07F-40EB-9E77-2EE127BAEBDA@cs.purdue.edu> References: , <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org>, , , , , , <408C9E73-BD22-4457-9685-E661CF5A8401@gmail.com>, <499B305B-B07F-40EB-9E77-2EE127BAEBDA@cs.purdue.edu> Message-ID: I'd like to reference a member in a struct, a typed function pointer.I think I see your point though.Each partial revelation describes a subset of the methods.Almost like multiple inheritance, multiple vtables, but subsequences within one linear vtable.More later.. - Jay From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 17:09:33 -0400 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] layout of objects? From the language spec: There are two kinds of revelations, partial and complete. A program can contain any number of partial revelations for an opaque type; it must contain exactly one complete revelation. Are you typing the method table as an array?Why not simply index the array? I don't think there is any C type that natively captures the notion of opaque types.The whole point is that you don't know all the parent types.But you do know that, given the offset of the opaque type's methods in the method table, you can compute the offset of any given method. For example: TYPE T <: U; Without seeing the revelation of T there is no way to know what methods are inherited from everything between T and U.But, so long as at run time you are told the method offset of T's methods in its method table then you can find any method defined in T at a known index from that offset. On Mar 22, 2013, at 2:18 PM, Jay wrote:Can it have zero revelations? Can you assist lazy me and suggest an accurate way to describe opaque types in a typeful way in C? Ultimate goal would be to get m3front & m3back optionally out of the business of computing offsets, instead using C structs and members and pointers and leave layout to the C compiler.Ultimately generating one architecture-independent, pointer-size-independent C. I understand there are multiple challenges here and eventually m3cg and m3front will need changes, to pass down more higher level information. - Jay On Mar 22, 2013, at 11:11 AM, Tony Hosking wrote: Every opaque type in a linkage must have only one revelation. Sent from my iPad On Mar 22, 2013, at 12:13 PM, Jay K wrote: Are opaque types always revealed eventually? Or only sometimes? I'd like to generate structs and member references and not be adding offsets to pointers. For method calls and record field references. And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch of integers and no indication where the frontend got them from.. :( Thanks, - Jay From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 03:08:04 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] layout of objects? x>=0 means a known constant method offset at compile time.Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. On Mar 22, 2013, at 2:01 AM, Jay K wrote:Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? PROCEDURE Compile (p: P) = VAR x := ObjectType.MethodOffset (p.holder); method: Method.Info; BEGIN Type.Compile (p.object); Method.SplitX (p.method, method); Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); IF (x >= 0) THEN INC (method.offset, x); ELSE (* runtime offset to methods *) Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); CG.Index_bytes (Target.Byte); END; CG.Boost_alignment (Target.Address.align); CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); CG.Boost_alignment (Target.Address.align); END Compile; "runtime offset to methods"? ObjectType.MethodOffset: PROCEDURE MethodOffset (t: Type.T): INTEGER = VAR p := Confirm (t); BEGIN IF (p = NIL) THEN RETURN Unknown_w_magic END; GetOffsets (p, use_magic := TRUE); RETURN p.methodOffset; END MethodOffset; PROCEDURE Confirm (t: Type.T): P = VAR info: Type.Info; BEGIN LOOP t := Type.CheckInfo (t, info); IF (info.class = Type.Class.Object) THEN RETURN t; ELSIF (info.class = Type.Class.Opaque) THEN t := Revelation.LookUp (t); ELSE RETURN NIL; END; END; END Confirm; ... - Jay Subject: Re: [M3devel] layout of objects? From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 01:44:37 -0500 CC: jay.krell at cornell.edu; m3devel at elegosoft.com To: dragisha at m3w.org Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields.Heap header is at -ADRSIZE(Header).The type information in RT0 is used to initialize the object instances. On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote:It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote:layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAMobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 22:30:02 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 21:30:02 +0000 Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: <20130322194459.GE12913@tucnak.redhat.com> References: <20130322194459.GE12913@tucnak.redhat.com> Message-ID: Perhaps we should use this. I'm more inclined to work on the C backend though. - Jay > Date: Fri, 22 Mar 2013 20:44:59 +0100 > From: jakub at redhat.com > To: gcc-announce at gcc.gnu.org > Subject: GCC 4.8.0 Released > > Exactly one year after the last major GCC release has been announced, > celebrating the 26th anniversary of the GNU Compiler Collection, > the GCC development team announces a new major GCC release, 4.8.0. > > GCC 4.8.0 is a major release containing substantial new > functionality not available in GCC 4.7.x or previous GCC releases. > > GCC 4.8 features a new Local Register Allocator which replaces the 26 > years old reload pass and improves generated code quality on ia32 and > x86-64 targets. The C++ frontend and standard library have been > enhanced with various improvements for C++11 support not limited to C++11 > attribute syntax, thread_local or inheriting constructors support. > > AddressSanitizer and ThreadSanitizer instrumentation have been > added to detect heap, stack and global buffer overflows, uses after free > and data races. > > Many scalability bottle-necks have been removed from GCC optimization > passes, thus it is now possible to compile extremely large functions with > smaller memory consumption in less time. > > Extending the widest support for hardware architectures in the industry, > GCC 4.8 has gained support for the upcoming 64-bit ARM instruction set > architecture, AArch64. GCC 4.8 also features support for Hardware > Transactional Memory on the upcoming Intel Haswell CPU architecture. > The S/390 target now supports the zEC12 architecture. The ARM 32-bit > target has gained support for AArch32 ARM v8 ISA additions. > > See > > http://gcc.gnu.org/gcc-4.8/changes.html > > for more information about changes in GCC 4.8. > > This release is available from the FTP servers listed here: > > http://www.gnu.org/order/ftp.html > > The release is in gcc/gcc-4.8.0/ subdirectory. > > If you encounter difficulties using GCC 4.8, please do not contact me > directly. Instead, please visit http://gcc.gnu.org for information > about getting help. > > > Driving a leading free software project such as GNU Compiler Collection > would not be possible without support from its many contributors. > Not to only mention its developers but especially its regular testers > and users which contribute to its high quality. The list of individuals > is too large to thank individually! -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 22:56:00 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 17:56:00 -0400 Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: References: <20130322194459.GE12913@tucnak.redhat.com> Message-ID: In my opinion it would be better to work on an LLVM backend. On Mar 22, 2013, at 5:30 PM, Jay K wrote: > > > Perhaps we should use this. I'm more inclined to work on the C backend though. > > - Jay > > Date: Fri, 22 Mar 2013 20:44:59 +0100 > > From: jakub at redhat.com > > To: gcc-announce at gcc.gnu.org > > Subject: GCC 4.8.0 Released > > > > Exactly one year after the last major GCC release has been announced, > > celebrating the 26th anniversary of the GNU Compiler Collection, > > the GCC development team announces a new major GCC release, 4.8.0. > > > > GCC 4.8.0 is a major release containing substantial new > > functionality not available in GCC 4.7.x or previous GCC releases. > > > > GCC 4.8 features a new Local Register Allocator which replaces the 26 > > years old reload pass and improves generated code quality on ia32 and > > x86-64 targets. The C++ frontend and standard library have been > > enhanced with various improvements for C++11 support not limited to C++11 > > attribute syntax, thread_local or inheriting constructors support. > > > > AddressSanitizer and ThreadSanitizer instrumentation have been > > added to detect heap, stack and global buffer overflows, uses after free > > and data races. > > > > Many scalability bottle-necks have been removed from GCC optimization > > passes, thus it is now possible to compile extremely large functions with > > smaller memory consumption in less time. > > > > Extending the widest support for hardware architectures in the industry, > > GCC 4.8 has gained support for the upcoming 64-bit ARM instruction set > > architecture, AArch64. GCC 4.8 also features support for Hardware > > Transactional Memory on the upcoming Intel Haswell CPU architecture. > > The S/390 target now supports the zEC12 architecture. The ARM 32-bit > > target has gained support for AArch32 ARM v8 ISA additions. > > > > See > > > > http://gcc.gnu.org/gcc-4.8/changes.html > > > > for more information about changes in GCC 4.8. > > > > This release is available from the FTP servers listed here: > > > > http://www.gnu.org/order/ftp.html > > > > The release is in gcc/gcc-4.8.0/ subdirectory. > > > > If you encounter difficulties using GCC 4.8, please do not contact me > > directly. Instead, please visit http://gcc.gnu.org for information > > about getting help. > > > > > > Driving a leading free software project such as GNU Compiler Collection > > would not be possible without support from its many contributors. > > Not to only mention its developers but especially its regular testers > > and users which contribute to its high quality. The list of individuals > > is too large to thank individually! -------------- next part -------------- An HTML attachment was scrubbed... URL: From lemming at henning-thielemann.de Fri Mar 22 22:57:29 2013 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Fri, 22 Mar 2013 22:57:29 +0100 (CET) Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: References: <20130322194459.GE12913@tucnak.redhat.com> Message-ID: On Fri, 22 Mar 2013, Tony Hosking wrote: > In my opinion it would be better to work on an LLVM backend. Btw. does someone of you attend to the Euro-LLVM meeting 29-30th April? From jay.krell at cornell.edu Sat Mar 23 00:05:16 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 23:05:16 +0000 Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: References: <20130322194459.GE12913@tucnak.redhat.com>, , , Message-ID: I favor a C backend for a few reasons. - portability -- C supports more than LLVM, past and future I haven't been able to build LLVM on my old MacOSX. - a possible portable source distribution, like most software, but, granted, not like many compilers, and granted, while the C backend now works quite well, this problem still needs a lot of work - Not having to learn LLVM, resting on my C knowledge; might apply to others - LLVM might have the same m3gdb integration problem as C, no better, no worse On the other hand, LLVM is good for: - learn something new - resulting compiler will probably run faster - Jay > Date: Fri, 22 Mar 2013 22:57:29 +0100 > From: lemming at henning-thielemann.de > To: m3devel at elegosoft.com > Subject: Re: [M3devel] FW: GCC 4.8.0 Released > > > On Fri, 22 Mar 2013, Tony Hosking wrote: > > > In my opinion it would be better to work on an LLVM backend. > > Btw. does someone of you attend to the Euro-LLVM meeting 29-30th April? -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sat Mar 23 01:57:46 2013 From: jay.krell at cornell.edu (Jay K) Date: Sat, 23 Mar 2013 00:57:46 +0000 Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: References: <20130322194459.GE12913@tucnak.redhat.com>, , , , , , , Message-ID: (but, ps, for high-end full time wages I'd write an LLVM backend or port to gcc 4.8.0 or port the existing integrated x86 backend, or other, and be more flexible/open-minded. :) Yes I know that is kind of rude and against the spirit of things... ) - JayFrom: jay.krell at cornell.edu To: lemming at henning-thielemann.de; m3devel at elegosoft.com Date: Fri, 22 Mar 2013 23:05:16 +0000 Subject: Re: [M3devel] FW: GCC 4.8.0 Released I favor a C backend for a few reasons. - portability -- C supports more than LLVM, past and future I haven't been able to build LLVM on my old MacOSX. - a possible portable source distribution, like most software, but, granted, not like many compilers, and granted, while the C backend now works quite well, this problem still needs a lot of work - Not having to learn LLVM, resting on my C knowledge; might apply to others - LLVM might have the same m3gdb integration problem as C, no better, no worse On the other hand, LLVM is good for: - learn something new - resulting compiler will probably run faster - Jay > Date: Fri, 22 Mar 2013 22:57:29 +0100 > From: lemming at henning-thielemann.de > To: m3devel at elegosoft.com > Subject: Re: [M3devel] FW: GCC 4.8.0 Released > > > On Fri, 22 Mar 2013, Tony Hosking wrote: > > > In my opinion it would be better to work on an LLVM backend. > > Btw. does someone of you attend to the Euro-LLVM meeting 29-30th April? -------------- next part -------------- An HTML attachment was scrubbed... URL: From dabenavidesd at yahoo.es Sat Mar 23 16:19:26 2013 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sat, 23 Mar 2013 15:19:26 +0000 (GMT) Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: Message-ID: <1364051966.34337.YahooMailClassic@web133101.mail.ir2.yahoo.com> Hi : a bytecoded interpreter would make the trick to boot from m3c instead of using a compiler. Was natural choice in Pascal. Thanks in advance --- El vie, 22/3/13, Jay K escribi?: De: Jay K Asunto: Re: [M3devel] FW: GCC 4.8.0 Released Para: "Henning Thielemann" , "m3devel" Fecha: viernes, 22 de marzo, 2013 19:57 (but, ps,?for high-end full time?wages I'd write an LLVM backend or port to gcc 4.8.0 or port the existing integrated x86 backend, or other, and be more flexible/open-minded.?:) Yes I know that is kind of rude and against the spirit of things... ) ? ?- Jay From: jay.krell at cornell.edu To: lemming at henning-thielemann.de; m3devel at elegosoft.com Date: Fri, 22 Mar 2013 23:05:16 +0000 Subject: Re: [M3devel] FW: GCC 4.8.0 Released I?favor a C backend for a few reasons. ??-?portability -- C?supports more than LLVM, past and future ???? I haven't been able to build LLVM on my old MacOSX.? ??- a possible portable source?distribution, like most software, but,?granted, not like many compilers, and granted, while the C backend now works quite well, this problem still needs a lot of work ? -?Not having to learn LLVM, resting on my C knowledge; might apply to others ?? ? - LLVM might have the same?m3gdb integration problem as C, no better, no worse ? ? ? ?On the other hand, LLVM is good for: ?? - learn something new ?? - resulting compiler?will?probably run faster ? ? ?- Jay? > Date: Fri, 22 Mar 2013 22:57:29 +0100 > From: lemming at henning-thielemann.de > To: m3devel at elegosoft.com > Subject: Re: [M3devel] FW: GCC 4.8.0 Released > > > On Fri, 22 Mar 2013, Tony Hosking wrote: > > > In my opinion it would be better to work on an LLVM backend. > > Btw. does someone of you attend to the Euro-LLVM meeting 29-30th April? -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Mar 28 06:04:46 2013 From: jay.krell at cornell.edu (Jay K) Date: Thu, 28 Mar 2013 05:04:46 +0000 Subject: [M3devel] LLVM backend? Message-ID: I was thinking of looking into LLVM more. For selfish reasons -- resume growth, but no matter. 1) Tony, are you making progress? Should I wait? Collaberate? Go it alone? 2) An LLVM backend would I suspect have the same lack of m3gdb support as a C backend. Does that bother people?Actually I was just skimming "parse.c"..I don't remember exactly how I decided it is all a stabs-specific hack.Though, I do realize 1) typeids are encoded in identifier names, which certainly hurts debuggingw/o m3gdb 2) types aren't being described as they ought to be. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Mar 28 06:39:35 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 28 Mar 2013 16:39:35 +1100 Subject: [M3devel] LLVM backend? In-Reply-To: References: Message-ID: I am short of the time needed to make real progress. I am happy to collaborate even if only in an advisory role. I have some of the design written down, but other aspects in my head. For example, dealing with lexically scoped variables for nested functions requires capturing all the "escaping" variables (referenced by inner scope functions) into a properly typed "frame" structure, along with the static link, and whose pointer can be passed as the static link to inner scope functions. On Mar 28, 2013, at 4:04 PM, Jay K wrote: > I was thinking of looking into LLVM more. For selfish reasons -- resume growth, but no matter. > > 1) Tony, are you making progress? Should I wait? Collaberate? Go it alone? > 2) An LLVM backend would I suspect have the same lack of m3gdb support as a C backend. > Does that bother people? > Actually I was just skimming "parse.c"..I don't remember exactly how I decided it is all a stabs-specific hack. > Though, I do realize 1) typeids are encoded in identifier names, which certainly hurts debugging > w/o m3gdb 2) types aren't being described as they ought to be. > > - Jay > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Thu Mar 28 16:23:17 2013 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Thu, 28 Mar 2013 10:23:17 -0500 Subject: [M3devel] LLVM backend? In-Reply-To: References: Message-ID: <51546065.5030709@lcwb.coop> On 03/28/2013 12:04 AM, Jay K wrote: > I was thinking of looking into LLVM more. For selfish reasons -- resume growth, but no matter. > > 1) Tony, are you making progress? Should I wait? Collaberate? Go it alone? (Jay, I reversed the order of your paragraphs here, because my responses make more sense in that order.) > Actually I was just skimming "parse.c"..I don't remember exactly how I decided it is all a stabs-specific hack. > Though, I do realize 1) typeids are encoded in identifier names, which certainly hurts debugging > w/o m3gdb 2) types aren't being described as they ought to be. > Yes, it is very much a hack. For one thing, stabs itself is something of a hack. For another, a lot of the fields of stabs info are really treated as just containers for some extremely Modula-3-specific info, that, to be fair, isn't provided for in any reasonable way by true stabs. Meanwhile, some true stabs stuff is produced too, but not used in m3gdb, because it isn't quite right or helpful. parse.c and m3gdb are highly coupled by all this. Stock gdb's code to read stabs is augmented by tons of stuff to further decode the M3-specific info inserted by parse.c, and tons more to interpret it. Moreover, debug info and code to be translated effectively become diverging streams in parse.c, notwithstanding the fact that they are often interspersed. This makes it very difficult for debug info to reflect anything gcc does to the code. I believe the stabs info is mostly or entirely untouched after parse.c, though I haven't ever thoroughly vetted this. One specific place where this particularly hurts right now is with nonlocal references, static links, etc. With the advent of tree-nested.c, in later gcc versions, the runtime storage model is drastically reworked in gcc, after the stabs has already been produced. That seriously broke a lot of stuff I had working in m3gdb. I have dabbled with Mickey- Mouse schemes to emit purely additional stabs info in tree-nested.c, without changing what was already there, then have m3gdb use it to selectively override the earlier-produced stabs. I never finished this, and have only limited confidence it is even feasible. > 2) An LLVM backend would I suspect have the same lack of m3gdb support as a C backend. > Does that bother people? LLVM has a lot of already provided support for dwarf debug info, keeping it together with code, and helping to transform it in parallel with code, when optimizations, etc., are done. Meanwhile, dwarf itself is vastly more complete and appears to me, from superficial study, to be capable of representing all, or certainly most, of what is needed for good Modula-3 debugging. For these two reasons, I think LLVM plus dwarf present by far the best method to support a nice language-specific debugging experience, while leaving massive kludges behind. This is one big reason why I support an LLVM back end. It would indeed require significant work to get debug support. But it would be so much easier and far more pleasant than the alternatives. That includes even the alternative of further fixing the existing m3gdb/gcc, which still needs perhaps as much additional work as has already gone into it. I am attached to it only because it now provides a lot more function than anything else we have (and which I use a lot). Mucking around in M3ified stabs is, for me, strictly a destination, not a journey. So, the short answer is, it bothers me less than any other option. From jay.krell at cornell.edu Fri Mar 29 17:09:09 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 29 Mar 2013 16:09:09 +0000 Subject: [M3devel] LLVM backend? In-Reply-To: <51546065.5030709@lcwb.coop> References: , <51546065.5030709@lcwb.coop> Message-ID: This doesn't completely make sense to me. But it is kind of what I expected and desire. The debug format isn't the point. parse.c should have no knowledge of dwarf vs. stabs vs. coff vs. xcoff vs. codeview vs. vms vs. anything else. It just happens that the authors found a private channel in stabs. Ideally any debug format used by any C compiler can fully describe C, and Modula-3. The way it (any gcc frontend) is supposed to work is you describe the types using a compiler-internal form, and that gets translated into whatever the user requests that is supported. The primary limit as to what gcc can do is probably the object file format. Any backend without a private channel to the debugger, i.e. the C backend as well as an LLVM backend, will have degraded debugging. Perhaps a private channel can be found either way though. Like, gcc does have this "tfile" thing where after compilation, a separate tool goes over the .S file and makes changes. Ideally we don't have intermediate .S files though. Now, on Windows, for cdb/ntsd/windbg/kd, you can write debugger plugins. .dlls loaded by the debugger that have full access to symbols. They are often very helpful, and would surely help here. I do wonder if it is worth changing TEXT for debuggability. Like, say, to always be flat, no trees, and always nul terminated: (actually I'd always write two zero bytes, in case of viewing the ascii as unicode) #define TEXT_FLAGS_UNICODE (0x00000001) #define TEXT_FLAGS_CONSTANT (0x00000002) typedef struct { size_t flags; size_t length; union { char* ascii; wchar_t* unicode; } data; } *TEXT; ? If we had merely that -- a more debugger/C-idiomatic representation for TEXT, would m3gdb's advantages decline significantly? I'd also be open to just plain typedef char* TEXT; UTF8 encoded. Text.Length is slow, and Text.Concat also slower. But ideally we'd store the length. The length could also be stored before the string. On Windows, "BSTR"s work this way. i.e. it is viable and practical and in wide use. Also, MFC/ATL CStringW/CStringA do this: typedef struct { wchar_t* data; } CStringW; typedef struct { char* data; } CStringA; and then have an entire small struct before the data. It holdes, as I recall, at least the length and a reference count. The strings are reference counted and copy-on-write. It is a nice implementation, but it isn't quite relevant here, since our TEXTs are immutable and garbage collected. The point is though, putting a struct in front of a char*/wchar_t* is viable. As long as the garbage collector doesn't get confused. Anyway, I think I'll start augmenting M3C.m3 to start writing .ll files also. We'll see how that goes. I realize it isn't the ideal path. Wrt nested variables/functions, I make a transform in the C backend. The LLVM backend will need to make a similar transform. I think the frontend should be willing/able to do this transform. It would likely help. - Jay > Date: Thu, 28 Mar 2013 10:23:17 -0500 > From: rodney_bates at lcwb.coop > To: m3devel at elegosoft.com > Subject: Re: [M3devel] LLVM backend? > > > > On 03/28/2013 12:04 AM, Jay K wrote: > > I was thinking of looking into LLVM more. For selfish reasons -- resume growth, but no matter. > > > > 1) Tony, are you making progress? Should I wait? Collaberate? Go it alone? > > (Jay, I reversed the order of your paragraphs here, because my responses make more sense in that order.) > > > Actually I was just skimming "parse.c"..I don't remember exactly how I decided it is all a stabs-specific hack. > > Though, I do realize 1) typeids are encoded in identifier names, which certainly hurts debugging > > w/o m3gdb 2) types aren't being described as they ought to be. > > > > Yes, it is very much a hack. For one thing, stabs itself is something of a hack. For another, > a lot of the fields of stabs info are really treated as just containers for some extremely > Modula-3-specific info, that, to be fair, isn't provided for in any reasonable way by > true stabs. Meanwhile, some true stabs stuff is produced too, but not used in m3gdb, because > it isn't quite right or helpful. parse.c and m3gdb are highly coupled by all this. Stock gdb's > code to read stabs is augmented by tons of stuff to further decode the M3-specific info > inserted by parse.c, and tons more to interpret it. > > Moreover, debug info and code to be translated effectively become diverging streams in > parse.c, notwithstanding the fact that they are often interspersed. This makes it very > difficult for debug info to reflect anything gcc does to the code. I believe the stabs > info is mostly or entirely untouched after parse.c, though I haven't ever thoroughly > vetted this. > > One specific place where this particularly hurts right now is with nonlocal references, > static links, etc. With the advent of tree-nested.c, in later gcc versions, the runtime > storage model is drastically reworked in gcc, after the stabs has already been produced. > That seriously broke a lot of stuff I had working in m3gdb. I have dabbled with Mickey- > Mouse schemes to emit purely additional stabs info in tree-nested.c, without changing what > was already there, then have m3gdb use it to selectively override the earlier-produced > stabs. I never finished this, and have only limited confidence it is even feasible. > > > 2) An LLVM backend would I suspect have the same lack of m3gdb support as a C backend. > > Does that bother people? > > LLVM has a lot of already provided support for dwarf debug info, keeping it together with code, > and helping to transform it in parallel with code, when optimizations, etc., are done. > Meanwhile, dwarf itself is vastly more complete and appears to me, from superficial study, > to be capable of representing all, or certainly most, of what is needed for good Modula-3 debugging. > For these two reasons, I think LLVM plus dwarf present by far the best method to support > a nice language-specific debugging experience, while leaving massive kludges behind. > > This is one big reason why I support an LLVM back end. It would indeed require significant > work to get debug support. But it would be so much easier and far more pleasant than > the alternatives. That includes even the alternative of further fixing the existing m3gdb/gcc, > which still needs perhaps as much additional work as has already gone into it. I am > attached to it only because it now provides a lot more function than anything else > we have (and which I use a lot). Mucking around in M3ified stabs is, for me, strictly a > destination, not a journey. > > So, the short answer is, it bothers me less than any other option. > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dmuysers at hotmail.com Fri Mar 29 17:58:54 2013 From: dmuysers at hotmail.com (Dirk Muysers) Date: Fri, 29 Mar 2013 17:58:54 +0100 Subject: [M3devel] LLVM backend? In-Reply-To: References: , <51546065.5030709@lcwb.coop> Message-ID: For me, the best debugger architecture still remains the one designed by D.R.Hanson: http://research.microsoft.com/pubs/69690/tr-99-04.pdf platform-independent and easy to implement. From: Jay K Sent: Friday, March 29, 2013 5:09 PM To: Rodney M. Bates ; m3devel Subject: Re: [M3devel] LLVM backend? This doesn't completely make sense to me. But it is kind of what I expected and desire. The debug format isn't the point. parse.c should have no knowledge of dwarf vs. stabs vs. coff vs. xcoff vs. codeview vs. vms vs. anything else. It just happens that the authors found a private channel in stabs. Ideally any debug format used by any C compiler can fully describe C, and Modula-3. The way it (any gcc frontend) is supposed to work is you describe the types using a compiler-internal form, and that gets translated into whatever the user requests that is supported. The primary limit as to what gcc can do is probably the object file format. Any backend without a private channel to the debugger, i.e. the C backend as well as an LLVM backend, will have degraded debugging. Perhaps a private channel can be found either way though. Like, gcc does have this "tfile" thing where after compilation, a separate tool goes over the .S file and makes changes. Ideally we don't have intermediate .S files though. Now, on Windows, for cdb/ntsd/windbg/kd, you can write debugger plugins. .dlls loaded by the debugger that have full access to symbols. They are often very helpful, and would surely help here. I do wonder if it is worth changing TEXT for debuggability. Like, say, to always be flat, no trees, and always nul terminated: (actually I'd always write two zero bytes, in case of viewing the ascii as unicode) #define TEXT_FLAGS_UNICODE (0x00000001) #define TEXT_FLAGS_CONSTANT (0x00000002) typedef struct { size_t flags; size_t length; union { char* ascii; wchar_t* unicode; } data; } *TEXT; ? If we had merely that -- a more debugger/C-idiomatic representation for TEXT, would m3gdb's advantages decline significantly? I'd also be open to just plain typedef char* TEXT; UTF8 encoded. Text.Length is slow, and Text.Concat also slower. But ideally we'd store the length. The length could also be stored before the string. On Windows, "BSTR"s work this way. i.e. it is viable and practical and in wide use. Also, MFC/ATL CStringW/CStringA do this: typedef struct { wchar_t* data; } CStringW; typedef struct { char* data; } CStringA; and then have an entire small struct before the data. It holdes, as I recall, at least the length and a reference count. The strings are reference counted and copy-on-write. It is a nice implementation, but it isn't quite relevant here, since our TEXTs are immutable and garbage collected. The point is though, putting a struct in front of a char*/wchar_t* is viable. As long as the garbage collector doesn't get confused. Anyway, I think I'll start augmenting M3C.m3 to start writing .ll files also. We'll see how that goes. I realize it isn't the ideal path. Wrt nested variables/functions, I make a transform in the C backend. The LLVM backend will need to make a similar transform. I think the frontend should be willing/able to do this transform. It would likely help. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From dabenavidesd at yahoo.es Fri Mar 29 22:24:41 2013 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Fri, 29 Mar 2013 21:24:41 +0000 (GMT) Subject: [M3devel] LLVM backend? In-Reply-To: Message-ID: <1364592281.98024.YahooMailClassic@web172804.mail.ir2.yahoo.com> Hi all: Im starting to get nervous of so many things going on and Cm3 going anywhere. We need to release something rather sooner than later. Thanks in advance --- El vie, 29/3/13, Dirk Muysers escribi?: De: Dirk Muysers Asunto: Re: [M3devel] LLVM backend? Para: m3devel at elegosoft.com, "Jay K" Fecha: viernes, 29 de marzo, 2013 11:58 For me, the best debugger architecture still remains the one designed by D.R.Hanson: ? http://research.microsoft.com/pubs/69690/tr-99-04.pdf ? platform-independent and easy to implement. From: Jay K Sent: Friday, March 29, 2013 5:09 PM To: Rodney M. Bates ; m3devel Subject: Re: [M3devel] LLVM backend? This doesn't completely make sense to me. But it is kind of what I expected and desire. The debug format isn't the point. parse.c should have no knowledge of dwarf vs. stabs vs. coff vs. xcoff vs. codeview vs. vms vs. anything else. It just happens that the authors found a private channel in stabs. Ideally any debug format used by any C compiler can fully describe C, and Modula-3. The way it (any gcc frontend) is supposed to work is you describe the types using a compiler-internal form, and that gets translated into whatever the user requests that is supported. The primary limit as to what gcc can do is probably the object file format. Any backend without a private channel to the debugger, i.e. the C backend as well as an LLVM backend, will have degraded debugging. Perhaps a private channel can be found either way though. Like, gcc does have this "tfile" thing where after compilation, a separate tool goes over the .S file and makes changes. Ideally we don't have intermediate .S files though. Now, on Windows, for cdb/ntsd/windbg/kd, you can write debugger plugins. .dlls loaded by the debugger that have full access to symbols. They are often very helpful, and would surely help here. I do wonder if it is worth changing TEXT for debuggability. Like, say, to always be flat, no trees, and always nul terminated: (actually I'd always write two zero bytes, in case of viewing the ascii as unicode) #define TEXT_FLAGS_UNICODE (0x00000001) #define TEXT_FLAGS_CONSTANT (0x00000002) typedef struct { ??? size_t flags; ??? size_t length; ??? union { ??????? char* ascii; ??????? wchar_t* unicode; ??? } data; } *TEXT; ?? If we had merely that -- a more debugger/C-idiomatic representation for TEXT, would m3gdb's advantages decline significantly? I'd also be open to just plain typedef char* TEXT; UTF8 encoded. Text.Length is slow, and Text.Concat also slower. But ideally we'd store the length. The length could also be stored before the string. On Windows, "BSTR"s work this way. i.e. it is viable and practical and in wide use. Also, MFC/ATL CStringW/CStringA do this: typedef struct { ? wchar_t* data; } CStringW; typedef struct { ? char* data; } CStringA; and then have an entire small struct before the data. It holdes, as I recall, at least the length and a reference count. The strings are reference counted and copy-on-write. It is a nice implementation, but it isn't quite relevant here, since our TEXTs are immutable and garbage collected. The point is though, putting a struct in front of a char*/wchar_t* is viable. As long as the garbage collector doesn't get confused. Anyway, I think I'll start augmenting M3C.m3 to start writing .ll files also. We'll see how that goes. I realize it isn't the ideal path. Wrt nested variables/functions, I make a transform in the C backend. The LLVM backend will need to make a similar transform. I think the frontend should be willing/able to do this transform. It would likely help. ?- Jay ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Sat Mar 30 23:30:53 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sat, 30 Mar 2013 23:30:53 +0100 Subject: [M3devel] LLVM backend? In-Reply-To: <51546065.5030709@lcwb.coop> References: <51546065.5030709@lcwb.coop> Message-ID: I've also skimmed through DWARF last year or something like that? _It is_ more complete than stabs and while (esp m3gdb) stabs are mostly hiding and guarding data from compiler through optimizer and linker to debugger, DWARF is made to enable modification of debug info as code is modified (esp while being optimized). There is no order of magnitude big enough to express its advantage over hacked-in-stabs. -- Dragi?a Duri? dragisha at m3w.org On Mar 28, 2013, at 4:23 PM, Rodney M. Bates wrote: > LLVM has a lot of already provided support for dwarf debug info, keeping it together with code, > and helping to transform it in parallel with code, when optimizations, etc., are done. > Meanwhile, dwarf itself is vastly more complete and appears to me, from superficial study, > to be capable of representing all, or certainly most, of what is needed for good Modula-3 debugging. > For these two reasons, I think LLVM plus dwarf present by far the best method to support > a nice language-specific debugging experience, while leaving massive kludges behind. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Mar 31 01:38:59 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 31 Mar 2013 00:38:59 +0000 Subject: [M3devel] LLVM backend? In-Reply-To: References: , <51546065.5030709@lcwb.coop>, Message-ID: To be clear, changing cm3cg output dwarf is, well, the support is already there, cm3cg -gdwarf or whatever. That isn't the right thing to do though. The right thing is just cm3cg -g or -g2 or whatnot, and let the target-specific default be used. For example, on Darwin it is probably "xcoff", on Cygwin it is probably unfortunately stabs. The key is that we don't describe types in the backend. Our structs are just records with size and no fields, and member/field accesses are done by adding an offset and casting. I started fixing this. It is farther along in the C backend though. The solution isn't to write any code that knows about any debug format. - Jay From: dragisha at m3w.org Date: Sat, 30 Mar 2013 23:30:53 +0100 To: rodney_bates at lcwb.coop CC: m3devel at elegosoft.com Subject: Re: [M3devel] LLVM backend? I've also skimmed through DWARF last year or something like that. _It is_ more complete than stabs and while (esp m3gdb) stabs are mostly hiding and guarding data from compiler through optimizer and linker to debugger, DWARF is made to enable modification of debug info as code is modified (esp while being optimized). There is no order of magnitude big enough to express its advantage over hacked-in-stabs. --Dragi?a Duri?dragisha at m3w.org On Mar 28, 2013, at 4:23 PM, Rodney M. Bates wrote:LLVM has a lot of already provided support for dwarf debug info, keeping it together with code, and helping to transform it in parallel with code, when optimizations, etc., are done. Meanwhile, dwarf itself is vastly more complete and appears to me, from superficial study, to be capable of representing all, or certainly most, of what is needed for good Modula-3 debugging. For these two reasons, I think LLVM plus dwarf present by far the best method to support a nice language-specific debugging experience, while leaving massive kludges behind. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Mar 31 07:10:00 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 31 Mar 2013 05:10:00 +0000 Subject: [M3devel] opaque types again Message-ID: I don't understand opaque types. I do understand the notion of fully opaque types. That are fully revealed in one step. In C this is common: window.h struct Window_t; typedef struct Window_t Window_t; Window_t* Window_Create(); void Window_Show(Window_*t); void Window_Close(Window_*t); long Window_GetHeight(Window_*t); long Window_GetWidth(Window_*t); etc. window.c struct Window_t { ... } /* reveal */ Back to Modula-3... opaque types must be OBJECTs, right? 1. What do they provide vs. more derived types? INTERFACE Animal; TYPE T = OBJECT METHODS makeNoise(); END; INTERFACE AnimalImpl; TYPE T = Animal.T OBJECT METHODS private(); END; If I had an Animal.T and wanted to call private(), wouldn't I just NARROW it to AnimalImpl.T? Is the point that it is more efficient and avoids a runtime type check? INTERFACE Animal; TYPE Public = OBJECT METHODS makeNoise(); END; TYPE T <: Public; INTERFACE AnimalImpl; REVEAL Animal.T = Animal.Public OBJECT METHODS private(); END; ? This way I can import AnimalImpl and then just call private() without a NARROW? 2. Given that the final revelation must be a linear form of all the declared subtypes, I don't understand how the offset used by any module w/o a full revelation could be anything other than zero. I'd like to fully understand this, so I can make the C backend provide maximal type information. More pointers to structs, with members/fields, fewer untyped void*/char*. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Mar 31 08:12:12 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 31 Mar 2013 06:12:12 +0000 Subject: [M3devel] opaque types again In-Reply-To: References: Message-ID: The Green Book's explanation of Rd/Wr might have finally given me the clue I needed. Private <: ROOT; Public = Private OBJECT ... The private part is a prefix of the public part. I still don't see why this is useful, vs. more derived more private types, unless it is to safe runtime casts. I'm trying to put together a small sample to exercise opaque types..and I'm getting: *** *** runtime error: *** A compile-time type is missing. *** I wish it could say which type. :( - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Sun, 31 Mar 2013 05:10:00 +0000 Subject: [M3devel] opaque types again I don't understand opaque types. I do understand the notion of fully opaque types. That are fully revealed in one step. In C this is common: window.h struct Window_t; typedef struct Window_t Window_t; Window_t* Window_Create(); void Window_Show(Window_*t); void Window_Close(Window_*t); long Window_GetHeight(Window_*t); long Window_GetWidth(Window_*t); etc. window.c struct Window_t { ... } /* reveal */ Back to Modula-3... opaque types must be OBJECTs, right? 1. What do they provide vs. more derived types? INTERFACE Animal; TYPE T = OBJECT METHODS makeNoise(); END; INTERFACE AnimalImpl; TYPE T = Animal.T OBJECT METHODS private(); END; If I had an Animal.T and wanted to call private(), wouldn't I just NARROW it to AnimalImpl.T? Is the point that it is more efficient and avoids a runtime type check? INTERFACE Animal; TYPE Public = OBJECT METHODS makeNoise(); END; TYPE T <: Public; INTERFACE AnimalImpl; REVEAL Animal.T = Animal.Public OBJECT METHODS private(); END; ? This way I can import AnimalImpl and then just call private() without a NARROW? 2. Given that the final revelation must be a linear form of all the declared subtypes, I don't understand how the offset used by any module w/o a full revelation could be anything other than zero. I'd like to fully understand this, so I can make the C backend provide maximal type information. More pointers to structs, with members/fields, fewer untyped void*/char*. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Sun Mar 31 18:50:14 2013 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sun, 31 Mar 2013 11:50:14 -0500 Subject: [M3devel] opaque types again In-Reply-To: References: Message-ID: <51586946.6070703@lcwb.coop> On 03/31/2013 12:10 AM, Jay K wrote: > I don't understand opaque types. > It can be tricky. > > I do understand the notion of fully opaque types. That are fully revealed in one step. > In C this is common: > > > window.h > struct Window_t; > typedef struct Window_t Window_t; > Window_t* Window_Create(); > void Window_Show(Window_*t); > void Window_Close(Window_*t); > long Window_GetHeight(Window_*t); > long Window_GetWidth(Window_*t); > etc. > > window.c > struct Window_t { ... } /* reveal */ > > > Back to Modula-3... opaque types must be OBJECTs, right? > It's slightly more liberal than that. They can be any reference type, which includes object types and REF Mumble, for any Mumble. But since the subtype hierarchy has only two levels for REF types (REFANY and REF Mumble), you can only get fully opaque and fully revealed, as in the C example above. > > 1. What do they provide vs. more derived types? > > > INTERFACE Animal; > > TYPE T = OBJECT > METHODS > makeNoise(); > END; > > > INTERFACE AnimalImpl; > > TYPE T = Animal.T OBJECT > METHODS > private(); > END; > > > If I had an Animal.T and wanted to call private(), > wouldn't I just NARROW it to AnimalImpl.T? > If you allocate VAR V : Animal.T := NEW (Animal.T), the result has allocated type Animal.T, not AnimalImpl.T. So it has no method private, and even with AnimalImpl imported, trying to narrow it to AnimalImpl.T will suffer a runtime error. If you do it this way: VAR V : Animal.T := NEW (AnimalImpl.T), V still has static type Animal.T, but its runtime value is (for now, at least) an object with allocated type AnimalImpl.T, which has method private, and you can thus narrow it to AnimalImpl.T and call private. > > Is the point that it is more efficient and avoids > a runtime type check? > That's part of it. > > > INTERFACE Animal; > > TYPE Public = OBJECT > METHODS > makeNoise(); > END; > > TYPE T <: Public; > > INTERFACE AnimalImpl; > > REVEAL Animal.T = Animal.Public OBJECT > METHODS > private(); > END; > > Here, even in a context where it is not revealed, if you allocate VAR V : Animal.T := NEW (Animal.T), the allocated type has method private. Note that Animal.T here is the same type as AnimalImpl.T is in the first example. You just don't know all there is to know about what type that is. So the object still sits in the heap with all the fields and methods of the final type. If you import AnimalImpl, this gives more (static) information about the same type Animal.T instead of just a different type. So the revelation would make it statically legal to call V.private(), without needing a narrow and without a runtime check. It is statically known everywhere Animal is imported, that objects of Animal.T have all the properties of the final revealed type, even though it's not knowy what they all are. Of course, you could also do this: VAR W : Animal.Public := NEW (Animal.Public), and that would behave just like Animal.T of the first example, since those are the same type. Usually, you would probably not want to use Animal.Private in that way. It's something like a variation on the theme of an abstract supertype that you will never allocate. Sometimes I think it would help clarity if you could define a reference type as ABSTRACT, meaning it's illegal to allocate it. But that might open a can of worms in the language. Hmm, maybe I'll work on remembering to write (*ABSTRACT*) OBJECT ... I think I even did that once. > ? > This way I can import AnimalImpl and then just call private() > without a NARROW? > > Yes > > > > 2. Given that the final revelation must be a linear > form of all the declared subtypes, I don't understand > how the offset used by any module w/o a full revelation > could be anything other than zero. > Not sure this helps much, but a complication comes from the fact that you can declare a truly new subtype (not just reveal more about an existing opaque type), in a context where the opaque type is not fully revealed. IMPORT Animal (* The second version of Animal above. *) TYPE Cat = Animal.T OBJECT IsDeclawed : BOOLEAN END; The compiler will not know while separately compiling this, the offset, relative to Animal.T, where new fields of Cat will start. I have never examined the way this is implemented. I would think a typical linker's relocation or external symbol mechanism could be used to add to the offset, a component that is defined in another compilation. I think Tony understands how this is implemented. I have noted that compilations sometimes tell us they are recompiling some module because new opaque information has become available. > > I'd like to fully understand this, so I can make the C backend > provide maximal type information. More pointers to structs, with members/fields, > fewer untyped void*/char*. > If you are hoping to express Modula-3's actual static information hiding in C, I suspect that is a Quixotic quest. At the very least, you would have to replace what is really a flat struct with lots of nesting of structs for the different static visibility groups, which would just hurt readability elsewhere, in references to fields. By definition, it is a lower-level form of code here. I'd just arrange to get the full, flat struct available anywhere it is needed, and rely on the fact that the M3 front end will already have refused to pass down any references to fields that aren't statically legal in the M3 source code. There is certainly no need to get the C compiler to redundantly enforce this. > > Thanks, > - Jay > > From rodney_bates at lcwb.coop Sun Mar 31 19:40:23 2013 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sun, 31 Mar 2013 12:40:23 -0500 Subject: [M3devel] opaque types again --- A Correction In-Reply-To: <51586946.6070703@lcwb.coop> References: <51586946.6070703@lcwb.coop> Message-ID: <51587507.5020603@lcwb.coop> On 03/31/2013 11:50 AM, Rodney M. Bates wrote: > > > On 03/31/2013 12:10 AM, Jay K wrote: >> I don't understand opaque types. >> > > It can be tricky. > >> >> I do understand the notion of fully opaque types. That are fully revealed in one step. >> In C this is common: >> >> >> window.h >> struct Window_t; >> typedef struct Window_t Window_t; >> Window_t* Window_Create(); >> void Window_Show(Window_*t); >> void Window_Close(Window_*t); >> long Window_GetHeight(Window_*t); >> long Window_GetWidth(Window_*t); >> etc. >> >> window.c >> struct Window_t { ... } /* reveal */ >> >> >> Back to Modula-3... opaque types must be OBJECTs, right? >> > > It's slightly more liberal than that. They can be any reference type, which > includes object types and REF Mumble, for any Mumble. But since the subtype > hierarchy has only two levels for REF types (REFANY and REF Mumble), you can > only get fully opaque and fully revealed, as in the C example above. > >> >> 1. What do they provide vs. more derived types? >> >> >> INTERFACE Animal; >> >> TYPE T = OBJECT >> METHODS >> makeNoise(); >> END; >> >> >> INTERFACE AnimalImpl; >> >> TYPE T = Animal.T OBJECT >> METHODS >> private(); >> END; >> >> >> If I had an Animal.T and wanted to call private(), >> wouldn't I just NARROW it to AnimalImpl.T? >> > > If you allocate VAR V : Animal.T := NEW (Animal.T), the result has allocated type Animal.T, not AnimalImpl.T. > So it has no method private, and even with AnimalImpl imported, trying to narrow it to AnimalImpl.T will > suffer a runtime error. > > If you do it this way: VAR V : Animal.T := NEW (AnimalImpl.T), V still has static type Animal.T, but > its runtime value is (for now, at least) an object with allocated type AnimalImpl.T, which has method > private, and you can thus narrow it to AnimalImpl.T and call private. > >> >> Is the point that it is more efficient and avoids >> a runtime type check? >> > > That's part of it. > >> >> >> INTERFACE Animal; >> >> TYPE Public = OBJECT >> METHODS >> makeNoise(); >> END; >> >> TYPE T <: Public; >> >> INTERFACE AnimalImpl; >> >> REVEAL Animal.T = Animal.Public OBJECT >> METHODS >> private(); >> END; >> >> > > Here, even in a context where it is not revealed, if you allocate VAR V : Animal.T := NEW (Animal.T), > the allocated type has method private. Note that Animal.T here is the same type as AnimalImpl.T is > in the first example. You just don't know all there is to know about what type that is. > > So the object still sits in the heap with all the fields and methods of the final type. If you > import AnimalImpl, this gives more (static) information about the same type Animal.T instead of just > a different type. So the revelation would make it statically legal to call V.private(), without needing a > narrow and without a runtime check. It is statically known everywhere Animal is imported, that > objects of Animal.T have all the properties of the final revealed type, even though it's not knowy what > they all are. > > Of course, you could also do this: VAR W : Animal.Public := NEW (Animal.Public), and that would > behave just like Animal.T of the first example, since those are the same type. Usually, you would probably > not want to use Animal.Private in that way. It's something like a variation on the theme of an abstract Animal.Public > supertype that you will never allocate. > > Sometimes I think it would help clarity if you could define a reference type as ABSTRACT, meaning it's > illegal to allocate it. But that might open a can of worms in the language. Hmm, maybe I'll work on > remembering to write (*ABSTRACT*) OBJECT ... I think I even did that once. > >> ? >> This way I can import AnimalImpl and then just call private() >> without a NARROW? >> >> > > Yes > >> >> >> >> 2. Given that the final revelation must be a linear >> form of all the declared subtypes, I don't understand >> how the offset used by any module w/o a full revelation >> could be anything other than zero. >> > > Not sure this helps much, but a complication comes from the fact that you can declare a truly new subtype > (not just reveal more about an existing opaque type), in a context where the opaque type is not fully revealed. > > IMPORT Animal (* The second version of Animal above. *) > TYPE Cat = Animal.T OBJECT > IsDeclawed : BOOLEAN > END; > > The compiler will not know while separately compiling this, the offset, relative to Animal.T, where new fields of > Cat will start. I have never examined the way this is implemented. I would think a typical linker's relocation > or external symbol mechanism could be used to add to the offset, a component that is defined in another compilation. > I think Tony understands how this is implemented. I have noted that compilations sometimes tell us they are > recompiling some module because new opaque information has become available. > >> >> I'd like to fully understand this, so I can make the C backend >> provide maximal type information. More pointers to structs, with members/fields, >> fewer untyped void*/char*. >> > > If you are hoping to express Modula-3's actual static information hiding in C, I suspect that is a Quixotic quest. > At the very least, you would have to replace what is really a flat struct with lots of nesting of structs for > the different static visibility groups, which would just hurt readability elsewhere, in references to fields. > By definition, it is a lower-level form of code here. I'd just arrange to get the full, flat struct available > anywhere it is needed, and rely on the fact that the M3 front end will already have refused to pass down any > references to fields that aren't statically legal in the M3 source code. There is certainly no need to get > the C compiler to redundantly enforce this. > >> >> Thanks, >> - Jay >> >> > > From jay.krell at cornell.edu Sun Mar 31 21:54:28 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 31 Mar 2013 19:54:28 +0000 Subject: [M3devel] opaque types again --- A Correction In-Reply-To: <51587507.5020603@lcwb.coop> References: , <51586946.6070703@lcwb.coop>, <51587507.5020603@lcwb.coop> Message-ID: > If you allocate VAR V : Animal.T := NEW (Animal.T), > the result has allocated type Animal.T, not AnimalImpl.T. > So it has no method private, and even with AnimalImpl > imported, trying to narrow it to AnimalImpl.T will > suffer a runtime error. Sure, "creation is special" and "plain NEW doesn't necessarily suffice". One would have INTERFACE Animal or AnimalImpl; PROCEDURE Create(): Animal.T; MODULE AnimalImpl; PROCEDURE Create(): Animal.T = BEGIN RETURN NEW(AnimalTimpl.T); END Create; > I have noted that compilations sometimes tell us they are > recompiling some module because new opaque information has become available. Me too. And it appears this is an optional optimization. It initially compiles to something less efficient but correct. Then recompiles to something more efficient. > I'd just arrange to get the full, flat struct available anywhere it is needed If I can, then yes, agreed. I don't desire to hide information from the C compiler or debugger. In fact, there are related aspects of C++ that do hide too much from the debugger (e.g. COM -- all I can see in the debugger is the vtable and function pointers, instead of the debugger introspecting the most derived type and showing all the data members...) > I have never examined the way this is implemented. The generated C for my test case is surprising, very inefficient. In Main.m3 just to get the address of a.a involves like two lookups of static type data. What was the correction? Thanks, - Jay > Date: Sun, 31 Mar 2013 12:40:23 -0500 > From: rodney_bates at lcwb.coop > To: m3devel at elegosoft.com > Subject: Re: [M3devel] opaque types again --- A Correction > > > > On 03/31/2013 11:50 AM, Rodney M. Bates wrote: > > > > > > On 03/31/2013 12:10 AM, Jay K wrote: > >> I don't understand opaque types. > >> > > > > It can be tricky. > > > >> > >> I do understand the notion of fully opaque types. That are fully revealed in one step. > >> In C this is common: > >> > >> > >> window.h > >> struct Window_t; > >> typedef struct Window_t Window_t; > >> Window_t* Window_Create(); > >> void Window_Show(Window_*t); > >> void Window_Close(Window_*t); > >> long Window_GetHeight(Window_*t); > >> long Window_GetWidth(Window_*t); > >> etc. > >> > >> window.c > >> struct Window_t { ... } /* reveal */ > >> > >> > >> Back to Modula-3... opaque types must be OBJECTs, right? > >> > > > > It's slightly more liberal than that. They can be any reference type, which > > includes object types and REF Mumble, for any Mumble. But since the subtype > > hierarchy has only two levels for REF types (REFANY and REF Mumble), you can > > only get fully opaque and fully revealed, as in the C example above. > > > >> > >> 1. What do they provide vs. more derived types? > >> > >> > >> INTERFACE Animal; > >> > >> TYPE T = OBJECT > >> METHODS > >> makeNoise(); > >> END; > >> > >> > >> INTERFACE AnimalImpl; > >> > >> TYPE T = Animal.T OBJECT > >> METHODS > >> private(); > >> END; > >> > >> > >> If I had an Animal.T and wanted to call private(), > >> wouldn't I just NARROW it to AnimalImpl.T? > >> > > > > If you allocate VAR V : Animal.T := NEW (Animal.T), the result has allocated type Animal.T, not AnimalImpl.T. > > So it has no method private, and even with AnimalImpl imported, trying to narrow it to AnimalImpl.T will > > suffer a runtime error. > > > > If you do it this way: VAR V : Animal.T := NEW (AnimalImpl.T), V still has static type Animal.T, but > > its runtime value is (for now, at least) an object with allocated type AnimalImpl.T, which has method > > private, and you can thus narrow it to AnimalImpl.T and call private. > > > >> > >> Is the point that it is more efficient and avoids > >> a runtime type check? > >> > > > > That's part of it. > > > >> > >> > >> INTERFACE Animal; > >> > >> TYPE Public = OBJECT > >> METHODS > >> makeNoise(); > >> END; > >> > >> TYPE T <: Public; > >> > >> INTERFACE AnimalImpl; > >> > >> REVEAL Animal.T = Animal.Public OBJECT > >> METHODS > >> private(); > >> END; > >> > >> > > > > Here, even in a context where it is not revealed, if you allocate VAR V : Animal.T := NEW (Animal.T), > > the allocated type has method private. Note that Animal.T here is the same type as AnimalImpl.T is > > in the first example. You just don't know all there is to know about what type that is. > > > > So the object still sits in the heap with all the fields and methods of the final type. If you > > import AnimalImpl, this gives more (static) information about the same type Animal.T instead of just > > a different type. So the revelation would make it statically legal to call V.private(), without needing a > > narrow and without a runtime check. It is statically known everywhere Animal is imported, that > > objects of Animal.T have all the properties of the final revealed type, even though it's not knowy what > > they all are. > > > > Of course, you could also do this: VAR W : Animal.Public := NEW (Animal.Public), and that would > > behave just like Animal.T of the first example, since those are the same type. Usually, you would probably > > not want to use Animal.Private in that way. It's something like a variation on the theme of an abstract > Animal.Public > > supertype that you will never allocate. > > > > Sometimes I think it would help clarity if you could define a reference type as ABSTRACT, meaning it's > > illegal to allocate it. But that might open a can of worms in the language. Hmm, maybe I'll work on > > remembering to write (*ABSTRACT*) OBJECT ... I think I even did that once. > > > >> ? > >> This way I can import AnimalImpl and then just call private() > >> without a NARROW? > >> > >> > > > > Yes > > > >> > >> > >> > >> 2. Given that the final revelation must be a linear > >> form of all the declared subtypes, I don't understand > >> how the offset used by any module w/o a full revelation > >> could be anything other than zero. > >> > > > > Not sure this helps much, but a complication comes from the fact that you can declare a truly new subtype > > (not just reveal more about an existing opaque type), in a context where the opaque type is not fully revealed. > > > > IMPORT Animal (* The second version of Animal above. *) > > TYPE Cat = Animal.T OBJECT > > IsDeclawed : BOOLEAN > > END; > > > > The compiler will not know while separately compiling this, the offset, relative to Animal.T, where new fields of > > Cat will start. I have never examined the way this is implemented. I would think a typical linker's relocation > > or external symbol mechanism could be used to add to the offset, a component that is defined in another compilation. > > I think Tony understands how this is implemented. I have noted that compilations sometimes tell us they are > > recompiling some module because new opaque information has become available. > > > >> > >> I'd like to fully understand this, so I can make the C backend > >> provide maximal type information. More pointers to structs, with members/fields, > >> fewer untyped void*/char*. > >> > > > > If you are hoping to express Modula-3's actual static information hiding in C, I suspect that is a Quixotic quest. > > At the very least, you would have to replace what is really a flat struct with lots of nesting of structs for > > the different static visibility groups, which would just hurt readability elsewhere, in references to fields. > > By definition, it is a lower-level form of code here. I'd just arrange to get the full, flat struct available > > anywhere it is needed, and rely on the fact that the M3 front end will already have refused to pass down any > > references to fields that aren't statically legal in the M3 source code. There is certainly no need to get > > the C compiler to redundantly enforce this. > > > >> > >> Thanks, > >> - Jay > >> > >> > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Tue Mar 5 06:33:13 2013 From: jay.krell at cornell.edu (Jay K) Date: Tue, 5 Mar 2013 05:33:13 +0000 Subject: [M3devel] cg.declare_subrange should pass on cgtype Message-ID: cg.declare_subrange should include the cgtype the frontend is going to use for the type. I'm pretty darn certain of this. Otherwise a backend very might want/need to duplicate the logic in m3front/types/SubrangeType.m3 SetRep. The logic isn't that complicated, but really, declare_subrange should take the information. I intend to write and commit that either tonight or within a week. I assume this is ok..as I'm pretty certain of it.. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Tue Mar 5 06:56:39 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 5 Mar 2013 16:56:39 +1100 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: References: Message-ID: Isn?t it already there (implicitly) in the bitsize to be used to represent the range? The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64). The backend is supposed to respect the bitsize. So, why do you need to duplicate that information? On Mar 5, 2013, at 4:33 PM, Jay K wrote: > cg.declare_subrange should include the cgtype the frontend > is going to use for the type. > > > I'm pretty darn certain of this. > > > Otherwise a backend very might want/need to duplicate > the logic in m3front/types/SubrangeType.m3 SetRep. > > The logic isn't that complicated, but really, declare_subrange > should take the information. > > I intend to write and commit that either tonight or within a week. > I assume this is ok..as I'm pretty certain of it.. > > > - Jay > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Tue Mar 5 07:29:34 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 5 Mar 2013 17:29:34 +1100 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com> References: <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com> Message-ID: Signedness should be irrelevant. It is only the storage that is specified by this. The interpretation of the bits, including signed/unsigned, is in the operations performed on those bits. e.g., load 8 bits sign extended. Why do you need to know the signedness? Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Mobile +1 765 427 5484 On Mar 5, 2013, at 5:21 PM, Jay wrote: > Close, but also signedness. > > - Jay > > On Mar 4, 2013, at 9:56 PM, Tony Hosking wrote: > >> Isn?t it already there (implicitly) in the bitsize to be used to represent the range? >> The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64). >> The backend is supposed to respect the bitsize. >> So, why do you need to duplicate that information? >> >> On Mar 5, 2013, at 4:33 PM, Jay K wrote: >> >>> cg.declare_subrange should include the cgtype the frontend >>> is going to use for the type. >>> >>> >>> I'm pretty darn certain of this. >>> >>> >>> Otherwise a backend very might want/need to duplicate >>> the logic in m3front/types/SubrangeType.m3 SetRep. >>> >>> The logic isn't that complicated, but really, declare_subrange >>> should take the information. >>> >>> I intend to write and commit that either tonight or within a week. >>> I assume this is ok..as I'm pretty certain of it.. >>> >>> >>> - Jay >>> >>> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Tue Mar 5 07:21:25 2013 From: jay.krell at cornell.edu (Jay) Date: Mon, 4 Mar 2013 22:21:25 -0800 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: References: Message-ID: <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com> Close, but also signedness. - Jay On Mar 4, 2013, at 9:56 PM, Tony Hosking wrote: > Isn?t it already there (implicitly) in the bitsize to be used to represent the range? > The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64). > The backend is supposed to respect the bitsize. > So, why do you need to duplicate that information? > > On Mar 5, 2013, at 4:33 PM, Jay K wrote: > >> cg.declare_subrange should include the cgtype the frontend >> is going to use for the type. >> >> >> I'm pretty darn certain of this. >> >> >> Otherwise a backend very might want/need to duplicate >> the logic in m3front/types/SubrangeType.m3 SetRep. >> >> The logic isn't that complicated, but really, declare_subrange >> should take the information. >> >> I intend to write and commit that either tonight or within a week. >> I assume this is ok..as I'm pretty certain of it.. >> >> >> - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Tue Mar 5 14:30:08 2013 From: jay.krell at cornell.edu (Jay) Date: Tue, 5 Mar 2013 05:30:08 -0800 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: References: <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com> Message-ID: I want to view the value in a debugger. Without having to cast it. By your reasoning, for record fields, among float, double, int32, int64, uint32, uint64, we'd only need 2. We want strong accurate types in "declare", not just operations like "add". Declare_subrange: is there a point to domain_type? I.e. how about declare_subrange(cgtype, min, max)? I'd have to see if cm3cg and then m3gdb use it. - Jay On Mar 4, 2013, at 10:29 PM, Tony Hosking wrote: > Signedness should be irrelevant. > It is only the storage that is specified by this. > The interpretation of the bits, including signed/unsigned, is in the operations performed on those bits. > e.g., load 8 bits sign extended. > > Why do you need to know the signedness? > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Mobile +1 765 427 5484 > > > > > > On Mar 5, 2013, at 5:21 PM, Jay wrote: > >> Close, but also signedness. >> >> - Jay >> >> On Mar 4, 2013, at 9:56 PM, Tony Hosking wrote: >> >>> Isn?t it already there (implicitly) in the bitsize to be used to represent the range? >>> The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64). >>> The backend is supposed to respect the bitsize. >>> So, why do you need to duplicate that information? >>> >>> On Mar 5, 2013, at 4:33 PM, Jay K wrote: >>> >>>> cg.declare_subrange should include the cgtype the frontend >>>> is going to use for the type. >>>> >>>> >>>> I'm pretty darn certain of this. >>>> >>>> >>>> Otherwise a backend very might want/need to duplicate >>>> the logic in m3front/types/SubrangeType.m3 SetRep. >>>> >>>> The logic isn't that complicated, but really, declare_subrange >>>> should take the information. >>>> >>>> I intend to write and commit that either tonight or within a week. >>>> I assume this is ok..as I'm pretty certain of it.. >>>> >>>> >>>> - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Mar 7 03:50:25 2013 From: jay.krell at cornell.edu (Jay K) Date: Thu, 7 Mar 2013 02:50:25 +0000 Subject: [M3devel] cg.declare_subrange should pass on cgtype In-Reply-To: References: , , <9A2F4192-99A7-428C-9ED1-F2CD450EB737@gmail.com>, , Message-ID: For now I'll just check if min < 0, like cm3cg does. m3gdb does not appear to use or parse out domain_typeid. domain_typeid doesn't seem needed. I think this stuff was clearly done slightly incorrectly in the first place. Not a huge mistake. There is also wierdness imho around empty subranges. i.e. it is an unobvious language detail. If it were up to me, [10..0] would either be illegal, OR would be the same as [0..10], OR would contain the same elements as [0..10] but would iterate in reverse FOR i := FIRST([10..0]) TO LAST([10..0]) would be equivalent to FOR i := 10 to 0 BY -1. However, it not any of those. It is legal and "empty". The FOR loop, I believe, never runs. NUMBER of such an array is 0. - Jay From: jay.krell at cornell.edu Date: Tue, 5 Mar 2013 05:30:08 -0800 To: hosking at cs.purdue.edu CC: m3devel at elegosoft.com; jay.krell at cornell.edu Subject: Re: [M3devel] cg.declare_subrange should pass on cgtype I want to view the value in a debugger. Without having to cast it. By your reasoning, for record fields, among float, double, int32, int64, uint32, uint64, we'd only need 2. We want strong accurate types in "declare", not just operations like "add". Declare_subrange: is there a point to domain_type? I.e. how about declare_subrange(cgtype, min, max)? I'd have to see if cm3cg and then m3gdb use it. - Jay On Mar 4, 2013, at 10:29 PM, Tony Hosking wrote: Signedness should be irrelevant. It is only the storage that is specified by this.The interpretation of the bits, including signed/unsigned, is in the operations performed on those bits.e.g., load 8 bits sign extended. Why do you need to know the signedness? Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAMobile +1 765 427 5484 On Mar 5, 2013, at 5:21 PM, Jay wrote:Close, but also signedness. - Jay On Mar 4, 2013, at 9:56 PM, Tony Hosking wrote: Isn?t it already there (implicitly) in the bitsize to be used to represent the range?The representation CG.Type chosen in the front-end dictates exactly what is needed in terms of bits (8, 16, 32, 64).The backend is supposed to respect the bitsize.So, why do you need to duplicate that information? On Mar 5, 2013, at 4:33 PM, Jay K wrote:cg.declare_subrange should include the cgtype the frontend is going to use for the type. I'm pretty darn certain of this. Otherwise a backend very might want/need to duplicate the logic in m3front/types/SubrangeType.m3 SetRep. The logic isn't that complicated, but really, declare_subrange should take the information. I intend to write and commit that either tonight or within a week. I assume this is ok..as I'm pretty certain of it.. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Mar 7 09:05:43 2013 From: jay.krell at cornell.edu (Jay K) Date: Thu, 7 Mar 2013 08:05:43 +0000 Subject: [M3devel] funding for one full time developer? Message-ID: So...crazy self-serving question..is there enough interest and commercial use of Modula-3..such as to fund Modula-3 development? One full time developer? Me? I realize Critical Mass already tried. I do quite enjoy working on this stuff, but I don't have enough time for it. :( Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From wagner at elego.de Thu Mar 7 13:49:50 2013 From: wagner at elego.de (Olaf Wagner) Date: Thu, 7 Mar 2013 13:49:50 +0100 Subject: [M3devel] funding for one full time developer? In-Reply-To: References: Message-ID: <20130307134950.96fff38a.wagner@elego.de> On Thu, 7 Mar 2013 08:05:43 +0000 Jay K wrote: > So...crazy self-serving question..is there enough > interest and commercial use of Modula-3..such > as to fund Modula-3 development? One full time developer? Me? > > I realize Critical Mass already tried. > > I do quite enjoy working on this stuff, but I don't have enough time for it. :( Elego has never been able to find any customer willing to pay some money for M3 support or M3-related work. From a commercial point of view, our M3 engagement hasn't been a huge success ;-) I love the language and I'd really like to see it more widely used, but I'm afraid there won't be enough interest. Olaf -- Olaf Wagner -- elego Software Solutions GmbH -- http://www.elegosoft.com Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 Gesch?ftsf?hrer: Michael Diers, Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From dabenavidesd at yahoo.es Sat Mar 9 19:46:49 2013 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sat, 9 Mar 2013 18:46:49 +0000 (GMT) Subject: [M3devel] funding for one full time developer? In-Reply-To: <20130307134950.96fff38a.wagner@elego.de> Message-ID: <1362854809.42539.YahooMailClassic@web133101.mail.ir2.yahoo.com> Hi all: I disagree, there are commercial projects and industrial research projects using it, problem is normally are industrial TOP secrets. Nobody else means anymore I don't agree. Thing is normally they use their in-house compiler, Elego could find the tool chain set to sell to a given company but that company might have the most part of it already. If all projects were open I'm sure M3 will be much an open place to have experience on. I would go to work in a research project for veryfing compiler strategy for TOP industries consortium. But we would need big hackers as you and brilliant minds as Hendrik, perhaps, maybe some spot for me there, but don't count with me. Research labs were the main development sandbox for Modula-3 and continue to be for years to come. Thanks in advance --- El jue, 7/3/13, Olaf Wagner escribi?: De: Olaf Wagner Asunto: Re: [M3devel] funding for one full time developer? Para: "Jay K" CC: "m3devel" Fecha: jueves, 7 de marzo, 2013 07:49 On Thu, 7 Mar 2013 08:05:43 +0000 Jay K wrote: > So...crazy self-serving question..is there enough > interest and commercial use of Modula-3..such > as to fund Modula-3 development? One full time developer? Me? > > I realize Critical Mass already tried. > > I do quite enjoy working on this stuff, but I don't have enough time for it. :( Elego has never been able to find any customer willing to pay some money for M3 support or M3-related work. >From a commercial point of view, our M3 engagement hasn't been a huge success ;-) I love the language and I'd really like to see it more widely used, but I'm afraid there won't be enough interest. Olaf -- Olaf Wagner -- elego Software Solutions GmbH -- http://www.elegosoft.com ? ? ? ? ? ? ???Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96? mobile: +49 177 2345 869? fax: +49 30 23 45 86 95 Gesch?ftsf?hrer: Michael Diers, Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 -------------- next part -------------- An HTML attachment was scrubbed... URL: From rcolebur at SCIRES.COM Tue Mar 12 03:25:01 2013 From: rcolebur at SCIRES.COM (Coleburn, Randy) Date: Tue, 12 Mar 2013 02:25:01 +0000 Subject: [M3devel] funding for one full time developer? Message-ID: <0BB8FA59C2932741A3A2941A8B9D8BFF0C252968@ATLEX04-SRV.SCIRES.LOCAL> My company was one of the first customers for Critical Mass. We also funded some development of custom modules. I'm still a huge fan of the Modula-3 language and it is my first choice for any software development task. Alas, I don't get paid to do much software development anymore, so most of my work these days is for my own purposes, and support of prior projects. Regards, Randy Coleburn -----Original Message----- From: Olaf Wagner [mailto:wagner at elego.de] Sent: Thursday, March 07, 2013 7:50 AM To: Jay K Cc: m3devel Subject: EXT:Re: [M3devel] funding for one full time developer? On Thu, 7 Mar 2013 08:05:43 +0000 Jay K wrote: > So...crazy self-serving question..is there enough interest and > commercial use of Modula-3..such as to fund Modula-3 development? One > full time developer? Me? > > I realize Critical Mass already tried. > > I do quite enjoy working on this stuff, but I don't have enough time > for it. :( Elego has never been able to find any customer willing to pay some money for M3 support or M3-related work. >From a commercial point of view, our M3 engagement hasn't been a huge success ;-) I love the language and I'd really like to see it more widely used, but I'm afraid there won't be enough interest. Olaf -- Olaf Wagner -- elego Software Solutions GmbH -- http://www.elegosoft.com Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 Gesch?ftsf?hrer: Michael Diers, Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Tue Mar 12 06:31:13 2013 From: jay.krell at cornell.edu (Jay K) Date: Tue, 12 Mar 2013 05:31:13 +0000 Subject: [M3devel] load and store should take TypeUID parameters Message-ID: load and store should take TypeUID parameters There are multiple reasons for this. Given: TYPE Color = {Red,Blue}; PROCEDURE P1() = VAR v1 := Color.Red; BEGIN END P1; I would like to generate: preamble in all files: typedef unsigned char UINT8; typedef unsigned short UINT16; typedef unsigned int UINT32; typedef unsigned long long UINT64; (This is not quite right.) #if __GNUC__ /* >= ? */ #define M3_ENUM_SIZE #define M3_ENUM_MODE8 __attribute__((__mode__(__QI__))) #define M3_ENUM_MODE16 __attribute__((__mode__(__HI__))) #define M3_ENUM_MODE32 __attribute__((__mode__(__SI__))) #define M3_ENUM_MODE64 __attribute__((__mode__(__DI__))) #else #define M3_ENUM_MODE8 /* nothing */ #define M3_ENUM_MODE16 /* nothing */ #define M3_ENUM_MODE32 /* nothing */ #define M3_ENUM_MODE64 /* nothing */ #endif #if _MSC_VER >= 1400 && defined(__cplusplus) #define M3_ENUM_SIZE #define M3_ENUM_BASE8 : UINT8 #define M3_ENUM_BASE16 : UINT16 #define M3_ENUM_BASE32 : UINT32 #define M3_ENUM_BASE64 : UINT64 #else #define M3_ENUM_BASE8 /* nothing */ #define M3_ENUM_BASE16 /* nothing */ #define M3_ENUM_BASE32 /* nothing */ #define M3_ENUM_BASE64 /* nothing */ #endif and then: given TypeUID = 123 // declare enum #if M3_ENUM_SIZE M3_ENUM_MODE8 enum M123 M3_ENUM_MODE8 { M123_Red, M123_Blue, M123_Green }; #else typedef UINT8 M123; #define M123_Red ((M123)0) #define M123_Blue ((M123)1) #define M123_Green ((M123)2) #endif // declare typename typedef M123 Color; // smart compiler recognizes left and right are enums perhaps and therefore: #define Color_Red M123_Red #define Color_Blue M123_Blue #define Color_Green M123_Green Color v1 = M123_Red; or perhaps: Color v1 = Color_Red; or perhaps merely: Color v1 = (Color)0; and really, ideally NOT Color v1; *(UINT8*)&v1 = (UINT8)0; The readability of the right hand side isn't the most critical. What is more critical is the readability of v1 in a debugger. The last form is what we are stuck with. Similarly, given: PROCEDURE P2(VAR a: INTEGER); PROCEDURE P3(VAR a: INTEGER) = BEGIN P2(b); END P3; I want: void P2(INTEGER* a); void P3(INTEGER* a) { P2(a); } no casts. Today, I make all pointers "ADDRESS" which is void* or char*. I don't remember all the reasons why. I guess I should just get over the cast happiness and ugly C implied by using C as a backend. But I do want things to look right in a debugger. I'll iterate more..later... - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael.anderson at elegosoft.com Wed Mar 13 12:10:30 2013 From: michael.anderson at elegosoft.com (Michael Anderson) Date: Wed, 13 Mar 2013 12:10:30 +0100 Subject: [M3devel] [elego Server Maintenance 13.03.2013 21:30] Message-ID: <51405EA6.6010700@elegosoft.com> Hello, On Wednesday, March 13 at 9:30 PM, we will perform scheduled maintenance on our servers. The following sites will be affected: mail.elegosoft.com gitolite.elegosoft.com servicedesk-intern.elegosoft.com cm3-bugs.elegosoft.com projects.elegosoft.com plane.elego.de Brief interruptions of service may occur. Expected duration: 120 Min. We apologize for any inconvenience. - the elego Admins am Mittwoch, den 13.03, werden ab 21.30 Uhr planm??ige Wartungsma?nahmen an unseren Servern durchgef?hrt. Folgende Dienste werden davon betroffen: mail.elegosoft.com gitolite.elegosoft.com servicedesk-intern.elegosoft.com cm3-bugs.elegosoft.com projects.elegosoft.com plane.elego.de Es kann zur kurzzeitigen Unterbrechung mancher Dienste kommen. Voraussichtliche Dauer der Wartung: 120 Min. Wir bitten um Verst?ndnis. - die elego Admins -- Michael Anderson IT Services & Support elego Software Solutions GmbH Gustav-Meyer-Allee 25 Building 12.3 (BIG) room 227 13355 Berlin, Germany phone +49 30 23 45 86 96 michael.anderson at elegosoft.com fax +49 30 23 45 86 95 http://www.elegosoft.com Geschaeftsfuehrer: Olaf Wagner, Sitz Berlin Amtsgericht Berlin-Charlottenburg, HRB 77719, USt-IdNr: DE163214194 From dragisha at m3w.org Sun Mar 17 00:34:58 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sun, 17 Mar 2013 00:34:58 +0100 Subject: [M3devel] Interfacing to OSX Core Foundation classes Message-ID: <00DDEDB6-B1B6-45AF-9C97-62E86CD76011@m3w.org> To resolve an issue with a project, I need to wrap few functions from Security framework on OSX Lion. I have no experience on this level with OSX programming. I did a lot of such work on Linux and Windows, and all I needed there is to match signatures of functions, structure of types, and refer m3makefile to right libraries. Also, I did similar work for various non-framework libraries on OSX, and it is Unix all the way. Anyone with CF/framework related experience? Do I need some special voodoo for handling various CF opaque objects or they are simple addresses? TIA, dd -- Divided by a common language Dragi?a Duri? dragisha at m3w.org -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 495 bytes Desc: Message signed with OpenPGP using GPGMail URL: From jay.krell at cornell.edu Sun Mar 17 07:22:27 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 17 Mar 2013 06:22:27 +0000 Subject: [M3devel] unresponsiveness to control-c and control-z Message-ID: cm3's unresponsiveness to control-c and control-z, and slowness exiting from assertion failures, is a significant drain on my time. I don't know if it is Darwin specific, with its direct suspension, or if all cm3 targets have this behavior. But it really needs to be fixed. Perhaps cooperative suspend is the answer. But I'd like it fixed soon. Please. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Sun Mar 17 15:12:07 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sun, 17 Mar 2013 15:12:07 +0100 Subject: [M3devel] Interfacing to OSX Core Foundation classes In-Reply-To: <91C3D6A3-39E1-4387-B16B-1E3CEACA8FA4@gmail.com> References: <00DDEDB6-B1B6-45AF-9C97-62E86CD76011@m3w.org> <91C3D6A3-39E1-4387-B16B-1E3CEACA8FA4@gmail.com> Message-ID: <0D261766-55B8-4468-BDE2-CADA4A1BAE4D@m3w.org> After a hint from Anthony, and a share of mining, mostly due to being first-time OSX Doc Miner :), here comes result. Example code: == CoureFoundation.i3 == INTERFACE CoreFoundation; IMPORT Ctypes; TYPE TypeRef = ADDRESS; DataRef = ADDRESS; AllocatorRef = ADDRESS; Index = Ctypes.long_int; <* EXTERNAL CFRelease *> PROCEDURE Release(cf: TypeRef); <* EXTERNAL CFDataCreate *> PROCEDURE DataCreate(allocator: AllocatorRef; bytes: Ctypes.void_star; length: Index): DataRef; (* Not exactly CF, but I can split later, if need be to grow this *) END CoreFoundation. == m3makefile == ? proc use_framework(FW) is configure_c_compiler() SYSTEM_CC = SYSTEM_CC & " -framework " & FW end if equal(TARGET, "AMD64_DARWIN") use_framework("CoreFoundation") use_framework("Security") ... === I named things like this so I can "IMPORT CoreFoundation AS CF" later and use names like CF.Release(). Hope it saves few hours to somebody else :). -- Divided by a common language Dragi?a Duri? dragisha at m3w.org On Mar 17, 2013, at 3:37 AM, Antony Hosking wrote: > Should be simple addresses. > > > On Mar 16, 2013, at 6:34 PM, Dragi?a Duri? wrote: > >> To resolve an issue with a project, I need to wrap few functions from Security framework on OSX Lion. I have no experience on this level with OSX programming. >> >> I did a lot of such work on Linux and Windows, and all I needed there is to match signatures of functions, structure of types, and refer m3makefile to right libraries. Also, I did similar work for various non-framework libraries on OSX, and it is Unix all the way. >> >> Anyone with CF/framework related experience? Do I need some special voodoo for handling various CF opaque objects or they are simple addresses? >> >> TIA, >> dd >> >> -- >> Divided by a common language >> >> Dragi?a Duri? >> dragisha at m3w.org >> >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Sun Mar 17 16:24:55 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sun, 17 Mar 2013 16:24:55 +0100 Subject: [M3devel] Interfacing to OSX Core Foundation classes In-Reply-To: <52ED640E-5B43-428E-8186-7C8C7BBBF64B@darko.org> References: <00DDEDB6-B1B6-45AF-9C97-62E86CD76011@m3w.org> <91C3D6A3-39E1-4387-B16B-1E3CEACA8FA4@gmail.com> <0D261766-55B8-4468-BDE2-CADA4A1BAE4D@m3w.org> <52ED640E-5B43-428E-8186-7C8C7BBBF64B@darko.org> Message-ID: <93E972AD-5AC4-45DE-947F-FBC89E392E6E@m3w.org> My problem did not involve Objective-C, just C API's, CoreFoundation and Security were involved. I took only what I needed. Your Carbon interface is welcome - I would like to learn more about topic, as I never know when I will need it. I like to be prepared! :) Thanks in advance, dd -- Divided by a common language Dragi?a Duri? dragisha at m3w.org On Mar 17, 2013, at 4:05 PM, Darko wrote: > But what about creating objects and calling methods, or whatever they're called in Objective-C? > > Also be aware if you want to use any structures from the older interfaces and Carbon they have byte alignment and must be declared specially. I have an interface file for most Carbon stuff, but it's a bit large at 3.2MB (~500KB compressed). I can mail it if you need it. > > > On Mar 17, 2013, at 7:12 AM, Dragi?a Duri? wrote: > >> After a hint from Anthony, and a share of mining, mostly due to being first-time OSX Doc Miner :), here comes result. Example code: >> >> == CoureFoundation.i3 == >> INTERFACE CoreFoundation; >> >> IMPORT Ctypes; >> >> TYPE >> TypeRef = ADDRESS; >> DataRef = ADDRESS; >> AllocatorRef = ADDRESS; >> Index = Ctypes.long_int; >> >> <* EXTERNAL CFRelease *> >> PROCEDURE Release(cf: TypeRef); >> >> <* EXTERNAL CFDataCreate *> >> PROCEDURE DataCreate(allocator: AllocatorRef; bytes: Ctypes.void_star; length: Index): DataRef; >> >> (* Not exactly CF, but I can split later, if need be to grow this >> *) >> >> END CoreFoundation. >> == m3makefile == >> ? >> proc use_framework(FW) is >> configure_c_compiler() >> SYSTEM_CC = SYSTEM_CC & " -framework " & FW >> end >> >> if equal(TARGET, "AMD64_DARWIN") >> use_framework("CoreFoundation") >> use_framework("Security") >> ... >> === >> >> I named things like this so I can "IMPORT CoreFoundation AS CF" later and use names like CF.Release(). >> >> Hope it saves few hours to somebody else :). >> -- >> Divided by a common language >> >> Dragi?a Duri? >> dragisha at m3w.org >> >> >> >> >> On Mar 17, 2013, at 3:37 AM, Antony Hosking wrote: >> >>> Should be simple addresses. >>> >>> >>> On Mar 16, 2013, at 6:34 PM, Dragi?a Duri? wrote: >>> >>>> To resolve an issue with a project, I need to wrap few functions from Security framework on OSX Lion. I have no experience on this level with OSX programming. >>>> >>>> I did a lot of such work on Linux and Windows, and all I needed there is to match signatures of functions, structure of types, and refer m3makefile to right libraries. Also, I did similar work for various non-framework libraries on OSX, and it is Unix all the way. >>>> >>>> Anyone with CF/framework related experience? Do I need some special voodoo for handling various CF opaque objects or they are simple addresses? >>>> >>>> TIA, >>>> dd >>>> >>>> -- >>>> Divided by a common language >>>> >>>> Dragi?a Duri? >>>> dragisha at m3w.org >>>> >>>> >>>> >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From darko at darko.org Sun Mar 17 16:05:57 2013 From: darko at darko.org (Darko) Date: Sun, 17 Mar 2013 08:05:57 -0700 Subject: [M3devel] Interfacing to OSX Core Foundation classes In-Reply-To: <0D261766-55B8-4468-BDE2-CADA4A1BAE4D@m3w.org> References: <00DDEDB6-B1B6-45AF-9C97-62E86CD76011@m3w.org> <91C3D6A3-39E1-4387-B16B-1E3CEACA8FA4@gmail.com> <0D261766-55B8-4468-BDE2-CADA4A1BAE4D@m3w.org> Message-ID: <52ED640E-5B43-428E-8186-7C8C7BBBF64B@darko.org> But what about creating objects and calling methods, or whatever they're called in Objective-C? Also be aware if you want to use any structures from the older interfaces and Carbon they have byte alignment and must be declared specially. I have an interface file for most Carbon stuff, but it's a bit large at 3.2MB (~500KB compressed). I can mail it if you need it. On Mar 17, 2013, at 7:12 AM, Dragi?a Duri? wrote: > After a hint from Anthony, and a share of mining, mostly due to being first-time OSX Doc Miner :), here comes result. Example code: > > == CoureFoundation.i3 == > INTERFACE CoreFoundation; > > IMPORT Ctypes; > > TYPE > TypeRef = ADDRESS; > DataRef = ADDRESS; > AllocatorRef = ADDRESS; > Index = Ctypes.long_int; > > <* EXTERNAL CFRelease *> > PROCEDURE Release(cf: TypeRef); > > <* EXTERNAL CFDataCreate *> > PROCEDURE DataCreate(allocator: AllocatorRef; bytes: Ctypes.void_star; length: Index): DataRef; > > (* Not exactly CF, but I can split later, if need be to grow this > *) > > END CoreFoundation. > == m3makefile == > ? > proc use_framework(FW) is > configure_c_compiler() > SYSTEM_CC = SYSTEM_CC & " -framework " & FW > end > > if equal(TARGET, "AMD64_DARWIN") > use_framework("CoreFoundation") > use_framework("Security") > ... > === > > I named things like this so I can "IMPORT CoreFoundation AS CF" later and use names like CF.Release(). > > Hope it saves few hours to somebody else :). > -- > Divided by a common language > > Dragi?a Duri? > dragisha at m3w.org > > > > > On Mar 17, 2013, at 3:37 AM, Antony Hosking wrote: > >> Should be simple addresses. >> >> >> On Mar 16, 2013, at 6:34 PM, Dragi?a Duri? wrote: >> >>> To resolve an issue with a project, I need to wrap few functions from Security framework on OSX Lion. I have no experience on this level with OSX programming. >>> >>> I did a lot of such work on Linux and Windows, and all I needed there is to match signatures of functions, structure of types, and refer m3makefile to right libraries. Also, I did similar work for various non-framework libraries on OSX, and it is Unix all the way. >>> >>> Anyone with CF/framework related experience? Do I need some special voodoo for handling various CF opaque objects or they are simple addresses? >>> >>> TIA, >>> dd >>> >>> -- >>> Divided by a common language >>> >>> Dragi?a Duri? >>> dragisha at m3w.org >>> >>> >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 05:56:59 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 04:56:59 +0000 Subject: [M3devel] layout of objects? Message-ID: layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 05:55:56 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 04:55:56 +0000 Subject: [M3devel] layout of objects? Message-ID: layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 06:50:23 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 01:50:23 -0400 Subject: [M3devel] layout of objects? In-Reply-To: References: Message-ID: <431DA224-01A8-4A56-A802-970B3424305A@cs.purdue.edu> header methods pointer fields If I recall correctly. Sent from my iPad On Mar 22, 2013, at 12:55 AM, Jay K wrote: > layout of objects? > > > > How are Modula-3 objects layed out? > i.e. "OBJECT"/"METHODS"/"OVERRIDES" > I skimmed m3front and it wasn't obvious. > > > > A common way for C++ "objects" to be layed out, > in the face of no RTTI and only single inheritance, > and virtual functions, is that a pointer to a record > of function pointers is first in the record. > > > Like this: > > > class Type > { > virtual void F1(); > virtual void F2(); > int data1; > int data2; > }; > > > ends up lik more this: > > > struct TypeFunctions > { > void (*F1)(Type*); > void (*F2)(Type*); > }; > > > struct Type > { > TypeFunctions* Functions; /* always first, > or at least a fixed offset, and located independent > of the size of the data; could also be at "-1" or such */. > int data1; > int data2; > }; > > > Type* x; > x->F1(); > > > => > x->Functions->F1(x); > > > Functions added in more derived types go at the end. > Ditto for data. > In the absence of multiple-inheritance and RTTI, it is simple and predictable. > (RTTI makes only small modifications.) > > > Looking through m3front, it wasn't at all obvious if it works this way. > > > I would like to declare something in C (or possibly C++, but not likely), > such that I might actually recognize the various low level operations > and "uncompile" it back to a typeful/typesafe form, like the above C++ > to C transform. > > > > I can't likely uncompile to C++ with virtual functions, > because the actual layout in C++ is not guaranteed. > > > > Granted, I am being lazy. > I should/could compile some small samples. > But I might not get the entire story that way. > > > > Thanks, > - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Fri Mar 22 07:34:32 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Fri, 22 Mar 2013 07:34:32 +0100 Subject: [M3devel] layout of objects? In-Reply-To: References: Message-ID: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote: > layout of objects? > > > > How are Modula-3 objects layed out? > i.e. "OBJECT"/"METHODS"/"OVERRIDES" > I skimmed m3front and it wasn't obvious. > > > > A common way for C++ "objects" to be layed out, > in the face of no RTTI and only single inheritance, > and virtual functions, is that a pointer to a record > of function pointers is first in the record. > > > Like this: > > > class Type > { > virtual void F1(); > virtual void F2(); > int data1; > int data2; > }; > > > ends up lik more this: > > > struct TypeFunctions > { > void (*F1)(Type*); > void (*F2)(Type*); > }; > > > struct Type > { > TypeFunctions* Functions; /* always first, > or at least a fixed offset, and located independent > of the size of the data; could also be at "-1" or such */. > int data1; > int data2; > }; > > > Type* x; > x->F1(); > > > => > x->Functions->F1(x); > > > Functions added in more derived types go at the end. > Ditto for data. > In the absence of multiple-inheritance and RTTI, it is simple and predictable. > (RTTI makes only small modifications.) > > > Looking through m3front, it wasn't at all obvious if it works this way. > > > I would like to declare something in C (or possibly C++, but not likely), > such that I might actually recognize the various low level operations > and "uncompile" it back to a typeful/typesafe form, like the above C++ > to C transform. > > > > I can't likely uncompile to C++ with virtual functions, > because the actual layout in C++ is not guaranteed. > > > > Granted, I am being lazy. > I should/could compile some small samples. > But I might not get the entire story that way. > > > > Thanks, > - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Fri Mar 22 07:40:23 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Fri, 22 Mar 2013 07:40:23 +0100 Subject: [M3devel] layout of objects? In-Reply-To: <431DA224-01A8-4A56-A802-970B3424305A@cs.purdue.edu> References: <431DA224-01A8-4A56-A802-970B3424305A@cs.purdue.edu> Message-ID: Yes, header too. And methods pointer is a structure from RT0 (methods and everything else). And data pointer program gets is address of first of fields. On Mar 22, 2013, at 6:50 AM, Tony Hosking wrote: > header > methods pointer > fields > > If I recall correctly. > > Sent from my iPad > > On Mar 22, 2013, at 12:55 AM, Jay K wrote: > >> layout of objects? >> >> >> >> How are Modula-3 objects layed out? >> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >> I skimmed m3front and it wasn't obvious. >> >> >> >> A common way for C++ "objects" to be layed out, >> in the face of no RTTI and only single inheritance, >> and virtual functions, is that a pointer to a record >> of function pointers is first in the record. >> >> >> Like this: >> >> >> class Type >> { >> virtual void F1(); >> virtual void F2(); >> int data1; >> int data2; >> }; >> >> >> ends up lik more this: >> >> >> struct TypeFunctions >> { >> void (*F1)(Type*); >> void (*F2)(Type*); >> }; >> >> >> struct Type >> { >> TypeFunctions* Functions; /* always first, >> or at least a fixed offset, and located independent >> of the size of the data; could also be at "-1" or such */. >> int data1; >> int data2; >> }; >> >> >> Type* x; >> x->F1(); >> >> >> => >> x->Functions->F1(x); >> >> >> Functions added in more derived types go at the end. >> Ditto for data. >> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >> (RTTI makes only small modifications.) >> >> >> Looking through m3front, it wasn't at all obvious if it works this way. >> >> >> I would like to declare something in C (or possibly C++, but not likely), >> such that I might actually recognize the various low level operations >> and "uncompile" it back to a typeful/typesafe form, like the above C++ >> to C transform. >> >> >> >> I can't likely uncompile to C++ with virtual functions, >> because the actual layout in C++ is not guaranteed. >> >> >> >> Granted, I am being lazy. >> I should/could compile some small samples. >> But I might not get the entire story that way. >> >> >> >> Thanks, >> - Jay >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 07:41:33 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 06:41:33 +0000 Subject: [M3devel] layout of objects? In-Reply-To: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> References: , <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: tangent: Shouldn't the methods and header/typeinfo be combined? Or is the header mutable and per-object? But, yeah, my point is more to understand, not to question or change. Thank you, - Jay From: dragisha at m3w.org Date: Fri, 22 Mar 2013 07:34:32 +0100 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] layout of objects? It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote:layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 07:44:37 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 01:44:37 -0500 Subject: [M3devel] layout of objects? In-Reply-To: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. Heap header is at -ADRSIZE(Header). The type information in RT0 is used to initialize the object instances. On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: > It's not m3front, it's RT0. > > First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. > > On Mar 22, 2013, at 5:56 AM, Jay K wrote: > >> layout of objects? >> >> >> >> How are Modula-3 objects layed out? >> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >> I skimmed m3front and it wasn't obvious. >> >> >> >> A common way for C++ "objects" to be layed out, >> in the face of no RTTI and only single inheritance, >> and virtual functions, is that a pointer to a record >> of function pointers is first in the record. >> >> >> Like this: >> >> >> class Type >> { >> virtual void F1(); >> virtual void F2(); >> int data1; >> int data2; >> }; >> >> >> ends up lik more this: >> >> >> struct TypeFunctions >> { >> void (*F1)(Type*); >> void (*F2)(Type*); >> }; >> >> >> struct Type >> { >> TypeFunctions* Functions; /* always first, >> or at least a fixed offset, and located independent >> of the size of the data; could also be at "-1" or such */. >> int data1; >> int data2; >> }; >> >> >> Type* x; >> x->F1(); >> >> >> => >> x->Functions->F1(x); >> >> >> Functions added in more derived types go at the end. >> Ditto for data. >> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >> (RTTI makes only small modifications.) >> >> >> Looking through m3front, it wasn't at all obvious if it works this way. >> >> >> I would like to declare something in C (or possibly C++, but not likely), >> such that I might actually recognize the various low level operations >> and "uncompile" it back to a typeful/typesafe form, like the above C++ >> to C transform. >> >> >> >> I can't likely uncompile to C++ with virtual functions, >> because the actual layout in C++ is not guaranteed. >> >> >> >> Granted, I am being lazy. >> I should/could compile some small samples. >> But I might not get the entire story that way. >> >> >> >> Thanks, >> - Jay >> > Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Fri Mar 22 08:06:53 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Fri, 22 Mar 2013 08:06:53 +0100 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: <9F41859D-4A58-4DEA-94AE-401B66DF4DE5@m3w.org> Relevant part is: LOOPHOLE(res - ADRSIZE(Header), RefHeader)^ := Header{typecode := def.typecode, dirty := TRUE}; So, there ia a header, where data is combined. dirty fields is for GC, and typecode is index into RT0 structures. -- Divided by a common language Dragi?a Duri? dragisha at m3w.org On Mar 22, 2013, at 7:44 AM, Tony Hosking wrote: > Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. > Heap header is at -ADRSIZE(Header). > The type information in RT0 is used to initialize the object instances. > > On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: > >> It's not m3front, it's RT0. >> >> First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. >> >> On Mar 22, 2013, at 5:56 AM, Jay K wrote: >> >>> layout of objects? >>> >>> >>> >>> How are Modula-3 objects layed out? >>> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >>> I skimmed m3front and it wasn't obvious. >>> >>> >>> >>> A common way for C++ "objects" to be layed out, >>> in the face of no RTTI and only single inheritance, >>> and virtual functions, is that a pointer to a record >>> of function pointers is first in the record. >>> >>> >>> Like this: >>> >>> >>> class Type >>> { >>> virtual void F1(); >>> virtual void F2(); >>> int data1; >>> int data2; >>> }; >>> >>> >>> ends up lik more this: >>> >>> >>> struct TypeFunctions >>> { >>> void (*F1)(Type*); >>> void (*F2)(Type*); >>> }; >>> >>> >>> struct Type >>> { >>> TypeFunctions* Functions; /* always first, >>> or at least a fixed offset, and located independent >>> of the size of the data; could also be at "-1" or such */. >>> int data1; >>> int data2; >>> }; >>> >>> >>> Type* x; >>> x->F1(); >>> >>> >>> => >>> x->Functions->F1(x); >>> >>> >>> Functions added in more derived types go at the end. >>> Ditto for data. >>> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >>> (RTTI makes only small modifications.) >>> >>> >>> Looking through m3front, it wasn't at all obvious if it works this way. >>> >>> >>> I would like to declare something in C (or possibly C++, but not likely), >>> such that I might actually recognize the various low level operations >>> and "uncompile" it back to a typeful/typesafe form, like the above C++ >>> to C transform. >>> >>> >>> >>> I can't likely uncompile to C++ with virtual functions, >>> because the actual layout in C++ is not guaranteed. >>> >>> >>> >>> Granted, I am being lazy. >>> I should/could compile some small samples. >>> But I might not get the entire story that way. >>> >>> >>> >>> Thanks, >>> - Jay >>> >> > > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Mobile +1 765 427 5484 > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 08:01:12 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 07:01:12 +0000 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org>, Message-ID: Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? PROCEDURE Compile (p: P) = VAR x := ObjectType.MethodOffset (p.holder); method: Method.Info; BEGIN Type.Compile (p.object); Method.SplitX (p.method, method); Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); IF (x >= 0) THEN INC (method.offset, x); ELSE (* runtime offset to methods *) Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); CG.Index_bytes (Target.Byte); END; CG.Boost_alignment (Target.Address.align); CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); CG.Boost_alignment (Target.Address.align); END Compile; "runtime offset to methods"? ObjectType.MethodOffset: PROCEDURE MethodOffset (t: Type.T): INTEGER = VAR p := Confirm (t); BEGIN IF (p = NIL) THEN RETURN Unknown_w_magic END; GetOffsets (p, use_magic := TRUE); RETURN p.methodOffset; END MethodOffset; PROCEDURE Confirm (t: Type.T): P = VAR info: Type.Info; BEGIN LOOP t := Type.CheckInfo (t, info); IF (info.class = Type.Class.Object) THEN RETURN t; ELSIF (info.class = Type.Class.Opaque) THEN t := Revelation.LookUp (t); ELSE RETURN NIL; END; END; END Confirm; ... - Jay Subject: Re: [M3devel] layout of objects? From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 01:44:37 -0500 CC: jay.krell at cornell.edu; m3devel at elegosoft.com To: dragisha at m3w.org Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields.Heap header is at -ADRSIZE(Header).The type information in RT0 is used to initialize the object instances. On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote:It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote:layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAMobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 09:08:04 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 03:08:04 -0500 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org>, Message-ID: x>=0 means a known constant method offset at compile time. Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can?t know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. On Mar 22, 2013, at 2:01 AM, Jay K wrote: > Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? > > > PROCEDURE Compile (p: P) = > VAR > x := ObjectType.MethodOffset (p.holder); > method: Method.Info; > BEGIN > Type.Compile (p.object); > Method.SplitX (p.method, method); > > Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); > IF (x >= 0) THEN > INC (method.offset, x); > ELSE (* runtime offset to methods *) > Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); > CG.Index_bytes (Target.Byte); > END; > CG.Boost_alignment (Target.Address.align); > CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); > CG.Boost_alignment (Target.Address.align); > END Compile; > > > "runtime offset to methods"? > ObjectType.MethodOffset: > > PROCEDURE MethodOffset (t: Type.T): INTEGER = > VAR p := Confirm (t); > BEGIN > IF (p = NIL) THEN RETURN Unknown_w_magic END; > GetOffsets (p, use_magic := TRUE); > RETURN p.methodOffset; > END MethodOffset; > > > PROCEDURE Confirm (t: Type.T): P = > VAR info: Type.Info; > BEGIN > LOOP > t := Type.CheckInfo (t, info); > IF (info.class = Type.Class.Object) THEN > RETURN t; > ELSIF (info.class = Type.Class.Opaque) THEN > t := Revelation.LookUp (t); > ELSE > RETURN NIL; > END; > END; > END Confirm; > > > ... > > > > - Jay > > > > > > Subject: Re: [M3devel] layout of objects? > From: hosking at cs.purdue.edu > Date: Fri, 22 Mar 2013 01:44:37 -0500 > CC: jay.krell at cornell.edu; m3devel at elegosoft.com > To: dragisha at m3w.org > > Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. > Heap header is at -ADRSIZE(Header). > The type information in RT0 is used to initialize the object instances. > > On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: > > It's not m3front, it's RT0. > > First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. > > On Mar 22, 2013, at 5:56 AM, Jay K wrote: > > layout of objects? > > > > How are Modula-3 objects layed out? > i.e. "OBJECT"/"METHODS"/"OVERRIDES" > I skimmed m3front and it wasn't obvious. > > > > A common way for C++ "objects" to be layed out, > in the face of no RTTI and only single inheritance, > and virtual functions, is that a pointer to a record > of function pointers is first in the record. > > > Like this: > > > class Type > { > virtual void F1(); > virtual void F2(); > int data1; > int data2; > }; > > > ends up lik more this: > > > struct TypeFunctions > { > void (*F1)(Type*); > void (*F2)(Type*); > }; > > > struct Type > { > TypeFunctions* Functions; /* always first, > or at least a fixed offset, and located independent > of the size of the data; could also be at "-1" or such */. > int data1; > int data2; > }; > > > Type* x; > x->F1(); > > > => > x->Functions->F1(x); > > > Functions added in more derived types go at the end. > Ditto for data. > In the absence of multiple-inheritance and RTTI, it is simple and predictable. > (RTTI makes only small modifications.) > > > Looking through m3front, it wasn't at all obvious if it works this way. > > > I would like to declare something in C (or possibly C++, but not likely), > such that I might actually recognize the various low level operations > and "uncompile" it back to a typeful/typesafe form, like the above C++ > to C transform. > > > > I can't likely uncompile to C++ with virtual functions, > because the actual layout in C++ is not guaranteed. > > > > Granted, I am being lazy. > I should/could compile some small samples. > But I might not get the entire story that way. > > > > Thanks, > - Jay > > > > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 17:13:44 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 16:13:44 +0000 Subject: [M3devel] layout of objects? In-Reply-To: References: , <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org>, , , , Message-ID: Are opaque types always revealed eventually? Or only sometimes? I'd like to generate structs and member references and not be adding offsets to pointers. For method calls and record field references. And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch of integers and no indication where the frontend got them from.. :( Thanks, - Jay From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 03:08:04 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] layout of objects? x>=0 means a known constant method offset at compile time.Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. On Mar 22, 2013, at 2:01 AM, Jay K wrote:Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? PROCEDURE Compile (p: P) = VAR x := ObjectType.MethodOffset (p.holder); method: Method.Info; BEGIN Type.Compile (p.object); Method.SplitX (p.method, method); Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); IF (x >= 0) THEN INC (method.offset, x); ELSE (* runtime offset to methods *) Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); CG.Index_bytes (Target.Byte); END; CG.Boost_alignment (Target.Address.align); CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); CG.Boost_alignment (Target.Address.align); END Compile; "runtime offset to methods"? ObjectType.MethodOffset: PROCEDURE MethodOffset (t: Type.T): INTEGER = VAR p := Confirm (t); BEGIN IF (p = NIL) THEN RETURN Unknown_w_magic END; GetOffsets (p, use_magic := TRUE); RETURN p.methodOffset; END MethodOffset; PROCEDURE Confirm (t: Type.T): P = VAR info: Type.Info; BEGIN LOOP t := Type.CheckInfo (t, info); IF (info.class = Type.Class.Object) THEN RETURN t; ELSIF (info.class = Type.Class.Opaque) THEN t := Revelation.LookUp (t); ELSE RETURN NIL; END; END; END Confirm; ... - Jay Subject: Re: [M3devel] layout of objects? From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 01:44:37 -0500 CC: jay.krell at cornell.edu; m3devel at elegosoft.com To: dragisha at m3w.org Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields.Heap header is at -ADRSIZE(Header).The type information in RT0 is used to initialize the object instances. On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote:It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote:layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAMobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 19:11:59 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 14:11:59 -0400 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: Every opaque type in a linkage must have only one revelation. Sent from my iPad On Mar 22, 2013, at 12:13 PM, Jay K wrote: > Are opaque types always revealed eventually? Or only sometimes? > I'd like to generate structs and member references and not be adding offsets to pointers. > For method calls and record field references. > And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch > of integers and no indication where the frontend got them from.. :( > > > Thanks, > - Jay > > > From: hosking at cs.purdue.edu > Date: Fri, 22 Mar 2013 03:08:04 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] layout of objects? > > x>=0 means a known constant method offset at compile time. > Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. > > On Mar 22, 2013, at 2:01 AM, Jay K wrote: > > Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? > > > PROCEDURE Compile (p: P) = > VAR > x := ObjectType.MethodOffset (p.holder); > method: Method.Info; > BEGIN > Type.Compile (p.object); > Method.SplitX (p.method, method); > > Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); > IF (x >= 0) THEN > INC (method.offset, x); > ELSE (* runtime offset to methods *) > Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); > CG.Index_bytes (Target.Byte); > END; > CG.Boost_alignment (Target.Address.align); > CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); > CG.Boost_alignment (Target.Address.align); > END Compile; > > > "runtime offset to methods"? > > ObjectType.MethodOffset: > > PROCEDURE MethodOffset (t: Type.T): INTEGER = > VAR p := Confirm (t); > BEGIN > IF (p = NIL) THEN RETURN Unknown_w_magic END; > GetOffsets (p, use_magic := TRUE); > RETURN p.methodOffset; > END MethodOffset; > > > PROCEDURE Confirm (t: Type.T): P = > VAR info: Type.Info; > BEGIN > LOOP > t := Type.CheckInfo (t, info); > IF (info.class = Type.Class.Object) THEN > RETURN t; > ELSIF (info.class = Type.Class.Opaque) THEN > t := Revelation.LookUp (t); > ELSE > RETURN NIL; > END; > END; > END Confirm; > > > ... > > > > - Jay > > > > > > Subject: Re: [M3devel] layout of objects? > From: hosking at cs.purdue.edu > Date: Fri, 22 Mar 2013 01:44:37 -0500 > CC: jay.krell at cornell.edu; m3devel at elegosoft.com > To: dragisha at m3w.org > > Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. > Heap header is at -ADRSIZE(Header). > The type information in RT0 is used to initialize the object instances. > > On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: > > It's not m3front, it's RT0. > > First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. > > On Mar 22, 2013, at 5:56 AM, Jay K wrote: > > layout of objects? > > > > How are Modula-3 objects layed out? > i.e. "OBJECT"/"METHODS"/"OVERRIDES" > I skimmed m3front and it wasn't obvious. > > > > A common way for C++ "objects" to be layed out, > in the face of no RTTI and only single inheritance, > and virtual functions, is that a pointer to a record > of function pointers is first in the record. > > > Like this: > > > class Type > { > virtual void F1(); > virtual void F2(); > int data1; > int data2; > }; > > > ends up lik more this: > > > struct TypeFunctions > { > void (*F1)(Type*); > void (*F2)(Type*); > }; > > > struct Type > { > TypeFunctions* Functions; /* always first, > or at least a fixed offset, and located independent > of the size of the data; could also be at "-1" or such */. > int data1; > int data2; > }; > > > Type* x; > x->F1(); > > > => > x->Functions->F1(x); > > > Functions added in more derived types go at the end. > Ditto for data. > In the absence of multiple-inheritance and RTTI, it is simple and predictable. > (RTTI makes only small modifications.) > > > Looking through m3front, it wasn't at all obvious if it works this way. > > > I would like to declare something in C (or possibly C++, but not likely), > such that I might actually recognize the various low level operations > and "uncompile" it back to a typeful/typesafe form, like the above C++ > to C transform. > > > > I can't likely uncompile to C++ with virtual functions, > because the actual layout in C++ is not guaranteed. > > > > Granted, I am being lazy. > I should/could compile some small samples. > But I might not get the entire story that way. > > > > Thanks, > - Jay > > > > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Mobile +1 765 427 5484 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 19:18:21 2013 From: jay.krell at cornell.edu (Jay) Date: Fri, 22 Mar 2013 11:18:21 -0700 Subject: [M3devel] layout of objects? In-Reply-To: References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> Message-ID: <408C9E73-BD22-4457-9685-E661CF5A8401@gmail.com> Can it have zero revelations? Can you assist lazy me and suggest an accurate way to describe opaque types in a typeful way in C? Ultimate goal would be to get m3front & m3back optionally out of the business of computing offsets, instead using C structs and members and pointers and leave layout to the C compiler. Ultimately generating one architecture-independent, pointer-size-independent C. I understand there are multiple challenges here and eventually m3cg and m3front will need changes, to pass down more higher level information. - Jay On Mar 22, 2013, at 11:11 AM, Tony Hosking wrote: > Every opaque type in a linkage must have only one revelation. > > Sent from my iPad > > On Mar 22, 2013, at 12:13 PM, Jay K wrote: > >> Are opaque types always revealed eventually? Or only sometimes? >> I'd like to generate structs and member references and not be adding offsets to pointers. >> For method calls and record field references. >> And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch >> of integers and no indication where the frontend got them from.. :( >> >> >> Thanks, >> - Jay >> >> >> From: hosking at cs.purdue.edu >> Date: Fri, 22 Mar 2013 03:08:04 -0500 >> To: jay.krell at cornell.edu >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] layout of objects? >> >> x>=0 means a known constant method offset at compile time. >> Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. >> >> On Mar 22, 2013, at 2:01 AM, Jay K wrote: >> >> Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? >> >> >> PROCEDURE Compile (p: P) = >> VAR >> x := ObjectType.MethodOffset (p.holder); >> method: Method.Info; >> BEGIN >> Type.Compile (p.object); >> Method.SplitX (p.method, method); >> >> Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); >> IF (x >= 0) THEN >> INC (method.offset, x); >> ELSE (* runtime offset to methods *) >> Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); >> CG.Index_bytes (Target.Byte); >> END; >> CG.Boost_alignment (Target.Address.align); >> CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); >> CG.Boost_alignment (Target.Address.align); >> END Compile; >> >> >> "runtime offset to methods"? >> >> ObjectType.MethodOffset: >> >> PROCEDURE MethodOffset (t: Type.T): INTEGER = >> VAR p := Confirm (t); >> BEGIN >> IF (p = NIL) THEN RETURN Unknown_w_magic END; >> GetOffsets (p, use_magic := TRUE); >> RETURN p.methodOffset; >> END MethodOffset; >> >> >> PROCEDURE Confirm (t: Type.T): P = >> VAR info: Type.Info; >> BEGIN >> LOOP >> t := Type.CheckInfo (t, info); >> IF (info.class = Type.Class.Object) THEN >> RETURN t; >> ELSIF (info.class = Type.Class.Opaque) THEN >> t := Revelation.LookUp (t); >> ELSE >> RETURN NIL; >> END; >> END; >> END Confirm; >> >> >> ... >> >> >> >> - Jay >> >> >> >> >> >> Subject: Re: [M3devel] layout of objects? >> From: hosking at cs.purdue.edu >> Date: Fri, 22 Mar 2013 01:44:37 -0500 >> CC: jay.krell at cornell.edu; m3devel at elegosoft.com >> To: dragisha at m3w.org >> >> Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. >> Heap header is at -ADRSIZE(Header). >> The type information in RT0 is used to initialize the object instances. >> >> On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: >> >> It's not m3front, it's RT0. >> >> First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. >> >> On Mar 22, 2013, at 5:56 AM, Jay K wrote: >> >> layout of objects? >> >> >> >> How are Modula-3 objects layed out? >> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >> I skimmed m3front and it wasn't obvious. >> >> >> >> A common way for C++ "objects" to be layed out, >> in the face of no RTTI and only single inheritance, >> and virtual functions, is that a pointer to a record >> of function pointers is first in the record. >> >> >> Like this: >> >> >> class Type >> { >> virtual void F1(); >> virtual void F2(); >> int data1; >> int data2; >> }; >> >> >> ends up lik more this: >> >> >> struct TypeFunctions >> { >> void (*F1)(Type*); >> void (*F2)(Type*); >> }; >> >> >> struct Type >> { >> TypeFunctions* Functions; /* always first, >> or at least a fixed offset, and located independent >> of the size of the data; could also be at "-1" or such */. >> int data1; >> int data2; >> }; >> >> >> Type* x; >> x->F1(); >> >> >> => >> x->Functions->F1(x); >> >> >> Functions added in more derived types go at the end. >> Ditto for data. >> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >> (RTTI makes only small modifications.) >> >> >> Looking through m3front, it wasn't at all obvious if it works this way. >> >> >> I would like to declare something in C (or possibly C++, but not likely), >> such that I might actually recognize the various low level operations >> and "uncompile" it back to a typeful/typesafe form, like the above C++ >> to C transform. >> >> >> >> I can't likely uncompile to C++ with virtual functions, >> because the actual layout in C++ is not guaranteed. >> >> >> >> Granted, I am being lazy. >> I should/could compile some small samples. >> But I might not get the entire story that way. >> >> >> >> Thanks, >> - Jay >> >> >> >> >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Mobile +1 765 427 5484 >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 22:09:33 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 17:09:33 -0400 Subject: [M3devel] layout of objects? In-Reply-To: <408C9E73-BD22-4457-9685-E661CF5A8401@gmail.com> References: <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org> <408C9E73-BD22-4457-9685-E661CF5A8401@gmail.com> Message-ID: <499B305B-B07F-40EB-9E77-2EE127BAEBDA@cs.purdue.edu> From the language spec: There are two kinds of revelations, partial and complete. A program can contain any number of partial revelations for an opaque type; it must contain exactly one complete revelation. Are you typing the method table as an array? Why not simply index the array? I don?t think there is any C type that natively captures the notion of opaque types. The whole point is that you don?t know all the parent types. But you do know that, given the offset of the opaque type?s methods in the method table, you can compute the offset of any given method. For example: TYPE T <: U; Without seeing the revelation of T there is no way to know what methods are inherited from everything between T and U. But, so long as at run time you are told the method offset of T?s methods in its method table then you can find any method defined in T at a known index from that offset. On Mar 22, 2013, at 2:18 PM, Jay wrote: > Can it have zero revelations? > > > Can you assist lazy me and suggest an accurate way to describe opaque types in a typeful way in C? > > > Ultimate goal would be to get m3front & m3back optionally out of the business of computing offsets, instead using C structs and members and pointers and leave layout to the C compiler. > Ultimately generating one architecture-independent, pointer-size-independent C. > > > I understand there are multiple challenges here and eventually m3cg and m3front will need changes, to pass down more higher level information. > > > - Jay > > On Mar 22, 2013, at 11:11 AM, Tony Hosking wrote: > >> Every opaque type in a linkage must have only one revelation. >> >> Sent from my iPad >> >> On Mar 22, 2013, at 12:13 PM, Jay K wrote: >> >>> Are opaque types always revealed eventually? Or only sometimes? >>> I'd like to generate structs and member references and not be adding offsets to pointers. >>> For method calls and record field references. >>> And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch >>> of integers and no indication where the frontend got them from.. :( >>> >>> >>> Thanks, >>> - Jay >>> >>> >>> From: hosking at cs.purdue.edu >>> Date: Fri, 22 Mar 2013 03:08:04 -0500 >>> To: jay.krell at cornell.edu >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] layout of objects? >>> >>> x>=0 means a known constant method offset at compile time. >>> Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. >>> >>> On Mar 22, 2013, at 2:01 AM, Jay K wrote: >>> >>> Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? >>> >>> >>> PROCEDURE Compile (p: P) = >>> VAR >>> x := ObjectType.MethodOffset (p.holder); >>> method: Method.Info; >>> BEGIN >>> Type.Compile (p.object); >>> Method.SplitX (p.method, method); >>> >>> Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); >>> IF (x >= 0) THEN >>> INC (method.offset, x); >>> ELSE (* runtime offset to methods *) >>> Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); >>> CG.Index_bytes (Target.Byte); >>> END; >>> CG.Boost_alignment (Target.Address.align); >>> CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); >>> CG.Boost_alignment (Target.Address.align); >>> END Compile; >>> >>> >>> "runtime offset to methods"? >>> >>> ObjectType.MethodOffset: >>> >>> PROCEDURE MethodOffset (t: Type.T): INTEGER = >>> VAR p := Confirm (t); >>> BEGIN >>> IF (p = NIL) THEN RETURN Unknown_w_magic END; >>> GetOffsets (p, use_magic := TRUE); >>> RETURN p.methodOffset; >>> END MethodOffset; >>> >>> >>> PROCEDURE Confirm (t: Type.T): P = >>> VAR info: Type.Info; >>> BEGIN >>> LOOP >>> t := Type.CheckInfo (t, info); >>> IF (info.class = Type.Class.Object) THEN >>> RETURN t; >>> ELSIF (info.class = Type.Class.Opaque) THEN >>> t := Revelation.LookUp (t); >>> ELSE >>> RETURN NIL; >>> END; >>> END; >>> END Confirm; >>> >>> >>> ... >>> >>> >>> >>> - Jay >>> >>> >>> >>> >>> >>> Subject: Re: [M3devel] layout of objects? >>> From: hosking at cs.purdue.edu >>> Date: Fri, 22 Mar 2013 01:44:37 -0500 >>> CC: jay.krell at cornell.edu; m3devel at elegosoft.com >>> To: dragisha at m3w.org >>> >>> Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields. >>> Heap header is at -ADRSIZE(Header). >>> The type information in RT0 is used to initialize the object instances. >>> >>> On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote: >>> >>> It's not m3front, it's RT0. >>> >>> First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. >>> >>> On Mar 22, 2013, at 5:56 AM, Jay K wrote: >>> >>> layout of objects? >>> >>> >>> >>> How are Modula-3 objects layed out? >>> i.e. "OBJECT"/"METHODS"/"OVERRIDES" >>> I skimmed m3front and it wasn't obvious. >>> >>> >>> >>> A common way for C++ "objects" to be layed out, >>> in the face of no RTTI and only single inheritance, >>> and virtual functions, is that a pointer to a record >>> of function pointers is first in the record. >>> >>> >>> Like this: >>> >>> >>> class Type >>> { >>> virtual void F1(); >>> virtual void F2(); >>> int data1; >>> int data2; >>> }; >>> >>> >>> ends up lik more this: >>> >>> >>> struct TypeFunctions >>> { >>> void (*F1)(Type*); >>> void (*F2)(Type*); >>> }; >>> >>> >>> struct Type >>> { >>> TypeFunctions* Functions; /* always first, >>> or at least a fixed offset, and located independent >>> of the size of the data; could also be at "-1" or such */. >>> int data1; >>> int data2; >>> }; >>> >>> >>> Type* x; >>> x->F1(); >>> >>> >>> => >>> x->Functions->F1(x); >>> >>> >>> Functions added in more derived types go at the end. >>> Ditto for data. >>> In the absence of multiple-inheritance and RTTI, it is simple and predictable. >>> (RTTI makes only small modifications.) >>> >>> >>> Looking through m3front, it wasn't at all obvious if it works this way. >>> >>> >>> I would like to declare something in C (or possibly C++, but not likely), >>> such that I might actually recognize the various low level operations >>> and "uncompile" it back to a typeful/typesafe form, like the above C++ >>> to C transform. >>> >>> >>> >>> I can't likely uncompile to C++ with virtual functions, >>> because the actual layout in C++ is not guaranteed. >>> >>> >>> >>> Granted, I am being lazy. >>> I should/could compile some small samples. >>> But I might not get the entire story that way. >>> >>> >>> >>> Thanks, >>> - Jay >>> >>> >>> >>> >>> >>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>> 305 N. University Street | West Lafayette | IN 47907 | USA >>> Mobile +1 765 427 5484 >>> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 22:29:07 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 21:29:07 +0000 Subject: [M3devel] layout of objects? In-Reply-To: <499B305B-B07F-40EB-9E77-2EE127BAEBDA@cs.purdue.edu> References: , <617F9840-E16F-4AE4-9FFB-8D1A3D8B27C8@m3w.org>, , , , , , <408C9E73-BD22-4457-9685-E661CF5A8401@gmail.com>, <499B305B-B07F-40EB-9E77-2EE127BAEBDA@cs.purdue.edu> Message-ID: I'd like to reference a member in a struct, a typed function pointer.I think I see your point though.Each partial revelation describes a subset of the methods.Almost like multiple inheritance, multiple vtables, but subsequences within one linear vtable.More later.. - Jay From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 17:09:33 -0400 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] layout of objects? From the language spec: There are two kinds of revelations, partial and complete. A program can contain any number of partial revelations for an opaque type; it must contain exactly one complete revelation. Are you typing the method table as an array?Why not simply index the array? I don't think there is any C type that natively captures the notion of opaque types.The whole point is that you don't know all the parent types.But you do know that, given the offset of the opaque type's methods in the method table, you can compute the offset of any given method. For example: TYPE T <: U; Without seeing the revelation of T there is no way to know what methods are inherited from everything between T and U.But, so long as at run time you are told the method offset of T's methods in its method table then you can find any method defined in T at a known index from that offset. On Mar 22, 2013, at 2:18 PM, Jay wrote:Can it have zero revelations? Can you assist lazy me and suggest an accurate way to describe opaque types in a typeful way in C? Ultimate goal would be to get m3front & m3back optionally out of the business of computing offsets, instead using C structs and members and pointers and leave layout to the C compiler.Ultimately generating one architecture-independent, pointer-size-independent C. I understand there are multiple challenges here and eventually m3cg and m3front will need changes, to pass down more higher level information. - Jay On Mar 22, 2013, at 11:11 AM, Tony Hosking wrote: Every opaque type in a linkage must have only one revelation. Sent from my iPad On Mar 22, 2013, at 12:13 PM, Jay K wrote: Are opaque types always revealed eventually? Or only sometimes? I'd like to generate structs and member references and not be adding offsets to pointers. For method calls and record field references. And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch of integers and no indication where the frontend got them from.. :( Thanks, - Jay From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 03:08:04 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] layout of objects? x>=0 means a known constant method offset at compile time.Otherwise, offset must be loaded at run time. This is needed for opaque types, where the offset cannot be computed at run time. Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant. On Mar 22, 2013, at 2:01 AM, Jay K wrote:Do you understand hereabouts m3front/src/exprs/MethodExpr.m3? PROCEDURE Compile (p: P) = VAR x := ObjectType.MethodOffset (p.holder); method: Method.Info; BEGIN Type.Compile (p.object); Method.SplitX (p.method, method); Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE); IF (x >= 0) THEN INC (method.offset, x); ELSE (* runtime offset to methods *) Type.LoadInfo (p.holder, M3RT.OTC_methodOffset); CG.Index_bytes (Target.Byte); END; CG.Boost_alignment (Target.Address.align); CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size); CG.Boost_alignment (Target.Address.align); END Compile; "runtime offset to methods"? ObjectType.MethodOffset: PROCEDURE MethodOffset (t: Type.T): INTEGER = VAR p := Confirm (t); BEGIN IF (p = NIL) THEN RETURN Unknown_w_magic END; GetOffsets (p, use_magic := TRUE); RETURN p.methodOffset; END MethodOffset; PROCEDURE Confirm (t: Type.T): P = VAR info: Type.Info; BEGIN LOOP t := Type.CheckInfo (t, info); IF (info.class = Type.Class.Object) THEN RETURN t; ELSIF (info.class = Type.Class.Opaque) THEN t := Revelation.LookUp (t); ELSE RETURN NIL; END; END; END Confirm; ... - Jay Subject: Re: [M3devel] layout of objects? From: hosking at cs.purdue.edu Date: Fri, 22 Mar 2013 01:44:37 -0500 CC: jay.krell at cornell.edu; m3devel at elegosoft.com To: dragisha at m3w.org Not quite. I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields.Heap header is at -ADRSIZE(Header).The type information in RT0 is used to initialize the object instances. On Mar 22, 2013, at 1:34 AM, Dragi?a Duri? wrote:It's not m3front, it's RT0. First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0. On Mar 22, 2013, at 5:56 AM, Jay K wrote:layout of objects? How are Modula-3 objects layed out? i.e. "OBJECT"/"METHODS"/"OVERRIDES" I skimmed m3front and it wasn't obvious. A common way for C++ "objects" to be layed out, in the face of no RTTI and only single inheritance, and virtual functions, is that a pointer to a record of function pointers is first in the record. Like this: class Type { virtual void F1(); virtual void F2(); int data1; int data2; }; ends up lik more this: struct TypeFunctions { void (*F1)(Type*); void (*F2)(Type*); }; struct Type { TypeFunctions* Functions; /* always first, or at least a fixed offset, and located independent of the size of the data; could also be at "-1" or such */. int data1; int data2; }; Type* x; x->F1(); => x->Functions->F1(x); Functions added in more derived types go at the end. Ditto for data. In the absence of multiple-inheritance and RTTI, it is simple and predictable. (RTTI makes only small modifications.) Looking through m3front, it wasn't at all obvious if it works this way. I would like to declare something in C (or possibly C++, but not likely), such that I might actually recognize the various low level operations and "uncompile" it back to a typeful/typesafe form, like the above C++ to C transform. I can't likely uncompile to C++ with virtual functions, because the actual layout in C++ is not guaranteed. Granted, I am being lazy. I should/could compile some small samples. But I might not get the entire story that way. Thanks, - Jay Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAMobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Mar 22 22:30:02 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 21:30:02 +0000 Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: <20130322194459.GE12913@tucnak.redhat.com> References: <20130322194459.GE12913@tucnak.redhat.com> Message-ID: Perhaps we should use this. I'm more inclined to work on the C backend though. - Jay > Date: Fri, 22 Mar 2013 20:44:59 +0100 > From: jakub at redhat.com > To: gcc-announce at gcc.gnu.org > Subject: GCC 4.8.0 Released > > Exactly one year after the last major GCC release has been announced, > celebrating the 26th anniversary of the GNU Compiler Collection, > the GCC development team announces a new major GCC release, 4.8.0. > > GCC 4.8.0 is a major release containing substantial new > functionality not available in GCC 4.7.x or previous GCC releases. > > GCC 4.8 features a new Local Register Allocator which replaces the 26 > years old reload pass and improves generated code quality on ia32 and > x86-64 targets. The C++ frontend and standard library have been > enhanced with various improvements for C++11 support not limited to C++11 > attribute syntax, thread_local or inheriting constructors support. > > AddressSanitizer and ThreadSanitizer instrumentation have been > added to detect heap, stack and global buffer overflows, uses after free > and data races. > > Many scalability bottle-necks have been removed from GCC optimization > passes, thus it is now possible to compile extremely large functions with > smaller memory consumption in less time. > > Extending the widest support for hardware architectures in the industry, > GCC 4.8 has gained support for the upcoming 64-bit ARM instruction set > architecture, AArch64. GCC 4.8 also features support for Hardware > Transactional Memory on the upcoming Intel Haswell CPU architecture. > The S/390 target now supports the zEC12 architecture. The ARM 32-bit > target has gained support for AArch32 ARM v8 ISA additions. > > See > > http://gcc.gnu.org/gcc-4.8/changes.html > > for more information about changes in GCC 4.8. > > This release is available from the FTP servers listed here: > > http://www.gnu.org/order/ftp.html > > The release is in gcc/gcc-4.8.0/ subdirectory. > > If you encounter difficulties using GCC 4.8, please do not contact me > directly. Instead, please visit http://gcc.gnu.org for information > about getting help. > > > Driving a leading free software project such as GNU Compiler Collection > would not be possible without support from its many contributors. > Not to only mention its developers but especially its regular testers > and users which contribute to its high quality. The list of individuals > is too large to thank individually! -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Mar 22 22:56:00 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 22 Mar 2013 17:56:00 -0400 Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: References: <20130322194459.GE12913@tucnak.redhat.com> Message-ID: In my opinion it would be better to work on an LLVM backend. On Mar 22, 2013, at 5:30 PM, Jay K wrote: > > > Perhaps we should use this. I'm more inclined to work on the C backend though. > > - Jay > > Date: Fri, 22 Mar 2013 20:44:59 +0100 > > From: jakub at redhat.com > > To: gcc-announce at gcc.gnu.org > > Subject: GCC 4.8.0 Released > > > > Exactly one year after the last major GCC release has been announced, > > celebrating the 26th anniversary of the GNU Compiler Collection, > > the GCC development team announces a new major GCC release, 4.8.0. > > > > GCC 4.8.0 is a major release containing substantial new > > functionality not available in GCC 4.7.x or previous GCC releases. > > > > GCC 4.8 features a new Local Register Allocator which replaces the 26 > > years old reload pass and improves generated code quality on ia32 and > > x86-64 targets. The C++ frontend and standard library have been > > enhanced with various improvements for C++11 support not limited to C++11 > > attribute syntax, thread_local or inheriting constructors support. > > > > AddressSanitizer and ThreadSanitizer instrumentation have been > > added to detect heap, stack and global buffer overflows, uses after free > > and data races. > > > > Many scalability bottle-necks have been removed from GCC optimization > > passes, thus it is now possible to compile extremely large functions with > > smaller memory consumption in less time. > > > > Extending the widest support for hardware architectures in the industry, > > GCC 4.8 has gained support for the upcoming 64-bit ARM instruction set > > architecture, AArch64. GCC 4.8 also features support for Hardware > > Transactional Memory on the upcoming Intel Haswell CPU architecture. > > The S/390 target now supports the zEC12 architecture. The ARM 32-bit > > target has gained support for AArch32 ARM v8 ISA additions. > > > > See > > > > http://gcc.gnu.org/gcc-4.8/changes.html > > > > for more information about changes in GCC 4.8. > > > > This release is available from the FTP servers listed here: > > > > http://www.gnu.org/order/ftp.html > > > > The release is in gcc/gcc-4.8.0/ subdirectory. > > > > If you encounter difficulties using GCC 4.8, please do not contact me > > directly. Instead, please visit http://gcc.gnu.org for information > > about getting help. > > > > > > Driving a leading free software project such as GNU Compiler Collection > > would not be possible without support from its many contributors. > > Not to only mention its developers but especially its regular testers > > and users which contribute to its high quality. The list of individuals > > is too large to thank individually! -------------- next part -------------- An HTML attachment was scrubbed... URL: From lemming at henning-thielemann.de Fri Mar 22 22:57:29 2013 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Fri, 22 Mar 2013 22:57:29 +0100 (CET) Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: References: <20130322194459.GE12913@tucnak.redhat.com> Message-ID: On Fri, 22 Mar 2013, Tony Hosking wrote: > In my opinion it would be better to work on an LLVM backend. Btw. does someone of you attend to the Euro-LLVM meeting 29-30th April? From jay.krell at cornell.edu Sat Mar 23 00:05:16 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 22 Mar 2013 23:05:16 +0000 Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: References: <20130322194459.GE12913@tucnak.redhat.com>, , , Message-ID: I favor a C backend for a few reasons. - portability -- C supports more than LLVM, past and future I haven't been able to build LLVM on my old MacOSX. - a possible portable source distribution, like most software, but, granted, not like many compilers, and granted, while the C backend now works quite well, this problem still needs a lot of work - Not having to learn LLVM, resting on my C knowledge; might apply to others - LLVM might have the same m3gdb integration problem as C, no better, no worse On the other hand, LLVM is good for: - learn something new - resulting compiler will probably run faster - Jay > Date: Fri, 22 Mar 2013 22:57:29 +0100 > From: lemming at henning-thielemann.de > To: m3devel at elegosoft.com > Subject: Re: [M3devel] FW: GCC 4.8.0 Released > > > On Fri, 22 Mar 2013, Tony Hosking wrote: > > > In my opinion it would be better to work on an LLVM backend. > > Btw. does someone of you attend to the Euro-LLVM meeting 29-30th April? -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sat Mar 23 01:57:46 2013 From: jay.krell at cornell.edu (Jay K) Date: Sat, 23 Mar 2013 00:57:46 +0000 Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: References: <20130322194459.GE12913@tucnak.redhat.com>, , , , , , , Message-ID: (but, ps, for high-end full time wages I'd write an LLVM backend or port to gcc 4.8.0 or port the existing integrated x86 backend, or other, and be more flexible/open-minded. :) Yes I know that is kind of rude and against the spirit of things... ) - JayFrom: jay.krell at cornell.edu To: lemming at henning-thielemann.de; m3devel at elegosoft.com Date: Fri, 22 Mar 2013 23:05:16 +0000 Subject: Re: [M3devel] FW: GCC 4.8.0 Released I favor a C backend for a few reasons. - portability -- C supports more than LLVM, past and future I haven't been able to build LLVM on my old MacOSX. - a possible portable source distribution, like most software, but, granted, not like many compilers, and granted, while the C backend now works quite well, this problem still needs a lot of work - Not having to learn LLVM, resting on my C knowledge; might apply to others - LLVM might have the same m3gdb integration problem as C, no better, no worse On the other hand, LLVM is good for: - learn something new - resulting compiler will probably run faster - Jay > Date: Fri, 22 Mar 2013 22:57:29 +0100 > From: lemming at henning-thielemann.de > To: m3devel at elegosoft.com > Subject: Re: [M3devel] FW: GCC 4.8.0 Released > > > On Fri, 22 Mar 2013, Tony Hosking wrote: > > > In my opinion it would be better to work on an LLVM backend. > > Btw. does someone of you attend to the Euro-LLVM meeting 29-30th April? -------------- next part -------------- An HTML attachment was scrubbed... URL: From dabenavidesd at yahoo.es Sat Mar 23 16:19:26 2013 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sat, 23 Mar 2013 15:19:26 +0000 (GMT) Subject: [M3devel] FW: GCC 4.8.0 Released In-Reply-To: Message-ID: <1364051966.34337.YahooMailClassic@web133101.mail.ir2.yahoo.com> Hi : a bytecoded interpreter would make the trick to boot from m3c instead of using a compiler. Was natural choice in Pascal. Thanks in advance --- El vie, 22/3/13, Jay K escribi?: De: Jay K Asunto: Re: [M3devel] FW: GCC 4.8.0 Released Para: "Henning Thielemann" , "m3devel" Fecha: viernes, 22 de marzo, 2013 19:57 (but, ps,?for high-end full time?wages I'd write an LLVM backend or port to gcc 4.8.0 or port the existing integrated x86 backend, or other, and be more flexible/open-minded.?:) Yes I know that is kind of rude and against the spirit of things... ) ? ?- Jay From: jay.krell at cornell.edu To: lemming at henning-thielemann.de; m3devel at elegosoft.com Date: Fri, 22 Mar 2013 23:05:16 +0000 Subject: Re: [M3devel] FW: GCC 4.8.0 Released I?favor a C backend for a few reasons. ??-?portability -- C?supports more than LLVM, past and future ???? I haven't been able to build LLVM on my old MacOSX.? ??- a possible portable source?distribution, like most software, but,?granted, not like many compilers, and granted, while the C backend now works quite well, this problem still needs a lot of work ? -?Not having to learn LLVM, resting on my C knowledge; might apply to others ?? ? - LLVM might have the same?m3gdb integration problem as C, no better, no worse ? ? ? ?On the other hand, LLVM is good for: ?? - learn something new ?? - resulting compiler?will?probably run faster ? ? ?- Jay? > Date: Fri, 22 Mar 2013 22:57:29 +0100 > From: lemming at henning-thielemann.de > To: m3devel at elegosoft.com > Subject: Re: [M3devel] FW: GCC 4.8.0 Released > > > On Fri, 22 Mar 2013, Tony Hosking wrote: > > > In my opinion it would be better to work on an LLVM backend. > > Btw. does someone of you attend to the Euro-LLVM meeting 29-30th April? -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Mar 28 06:04:46 2013 From: jay.krell at cornell.edu (Jay K) Date: Thu, 28 Mar 2013 05:04:46 +0000 Subject: [M3devel] LLVM backend? Message-ID: I was thinking of looking into LLVM more. For selfish reasons -- resume growth, but no matter. 1) Tony, are you making progress? Should I wait? Collaberate? Go it alone? 2) An LLVM backend would I suspect have the same lack of m3gdb support as a C backend. Does that bother people?Actually I was just skimming "parse.c"..I don't remember exactly how I decided it is all a stabs-specific hack.Though, I do realize 1) typeids are encoded in identifier names, which certainly hurts debuggingw/o m3gdb 2) types aren't being described as they ought to be. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Mar 28 06:39:35 2013 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 28 Mar 2013 16:39:35 +1100 Subject: [M3devel] LLVM backend? In-Reply-To: References: Message-ID: I am short of the time needed to make real progress. I am happy to collaborate even if only in an advisory role. I have some of the design written down, but other aspects in my head. For example, dealing with lexically scoped variables for nested functions requires capturing all the "escaping" variables (referenced by inner scope functions) into a properly typed "frame" structure, along with the static link, and whose pointer can be passed as the static link to inner scope functions. On Mar 28, 2013, at 4:04 PM, Jay K wrote: > I was thinking of looking into LLVM more. For selfish reasons -- resume growth, but no matter. > > 1) Tony, are you making progress? Should I wait? Collaberate? Go it alone? > 2) An LLVM backend would I suspect have the same lack of m3gdb support as a C backend. > Does that bother people? > Actually I was just skimming "parse.c"..I don't remember exactly how I decided it is all a stabs-specific hack. > Though, I do realize 1) typeids are encoded in identifier names, which certainly hurts debugging > w/o m3gdb 2) types aren't being described as they ought to be. > > - Jay > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Thu Mar 28 16:23:17 2013 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Thu, 28 Mar 2013 10:23:17 -0500 Subject: [M3devel] LLVM backend? In-Reply-To: References: Message-ID: <51546065.5030709@lcwb.coop> On 03/28/2013 12:04 AM, Jay K wrote: > I was thinking of looking into LLVM more. For selfish reasons -- resume growth, but no matter. > > 1) Tony, are you making progress? Should I wait? Collaberate? Go it alone? (Jay, I reversed the order of your paragraphs here, because my responses make more sense in that order.) > Actually I was just skimming "parse.c"..I don't remember exactly how I decided it is all a stabs-specific hack. > Though, I do realize 1) typeids are encoded in identifier names, which certainly hurts debugging > w/o m3gdb 2) types aren't being described as they ought to be. > Yes, it is very much a hack. For one thing, stabs itself is something of a hack. For another, a lot of the fields of stabs info are really treated as just containers for some extremely Modula-3-specific info, that, to be fair, isn't provided for in any reasonable way by true stabs. Meanwhile, some true stabs stuff is produced too, but not used in m3gdb, because it isn't quite right or helpful. parse.c and m3gdb are highly coupled by all this. Stock gdb's code to read stabs is augmented by tons of stuff to further decode the M3-specific info inserted by parse.c, and tons more to interpret it. Moreover, debug info and code to be translated effectively become diverging streams in parse.c, notwithstanding the fact that they are often interspersed. This makes it very difficult for debug info to reflect anything gcc does to the code. I believe the stabs info is mostly or entirely untouched after parse.c, though I haven't ever thoroughly vetted this. One specific place where this particularly hurts right now is with nonlocal references, static links, etc. With the advent of tree-nested.c, in later gcc versions, the runtime storage model is drastically reworked in gcc, after the stabs has already been produced. That seriously broke a lot of stuff I had working in m3gdb. I have dabbled with Mickey- Mouse schemes to emit purely additional stabs info in tree-nested.c, without changing what was already there, then have m3gdb use it to selectively override the earlier-produced stabs. I never finished this, and have only limited confidence it is even feasible. > 2) An LLVM backend would I suspect have the same lack of m3gdb support as a C backend. > Does that bother people? LLVM has a lot of already provided support for dwarf debug info, keeping it together with code, and helping to transform it in parallel with code, when optimizations, etc., are done. Meanwhile, dwarf itself is vastly more complete and appears to me, from superficial study, to be capable of representing all, or certainly most, of what is needed for good Modula-3 debugging. For these two reasons, I think LLVM plus dwarf present by far the best method to support a nice language-specific debugging experience, while leaving massive kludges behind. This is one big reason why I support an LLVM back end. It would indeed require significant work to get debug support. But it would be so much easier and far more pleasant than the alternatives. That includes even the alternative of further fixing the existing m3gdb/gcc, which still needs perhaps as much additional work as has already gone into it. I am attached to it only because it now provides a lot more function than anything else we have (and which I use a lot). Mucking around in M3ified stabs is, for me, strictly a destination, not a journey. So, the short answer is, it bothers me less than any other option. From jay.krell at cornell.edu Fri Mar 29 17:09:09 2013 From: jay.krell at cornell.edu (Jay K) Date: Fri, 29 Mar 2013 16:09:09 +0000 Subject: [M3devel] LLVM backend? In-Reply-To: <51546065.5030709@lcwb.coop> References: , <51546065.5030709@lcwb.coop> Message-ID: This doesn't completely make sense to me. But it is kind of what I expected and desire. The debug format isn't the point. parse.c should have no knowledge of dwarf vs. stabs vs. coff vs. xcoff vs. codeview vs. vms vs. anything else. It just happens that the authors found a private channel in stabs. Ideally any debug format used by any C compiler can fully describe C, and Modula-3. The way it (any gcc frontend) is supposed to work is you describe the types using a compiler-internal form, and that gets translated into whatever the user requests that is supported. The primary limit as to what gcc can do is probably the object file format. Any backend without a private channel to the debugger, i.e. the C backend as well as an LLVM backend, will have degraded debugging. Perhaps a private channel can be found either way though. Like, gcc does have this "tfile" thing where after compilation, a separate tool goes over the .S file and makes changes. Ideally we don't have intermediate .S files though. Now, on Windows, for cdb/ntsd/windbg/kd, you can write debugger plugins. .dlls loaded by the debugger that have full access to symbols. They are often very helpful, and would surely help here. I do wonder if it is worth changing TEXT for debuggability. Like, say, to always be flat, no trees, and always nul terminated: (actually I'd always write two zero bytes, in case of viewing the ascii as unicode) #define TEXT_FLAGS_UNICODE (0x00000001) #define TEXT_FLAGS_CONSTANT (0x00000002) typedef struct { size_t flags; size_t length; union { char* ascii; wchar_t* unicode; } data; } *TEXT; ? If we had merely that -- a more debugger/C-idiomatic representation for TEXT, would m3gdb's advantages decline significantly? I'd also be open to just plain typedef char* TEXT; UTF8 encoded. Text.Length is slow, and Text.Concat also slower. But ideally we'd store the length. The length could also be stored before the string. On Windows, "BSTR"s work this way. i.e. it is viable and practical and in wide use. Also, MFC/ATL CStringW/CStringA do this: typedef struct { wchar_t* data; } CStringW; typedef struct { char* data; } CStringA; and then have an entire small struct before the data. It holdes, as I recall, at least the length and a reference count. The strings are reference counted and copy-on-write. It is a nice implementation, but it isn't quite relevant here, since our TEXTs are immutable and garbage collected. The point is though, putting a struct in front of a char*/wchar_t* is viable. As long as the garbage collector doesn't get confused. Anyway, I think I'll start augmenting M3C.m3 to start writing .ll files also. We'll see how that goes. I realize it isn't the ideal path. Wrt nested variables/functions, I make a transform in the C backend. The LLVM backend will need to make a similar transform. I think the frontend should be willing/able to do this transform. It would likely help. - Jay > Date: Thu, 28 Mar 2013 10:23:17 -0500 > From: rodney_bates at lcwb.coop > To: m3devel at elegosoft.com > Subject: Re: [M3devel] LLVM backend? > > > > On 03/28/2013 12:04 AM, Jay K wrote: > > I was thinking of looking into LLVM more. For selfish reasons -- resume growth, but no matter. > > > > 1) Tony, are you making progress? Should I wait? Collaberate? Go it alone? > > (Jay, I reversed the order of your paragraphs here, because my responses make more sense in that order.) > > > Actually I was just skimming "parse.c"..I don't remember exactly how I decided it is all a stabs-specific hack. > > Though, I do realize 1) typeids are encoded in identifier names, which certainly hurts debugging > > w/o m3gdb 2) types aren't being described as they ought to be. > > > > Yes, it is very much a hack. For one thing, stabs itself is something of a hack. For another, > a lot of the fields of stabs info are really treated as just containers for some extremely > Modula-3-specific info, that, to be fair, isn't provided for in any reasonable way by > true stabs. Meanwhile, some true stabs stuff is produced too, but not used in m3gdb, because > it isn't quite right or helpful. parse.c and m3gdb are highly coupled by all this. Stock gdb's > code to read stabs is augmented by tons of stuff to further decode the M3-specific info > inserted by parse.c, and tons more to interpret it. > > Moreover, debug info and code to be translated effectively become diverging streams in > parse.c, notwithstanding the fact that they are often interspersed. This makes it very > difficult for debug info to reflect anything gcc does to the code. I believe the stabs > info is mostly or entirely untouched after parse.c, though I haven't ever thoroughly > vetted this. > > One specific place where this particularly hurts right now is with nonlocal references, > static links, etc. With the advent of tree-nested.c, in later gcc versions, the runtime > storage model is drastically reworked in gcc, after the stabs has already been produced. > That seriously broke a lot of stuff I had working in m3gdb. I have dabbled with Mickey- > Mouse schemes to emit purely additional stabs info in tree-nested.c, without changing what > was already there, then have m3gdb use it to selectively override the earlier-produced > stabs. I never finished this, and have only limited confidence it is even feasible. > > > 2) An LLVM backend would I suspect have the same lack of m3gdb support as a C backend. > > Does that bother people? > > LLVM has a lot of already provided support for dwarf debug info, keeping it together with code, > and helping to transform it in parallel with code, when optimizations, etc., are done. > Meanwhile, dwarf itself is vastly more complete and appears to me, from superficial study, > to be capable of representing all, or certainly most, of what is needed for good Modula-3 debugging. > For these two reasons, I think LLVM plus dwarf present by far the best method to support > a nice language-specific debugging experience, while leaving massive kludges behind. > > This is one big reason why I support an LLVM back end. It would indeed require significant > work to get debug support. But it would be so much easier and far more pleasant than > the alternatives. That includes even the alternative of further fixing the existing m3gdb/gcc, > which still needs perhaps as much additional work as has already gone into it. I am > attached to it only because it now provides a lot more function than anything else > we have (and which I use a lot). Mucking around in M3ified stabs is, for me, strictly a > destination, not a journey. > > So, the short answer is, it bothers me less than any other option. > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dmuysers at hotmail.com Fri Mar 29 17:58:54 2013 From: dmuysers at hotmail.com (Dirk Muysers) Date: Fri, 29 Mar 2013 17:58:54 +0100 Subject: [M3devel] LLVM backend? In-Reply-To: References: , <51546065.5030709@lcwb.coop> Message-ID: For me, the best debugger architecture still remains the one designed by D.R.Hanson: http://research.microsoft.com/pubs/69690/tr-99-04.pdf platform-independent and easy to implement. From: Jay K Sent: Friday, March 29, 2013 5:09 PM To: Rodney M. Bates ; m3devel Subject: Re: [M3devel] LLVM backend? This doesn't completely make sense to me. But it is kind of what I expected and desire. The debug format isn't the point. parse.c should have no knowledge of dwarf vs. stabs vs. coff vs. xcoff vs. codeview vs. vms vs. anything else. It just happens that the authors found a private channel in stabs. Ideally any debug format used by any C compiler can fully describe C, and Modula-3. The way it (any gcc frontend) is supposed to work is you describe the types using a compiler-internal form, and that gets translated into whatever the user requests that is supported. The primary limit as to what gcc can do is probably the object file format. Any backend without a private channel to the debugger, i.e. the C backend as well as an LLVM backend, will have degraded debugging. Perhaps a private channel can be found either way though. Like, gcc does have this "tfile" thing where after compilation, a separate tool goes over the .S file and makes changes. Ideally we don't have intermediate .S files though. Now, on Windows, for cdb/ntsd/windbg/kd, you can write debugger plugins. .dlls loaded by the debugger that have full access to symbols. They are often very helpful, and would surely help here. I do wonder if it is worth changing TEXT for debuggability. Like, say, to always be flat, no trees, and always nul terminated: (actually I'd always write two zero bytes, in case of viewing the ascii as unicode) #define TEXT_FLAGS_UNICODE (0x00000001) #define TEXT_FLAGS_CONSTANT (0x00000002) typedef struct { size_t flags; size_t length; union { char* ascii; wchar_t* unicode; } data; } *TEXT; ? If we had merely that -- a more debugger/C-idiomatic representation for TEXT, would m3gdb's advantages decline significantly? I'd also be open to just plain typedef char* TEXT; UTF8 encoded. Text.Length is slow, and Text.Concat also slower. But ideally we'd store the length. The length could also be stored before the string. On Windows, "BSTR"s work this way. i.e. it is viable and practical and in wide use. Also, MFC/ATL CStringW/CStringA do this: typedef struct { wchar_t* data; } CStringW; typedef struct { char* data; } CStringA; and then have an entire small struct before the data. It holdes, as I recall, at least the length and a reference count. The strings are reference counted and copy-on-write. It is a nice implementation, but it isn't quite relevant here, since our TEXTs are immutable and garbage collected. The point is though, putting a struct in front of a char*/wchar_t* is viable. As long as the garbage collector doesn't get confused. Anyway, I think I'll start augmenting M3C.m3 to start writing .ll files also. We'll see how that goes. I realize it isn't the ideal path. Wrt nested variables/functions, I make a transform in the C backend. The LLVM backend will need to make a similar transform. I think the frontend should be willing/able to do this transform. It would likely help. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From dabenavidesd at yahoo.es Fri Mar 29 22:24:41 2013 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Fri, 29 Mar 2013 21:24:41 +0000 (GMT) Subject: [M3devel] LLVM backend? In-Reply-To: Message-ID: <1364592281.98024.YahooMailClassic@web172804.mail.ir2.yahoo.com> Hi all: Im starting to get nervous of so many things going on and Cm3 going anywhere. We need to release something rather sooner than later. Thanks in advance --- El vie, 29/3/13, Dirk Muysers escribi?: De: Dirk Muysers Asunto: Re: [M3devel] LLVM backend? Para: m3devel at elegosoft.com, "Jay K" Fecha: viernes, 29 de marzo, 2013 11:58 For me, the best debugger architecture still remains the one designed by D.R.Hanson: ? http://research.microsoft.com/pubs/69690/tr-99-04.pdf ? platform-independent and easy to implement. From: Jay K Sent: Friday, March 29, 2013 5:09 PM To: Rodney M. Bates ; m3devel Subject: Re: [M3devel] LLVM backend? This doesn't completely make sense to me. But it is kind of what I expected and desire. The debug format isn't the point. parse.c should have no knowledge of dwarf vs. stabs vs. coff vs. xcoff vs. codeview vs. vms vs. anything else. It just happens that the authors found a private channel in stabs. Ideally any debug format used by any C compiler can fully describe C, and Modula-3. The way it (any gcc frontend) is supposed to work is you describe the types using a compiler-internal form, and that gets translated into whatever the user requests that is supported. The primary limit as to what gcc can do is probably the object file format. Any backend without a private channel to the debugger, i.e. the C backend as well as an LLVM backend, will have degraded debugging. Perhaps a private channel can be found either way though. Like, gcc does have this "tfile" thing where after compilation, a separate tool goes over the .S file and makes changes. Ideally we don't have intermediate .S files though. Now, on Windows, for cdb/ntsd/windbg/kd, you can write debugger plugins. .dlls loaded by the debugger that have full access to symbols. They are often very helpful, and would surely help here. I do wonder if it is worth changing TEXT for debuggability. Like, say, to always be flat, no trees, and always nul terminated: (actually I'd always write two zero bytes, in case of viewing the ascii as unicode) #define TEXT_FLAGS_UNICODE (0x00000001) #define TEXT_FLAGS_CONSTANT (0x00000002) typedef struct { ??? size_t flags; ??? size_t length; ??? union { ??????? char* ascii; ??????? wchar_t* unicode; ??? } data; } *TEXT; ?? If we had merely that -- a more debugger/C-idiomatic representation for TEXT, would m3gdb's advantages decline significantly? I'd also be open to just plain typedef char* TEXT; UTF8 encoded. Text.Length is slow, and Text.Concat also slower. But ideally we'd store the length. The length could also be stored before the string. On Windows, "BSTR"s work this way. i.e. it is viable and practical and in wide use. Also, MFC/ATL CStringW/CStringA do this: typedef struct { ? wchar_t* data; } CStringW; typedef struct { ? char* data; } CStringA; and then have an entire small struct before the data. It holdes, as I recall, at least the length and a reference count. The strings are reference counted and copy-on-write. It is a nice implementation, but it isn't quite relevant here, since our TEXTs are immutable and garbage collected. The point is though, putting a struct in front of a char*/wchar_t* is viable. As long as the garbage collector doesn't get confused. Anyway, I think I'll start augmenting M3C.m3 to start writing .ll files also. We'll see how that goes. I realize it isn't the ideal path. Wrt nested variables/functions, I make a transform in the C backend. The LLVM backend will need to make a similar transform. I think the frontend should be willing/able to do this transform. It would likely help. ?- Jay ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Sat Mar 30 23:30:53 2013 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sat, 30 Mar 2013 23:30:53 +0100 Subject: [M3devel] LLVM backend? In-Reply-To: <51546065.5030709@lcwb.coop> References: <51546065.5030709@lcwb.coop> Message-ID: I've also skimmed through DWARF last year or something like that? _It is_ more complete than stabs and while (esp m3gdb) stabs are mostly hiding and guarding data from compiler through optimizer and linker to debugger, DWARF is made to enable modification of debug info as code is modified (esp while being optimized). There is no order of magnitude big enough to express its advantage over hacked-in-stabs. -- Dragi?a Duri? dragisha at m3w.org On Mar 28, 2013, at 4:23 PM, Rodney M. Bates wrote: > LLVM has a lot of already provided support for dwarf debug info, keeping it together with code, > and helping to transform it in parallel with code, when optimizations, etc., are done. > Meanwhile, dwarf itself is vastly more complete and appears to me, from superficial study, > to be capable of representing all, or certainly most, of what is needed for good Modula-3 debugging. > For these two reasons, I think LLVM plus dwarf present by far the best method to support > a nice language-specific debugging experience, while leaving massive kludges behind. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Mar 31 01:38:59 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 31 Mar 2013 00:38:59 +0000 Subject: [M3devel] LLVM backend? In-Reply-To: References: , <51546065.5030709@lcwb.coop>, Message-ID: To be clear, changing cm3cg output dwarf is, well, the support is already there, cm3cg -gdwarf or whatever. That isn't the right thing to do though. The right thing is just cm3cg -g or -g2 or whatnot, and let the target-specific default be used. For example, on Darwin it is probably "xcoff", on Cygwin it is probably unfortunately stabs. The key is that we don't describe types in the backend. Our structs are just records with size and no fields, and member/field accesses are done by adding an offset and casting. I started fixing this. It is farther along in the C backend though. The solution isn't to write any code that knows about any debug format. - Jay From: dragisha at m3w.org Date: Sat, 30 Mar 2013 23:30:53 +0100 To: rodney_bates at lcwb.coop CC: m3devel at elegosoft.com Subject: Re: [M3devel] LLVM backend? I've also skimmed through DWARF last year or something like that. _It is_ more complete than stabs and while (esp m3gdb) stabs are mostly hiding and guarding data from compiler through optimizer and linker to debugger, DWARF is made to enable modification of debug info as code is modified (esp while being optimized). There is no order of magnitude big enough to express its advantage over hacked-in-stabs. --Dragi?a Duri?dragisha at m3w.org On Mar 28, 2013, at 4:23 PM, Rodney M. Bates wrote:LLVM has a lot of already provided support for dwarf debug info, keeping it together with code, and helping to transform it in parallel with code, when optimizations, etc., are done. Meanwhile, dwarf itself is vastly more complete and appears to me, from superficial study, to be capable of representing all, or certainly most, of what is needed for good Modula-3 debugging. For these two reasons, I think LLVM plus dwarf present by far the best method to support a nice language-specific debugging experience, while leaving massive kludges behind. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Mar 31 07:10:00 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 31 Mar 2013 05:10:00 +0000 Subject: [M3devel] opaque types again Message-ID: I don't understand opaque types. I do understand the notion of fully opaque types. That are fully revealed in one step. In C this is common: window.h struct Window_t; typedef struct Window_t Window_t; Window_t* Window_Create(); void Window_Show(Window_*t); void Window_Close(Window_*t); long Window_GetHeight(Window_*t); long Window_GetWidth(Window_*t); etc. window.c struct Window_t { ... } /* reveal */ Back to Modula-3... opaque types must be OBJECTs, right? 1. What do they provide vs. more derived types? INTERFACE Animal; TYPE T = OBJECT METHODS makeNoise(); END; INTERFACE AnimalImpl; TYPE T = Animal.T OBJECT METHODS private(); END; If I had an Animal.T and wanted to call private(), wouldn't I just NARROW it to AnimalImpl.T? Is the point that it is more efficient and avoids a runtime type check? INTERFACE Animal; TYPE Public = OBJECT METHODS makeNoise(); END; TYPE T <: Public; INTERFACE AnimalImpl; REVEAL Animal.T = Animal.Public OBJECT METHODS private(); END; ? This way I can import AnimalImpl and then just call private() without a NARROW? 2. Given that the final revelation must be a linear form of all the declared subtypes, I don't understand how the offset used by any module w/o a full revelation could be anything other than zero. I'd like to fully understand this, so I can make the C backend provide maximal type information. More pointers to structs, with members/fields, fewer untyped void*/char*. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Mar 31 08:12:12 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 31 Mar 2013 06:12:12 +0000 Subject: [M3devel] opaque types again In-Reply-To: References: Message-ID: The Green Book's explanation of Rd/Wr might have finally given me the clue I needed. Private <: ROOT; Public = Private OBJECT ... The private part is a prefix of the public part. I still don't see why this is useful, vs. more derived more private types, unless it is to safe runtime casts. I'm trying to put together a small sample to exercise opaque types..and I'm getting: *** *** runtime error: *** A compile-time type is missing. *** I wish it could say which type. :( - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Sun, 31 Mar 2013 05:10:00 +0000 Subject: [M3devel] opaque types again I don't understand opaque types. I do understand the notion of fully opaque types. That are fully revealed in one step. In C this is common: window.h struct Window_t; typedef struct Window_t Window_t; Window_t* Window_Create(); void Window_Show(Window_*t); void Window_Close(Window_*t); long Window_GetHeight(Window_*t); long Window_GetWidth(Window_*t); etc. window.c struct Window_t { ... } /* reveal */ Back to Modula-3... opaque types must be OBJECTs, right? 1. What do they provide vs. more derived types? INTERFACE Animal; TYPE T = OBJECT METHODS makeNoise(); END; INTERFACE AnimalImpl; TYPE T = Animal.T OBJECT METHODS private(); END; If I had an Animal.T and wanted to call private(), wouldn't I just NARROW it to AnimalImpl.T? Is the point that it is more efficient and avoids a runtime type check? INTERFACE Animal; TYPE Public = OBJECT METHODS makeNoise(); END; TYPE T <: Public; INTERFACE AnimalImpl; REVEAL Animal.T = Animal.Public OBJECT METHODS private(); END; ? This way I can import AnimalImpl and then just call private() without a NARROW? 2. Given that the final revelation must be a linear form of all the declared subtypes, I don't understand how the offset used by any module w/o a full revelation could be anything other than zero. I'd like to fully understand this, so I can make the C backend provide maximal type information. More pointers to structs, with members/fields, fewer untyped void*/char*. Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Sun Mar 31 18:50:14 2013 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sun, 31 Mar 2013 11:50:14 -0500 Subject: [M3devel] opaque types again In-Reply-To: References: Message-ID: <51586946.6070703@lcwb.coop> On 03/31/2013 12:10 AM, Jay K wrote: > I don't understand opaque types. > It can be tricky. > > I do understand the notion of fully opaque types. That are fully revealed in one step. > In C this is common: > > > window.h > struct Window_t; > typedef struct Window_t Window_t; > Window_t* Window_Create(); > void Window_Show(Window_*t); > void Window_Close(Window_*t); > long Window_GetHeight(Window_*t); > long Window_GetWidth(Window_*t); > etc. > > window.c > struct Window_t { ... } /* reveal */ > > > Back to Modula-3... opaque types must be OBJECTs, right? > It's slightly more liberal than that. They can be any reference type, which includes object types and REF Mumble, for any Mumble. But since the subtype hierarchy has only two levels for REF types (REFANY and REF Mumble), you can only get fully opaque and fully revealed, as in the C example above. > > 1. What do they provide vs. more derived types? > > > INTERFACE Animal; > > TYPE T = OBJECT > METHODS > makeNoise(); > END; > > > INTERFACE AnimalImpl; > > TYPE T = Animal.T OBJECT > METHODS > private(); > END; > > > If I had an Animal.T and wanted to call private(), > wouldn't I just NARROW it to AnimalImpl.T? > If you allocate VAR V : Animal.T := NEW (Animal.T), the result has allocated type Animal.T, not AnimalImpl.T. So it has no method private, and even with AnimalImpl imported, trying to narrow it to AnimalImpl.T will suffer a runtime error. If you do it this way: VAR V : Animal.T := NEW (AnimalImpl.T), V still has static type Animal.T, but its runtime value is (for now, at least) an object with allocated type AnimalImpl.T, which has method private, and you can thus narrow it to AnimalImpl.T and call private. > > Is the point that it is more efficient and avoids > a runtime type check? > That's part of it. > > > INTERFACE Animal; > > TYPE Public = OBJECT > METHODS > makeNoise(); > END; > > TYPE T <: Public; > > INTERFACE AnimalImpl; > > REVEAL Animal.T = Animal.Public OBJECT > METHODS > private(); > END; > > Here, even in a context where it is not revealed, if you allocate VAR V : Animal.T := NEW (Animal.T), the allocated type has method private. Note that Animal.T here is the same type as AnimalImpl.T is in the first example. You just don't know all there is to know about what type that is. So the object still sits in the heap with all the fields and methods of the final type. If you import AnimalImpl, this gives more (static) information about the same type Animal.T instead of just a different type. So the revelation would make it statically legal to call V.private(), without needing a narrow and without a runtime check. It is statically known everywhere Animal is imported, that objects of Animal.T have all the properties of the final revealed type, even though it's not knowy what they all are. Of course, you could also do this: VAR W : Animal.Public := NEW (Animal.Public), and that would behave just like Animal.T of the first example, since those are the same type. Usually, you would probably not want to use Animal.Private in that way. It's something like a variation on the theme of an abstract supertype that you will never allocate. Sometimes I think it would help clarity if you could define a reference type as ABSTRACT, meaning it's illegal to allocate it. But that might open a can of worms in the language. Hmm, maybe I'll work on remembering to write (*ABSTRACT*) OBJECT ... I think I even did that once. > ? > This way I can import AnimalImpl and then just call private() > without a NARROW? > > Yes > > > > 2. Given that the final revelation must be a linear > form of all the declared subtypes, I don't understand > how the offset used by any module w/o a full revelation > could be anything other than zero. > Not sure this helps much, but a complication comes from the fact that you can declare a truly new subtype (not just reveal more about an existing opaque type), in a context where the opaque type is not fully revealed. IMPORT Animal (* The second version of Animal above. *) TYPE Cat = Animal.T OBJECT IsDeclawed : BOOLEAN END; The compiler will not know while separately compiling this, the offset, relative to Animal.T, where new fields of Cat will start. I have never examined the way this is implemented. I would think a typical linker's relocation or external symbol mechanism could be used to add to the offset, a component that is defined in another compilation. I think Tony understands how this is implemented. I have noted that compilations sometimes tell us they are recompiling some module because new opaque information has become available. > > I'd like to fully understand this, so I can make the C backend > provide maximal type information. More pointers to structs, with members/fields, > fewer untyped void*/char*. > If you are hoping to express Modula-3's actual static information hiding in C, I suspect that is a Quixotic quest. At the very least, you would have to replace what is really a flat struct with lots of nesting of structs for the different static visibility groups, which would just hurt readability elsewhere, in references to fields. By definition, it is a lower-level form of code here. I'd just arrange to get the full, flat struct available anywhere it is needed, and rely on the fact that the M3 front end will already have refused to pass down any references to fields that aren't statically legal in the M3 source code. There is certainly no need to get the C compiler to redundantly enforce this. > > Thanks, > - Jay > > From rodney_bates at lcwb.coop Sun Mar 31 19:40:23 2013 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sun, 31 Mar 2013 12:40:23 -0500 Subject: [M3devel] opaque types again --- A Correction In-Reply-To: <51586946.6070703@lcwb.coop> References: <51586946.6070703@lcwb.coop> Message-ID: <51587507.5020603@lcwb.coop> On 03/31/2013 11:50 AM, Rodney M. Bates wrote: > > > On 03/31/2013 12:10 AM, Jay K wrote: >> I don't understand opaque types. >> > > It can be tricky. > >> >> I do understand the notion of fully opaque types. That are fully revealed in one step. >> In C this is common: >> >> >> window.h >> struct Window_t; >> typedef struct Window_t Window_t; >> Window_t* Window_Create(); >> void Window_Show(Window_*t); >> void Window_Close(Window_*t); >> long Window_GetHeight(Window_*t); >> long Window_GetWidth(Window_*t); >> etc. >> >> window.c >> struct Window_t { ... } /* reveal */ >> >> >> Back to Modula-3... opaque types must be OBJECTs, right? >> > > It's slightly more liberal than that. They can be any reference type, which > includes object types and REF Mumble, for any Mumble. But since the subtype > hierarchy has only two levels for REF types (REFANY and REF Mumble), you can > only get fully opaque and fully revealed, as in the C example above. > >> >> 1. What do they provide vs. more derived types? >> >> >> INTERFACE Animal; >> >> TYPE T = OBJECT >> METHODS >> makeNoise(); >> END; >> >> >> INTERFACE AnimalImpl; >> >> TYPE T = Animal.T OBJECT >> METHODS >> private(); >> END; >> >> >> If I had an Animal.T and wanted to call private(), >> wouldn't I just NARROW it to AnimalImpl.T? >> > > If you allocate VAR V : Animal.T := NEW (Animal.T), the result has allocated type Animal.T, not AnimalImpl.T. > So it has no method private, and even with AnimalImpl imported, trying to narrow it to AnimalImpl.T will > suffer a runtime error. > > If you do it this way: VAR V : Animal.T := NEW (AnimalImpl.T), V still has static type Animal.T, but > its runtime value is (for now, at least) an object with allocated type AnimalImpl.T, which has method > private, and you can thus narrow it to AnimalImpl.T and call private. > >> >> Is the point that it is more efficient and avoids >> a runtime type check? >> > > That's part of it. > >> >> >> INTERFACE Animal; >> >> TYPE Public = OBJECT >> METHODS >> makeNoise(); >> END; >> >> TYPE T <: Public; >> >> INTERFACE AnimalImpl; >> >> REVEAL Animal.T = Animal.Public OBJECT >> METHODS >> private(); >> END; >> >> > > Here, even in a context where it is not revealed, if you allocate VAR V : Animal.T := NEW (Animal.T), > the allocated type has method private. Note that Animal.T here is the same type as AnimalImpl.T is > in the first example. You just don't know all there is to know about what type that is. > > So the object still sits in the heap with all the fields and methods of the final type. If you > import AnimalImpl, this gives more (static) information about the same type Animal.T instead of just > a different type. So the revelation would make it statically legal to call V.private(), without needing a > narrow and without a runtime check. It is statically known everywhere Animal is imported, that > objects of Animal.T have all the properties of the final revealed type, even though it's not knowy what > they all are. > > Of course, you could also do this: VAR W : Animal.Public := NEW (Animal.Public), and that would > behave just like Animal.T of the first example, since those are the same type. Usually, you would probably > not want to use Animal.Private in that way. It's something like a variation on the theme of an abstract Animal.Public > supertype that you will never allocate. > > Sometimes I think it would help clarity if you could define a reference type as ABSTRACT, meaning it's > illegal to allocate it. But that might open a can of worms in the language. Hmm, maybe I'll work on > remembering to write (*ABSTRACT*) OBJECT ... I think I even did that once. > >> ? >> This way I can import AnimalImpl and then just call private() >> without a NARROW? >> >> > > Yes > >> >> >> >> 2. Given that the final revelation must be a linear >> form of all the declared subtypes, I don't understand >> how the offset used by any module w/o a full revelation >> could be anything other than zero. >> > > Not sure this helps much, but a complication comes from the fact that you can declare a truly new subtype > (not just reveal more about an existing opaque type), in a context where the opaque type is not fully revealed. > > IMPORT Animal (* The second version of Animal above. *) > TYPE Cat = Animal.T OBJECT > IsDeclawed : BOOLEAN > END; > > The compiler will not know while separately compiling this, the offset, relative to Animal.T, where new fields of > Cat will start. I have never examined the way this is implemented. I would think a typical linker's relocation > or external symbol mechanism could be used to add to the offset, a component that is defined in another compilation. > I think Tony understands how this is implemented. I have noted that compilations sometimes tell us they are > recompiling some module because new opaque information has become available. > >> >> I'd like to fully understand this, so I can make the C backend >> provide maximal type information. More pointers to structs, with members/fields, >> fewer untyped void*/char*. >> > > If you are hoping to express Modula-3's actual static information hiding in C, I suspect that is a Quixotic quest. > At the very least, you would have to replace what is really a flat struct with lots of nesting of structs for > the different static visibility groups, which would just hurt readability elsewhere, in references to fields. > By definition, it is a lower-level form of code here. I'd just arrange to get the full, flat struct available > anywhere it is needed, and rely on the fact that the M3 front end will already have refused to pass down any > references to fields that aren't statically legal in the M3 source code. There is certainly no need to get > the C compiler to redundantly enforce this. > >> >> Thanks, >> - Jay >> >> > > From jay.krell at cornell.edu Sun Mar 31 21:54:28 2013 From: jay.krell at cornell.edu (Jay K) Date: Sun, 31 Mar 2013 19:54:28 +0000 Subject: [M3devel] opaque types again --- A Correction In-Reply-To: <51587507.5020603@lcwb.coop> References: , <51586946.6070703@lcwb.coop>, <51587507.5020603@lcwb.coop> Message-ID: > If you allocate VAR V : Animal.T := NEW (Animal.T), > the result has allocated type Animal.T, not AnimalImpl.T. > So it has no method private, and even with AnimalImpl > imported, trying to narrow it to AnimalImpl.T will > suffer a runtime error. Sure, "creation is special" and "plain NEW doesn't necessarily suffice". One would have INTERFACE Animal or AnimalImpl; PROCEDURE Create(): Animal.T; MODULE AnimalImpl; PROCEDURE Create(): Animal.T = BEGIN RETURN NEW(AnimalTimpl.T); END Create; > I have noted that compilations sometimes tell us they are > recompiling some module because new opaque information has become available. Me too. And it appears this is an optional optimization. It initially compiles to something less efficient but correct. Then recompiles to something more efficient. > I'd just arrange to get the full, flat struct available anywhere it is needed If I can, then yes, agreed. I don't desire to hide information from the C compiler or debugger. In fact, there are related aspects of C++ that do hide too much from the debugger (e.g. COM -- all I can see in the debugger is the vtable and function pointers, instead of the debugger introspecting the most derived type and showing all the data members...) > I have never examined the way this is implemented. The generated C for my test case is surprising, very inefficient. In Main.m3 just to get the address of a.a involves like two lookups of static type data. What was the correction? Thanks, - Jay > Date: Sun, 31 Mar 2013 12:40:23 -0500 > From: rodney_bates at lcwb.coop > To: m3devel at elegosoft.com > Subject: Re: [M3devel] opaque types again --- A Correction > > > > On 03/31/2013 11:50 AM, Rodney M. Bates wrote: > > > > > > On 03/31/2013 12:10 AM, Jay K wrote: > >> I don't understand opaque types. > >> > > > > It can be tricky. > > > >> > >> I do understand the notion of fully opaque types. That are fully revealed in one step. > >> In C this is common: > >> > >> > >> window.h > >> struct Window_t; > >> typedef struct Window_t Window_t; > >> Window_t* Window_Create(); > >> void Window_Show(Window_*t); > >> void Window_Close(Window_*t); > >> long Window_GetHeight(Window_*t); > >> long Window_GetWidth(Window_*t); > >> etc. > >> > >> window.c > >> struct Window_t { ... } /* reveal */ > >> > >> > >> Back to Modula-3... opaque types must be OBJECTs, right? > >> > > > > It's slightly more liberal than that. They can be any reference type, which > > includes object types and REF Mumble, for any Mumble. But since the subtype > > hierarchy has only two levels for REF types (REFANY and REF Mumble), you can > > only get fully opaque and fully revealed, as in the C example above. > > > >> > >> 1. What do they provide vs. more derived types? > >> > >> > >> INTERFACE Animal; > >> > >> TYPE T = OBJECT > >> METHODS > >> makeNoise(); > >> END; > >> > >> > >> INTERFACE AnimalImpl; > >> > >> TYPE T = Animal.T OBJECT > >> METHODS > >> private(); > >> END; > >> > >> > >> If I had an Animal.T and wanted to call private(), > >> wouldn't I just NARROW it to AnimalImpl.T? > >> > > > > If you allocate VAR V : Animal.T := NEW (Animal.T), the result has allocated type Animal.T, not AnimalImpl.T. > > So it has no method private, and even with AnimalImpl imported, trying to narrow it to AnimalImpl.T will > > suffer a runtime error. > > > > If you do it this way: VAR V : Animal.T := NEW (AnimalImpl.T), V still has static type Animal.T, but > > its runtime value is (for now, at least) an object with allocated type AnimalImpl.T, which has method > > private, and you can thus narrow it to AnimalImpl.T and call private. > > > >> > >> Is the point that it is more efficient and avoids > >> a runtime type check? > >> > > > > That's part of it. > > > >> > >> > >> INTERFACE Animal; > >> > >> TYPE Public = OBJECT > >> METHODS > >> makeNoise(); > >> END; > >> > >> TYPE T <: Public; > >> > >> INTERFACE AnimalImpl; > >> > >> REVEAL Animal.T = Animal.Public OBJECT > >> METHODS > >> private(); > >> END; > >> > >> > > > > Here, even in a context where it is not revealed, if you allocate VAR V : Animal.T := NEW (Animal.T), > > the allocated type has method private. Note that Animal.T here is the same type as AnimalImpl.T is > > in the first example. You just don't know all there is to know about what type that is. > > > > So the object still sits in the heap with all the fields and methods of the final type. If you > > import AnimalImpl, this gives more (static) information about the same type Animal.T instead of just > > a different type. So the revelation would make it statically legal to call V.private(), without needing a > > narrow and without a runtime check. It is statically known everywhere Animal is imported, that > > objects of Animal.T have all the properties of the final revealed type, even though it's not knowy what > > they all are. > > > > Of course, you could also do this: VAR W : Animal.Public := NEW (Animal.Public), and that would > > behave just like Animal.T of the first example, since those are the same type. Usually, you would probably > > not want to use Animal.Private in that way. It's something like a variation on the theme of an abstract > Animal.Public > > supertype that you will never allocate. > > > > Sometimes I think it would help clarity if you could define a reference type as ABSTRACT, meaning it's > > illegal to allocate it. But that might open a can of worms in the language. Hmm, maybe I'll work on > > remembering to write (*ABSTRACT*) OBJECT ... I think I even did that once. > > > >> ? > >> This way I can import AnimalImpl and then just call private() > >> without a NARROW? > >> > >> > > > > Yes > > > >> > >> > >> > >> 2. Given that the final revelation must be a linear > >> form of all the declared subtypes, I don't understand > >> how the offset used by any module w/o a full revelation > >> could be anything other than zero. > >> > > > > Not sure this helps much, but a complication comes from the fact that you can declare a truly new subtype > > (not just reveal more about an existing opaque type), in a context where the opaque type is not fully revealed. > > > > IMPORT Animal (* The second version of Animal above. *) > > TYPE Cat = Animal.T OBJECT > > IsDeclawed : BOOLEAN > > END; > > > > The compiler will not know while separately compiling this, the offset, relative to Animal.T, where new fields of > > Cat will start. I have never examined the way this is implemented. I would think a typical linker's relocation > > or external symbol mechanism could be used to add to the offset, a component that is defined in another compilation. > > I think Tony understands how this is implemented. I have noted that compilations sometimes tell us they are > > recompiling some module because new opaque information has become available. > > > >> > >> I'd like to fully understand this, so I can make the C backend > >> provide maximal type information. More pointers to structs, with members/fields, > >> fewer untyped void*/char*. > >> > > > > If you are hoping to express Modula-3's actual static information hiding in C, I suspect that is a Quixotic quest. > > At the very least, you would have to replace what is really a flat struct with lots of nesting of structs for > > the different static visibility groups, which would just hurt readability elsewhere, in references to fields. > > By definition, it is a lower-level form of code here. I'd just arrange to get the full, flat struct available > > anywhere it is needed, and rely on the fact that the M3 front end will already have refused to pass down any > > references to fields that aren't statically legal in the M3 source code. There is certainly no need to get > > the C compiler to redundantly enforce this. > > > >> > >> Thanks, > >> - Jay > >> > >> > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: