home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / std / cplus / 1814 < prev    next >
Encoding:
Internet Message Format  |  1992-12-16  |  3.4 KB

  1. Path: sparky!uunet!zaphod.mps.ohio-state.edu!cs.utexas.edu!sun-barr!news2me.EBay.Sun.COM!exodus.Eng.Sun.COM!rbbb.Eng.Sun.COM!chased
  2. From: chased@rbbb.Eng.Sun.COM (David Chase)
  3. Newsgroups: comp.std.c++
  4. Subject: C++ nested functions and C interoperability
  5. Date: 16 Dec 1992 23:35:27 GMT
  6. Organization: Sun
  7. Lines: 76
  8. Message-ID: <livf9vINN88l@exodus.Eng.Sun.COM>
  9. References: <24392@alice.att.com> <1992Dec12.162211.5076@ucc.su.OZ.AU> <24400@alice.att.com>
  10. NNTP-Posting-Host: rbbb
  11. Summary: It is elementary.  Next objection, please.
  12.  
  13.  
  14. >In article maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:
  15.  
  16. >> Do you personally favour nested functions?
  17. >> If not, why not?
  18.  
  19. In article <24400@alice.att.com> ark@alice.UUCP () writes:
  20. >In general, yes.  For C++, I'm not sure.
  21.  
  22. >The main argument against it is that C doesn't have them, which means
  23. >that having them in C++ would make C interoperability more difficult.
  24. >It would also be more difficult to interface C++ programs with
  25. >low-level assembly-language things like on-board controllers.  I don't
  26. >care about that personally, but I know that other people do.
  27.  
  28. C interoperability is elementary, and already done before.  This
  29. should also be transparent to other assembly languages like those used
  30. in on-board controllers.  (Besides which, people in those situations
  31. have been known to live with restrictions before.)
  32.  
  33. Implementation method #1: generate code into your stack frame to load
  34. up the lexical pointer and branch to where the "real" function is.
  35. For a 68k, this means pushing an additional parameter.  For a SPARC,
  36. this means (for example) loading a value into %g2.  The assembly
  37. language for this looks something like:
  38.  
  39.   sethi func>>10,%g1
  40.   sethi addr>>10,%g2
  41.   jmp   %g1+func&0x3ff
  42.   add   %g2,addr&0x3ff,%g2
  43.  
  44. Of course, when you generate this, you had better do the appropriate
  45. cache flushes.  "func" is entered with %g2 containing a pointer to
  46. whatever representation of the parent frame you find most suitable.
  47. (I got this trick from Thomas Breuel [sp?], and used it in an early
  48. Modula-3 implementation on the 68k.  It worked just fine -- Modula-3
  49. functions looked just like C functions.)
  50.  
  51. Implementation method #2: generate about 512 pieces of code of the
  52. form (SPARC-specific, for concreteness)
  53.  
  54.   sethi abslocX>>10,%g2
  55.   ld    [%g2+abslocX&0x3ff],%g1
  56.   jmp    %g1
  57.   add   %g2,abslocX&0x3ff,%g2
  58.  
  59. and about 512 8-byte chunks of data.
  60.  
  61.   (In this case, "func" is entered with a ptr to a thunk_data, and
  62.    not a direct ptr to the parent frame.)
  63.  
  64. where you have
  65.  
  66.  struct thunk_code {unsigned int sethi, ld, jmp, add; };
  67.  struct thunk_data {unsigned int function, parent_frame; };
  68.  struct thunk_code_page { struct thunk_code code [512]; };
  69.  struct thunk_data_page { struct thunk_data data [512]; };
  70.  
  71. Given a code page, code[i] has abslocX equal to data+i in a
  72. corresponding data page.  The code page is initialized once, flushed,
  73. mmap'd no-write, and nested functions are created by allocating them
  74. out of this pool and filling in the appropriate entries in the data
  75. page.  If you run out, create a new pair of pages.  Note that
  76. deallocating a thunk is now necessary (much like running destructors)
  77. but because exceptions in C++ are synchronous and interaction with
  78. longjmp is undefined, everything will work (ho, ho, ho).  At worst,
  79. longjmp creates a storage leak that can probably be dealt with by
  80. putting a little bit more information into a thunk_data.
  81.  
  82. So, given that we can implement nested functions and maintain
  83. compatibility with C, why not?
  84.  
  85. David Chase
  86. Sun
  87.  
  88.  
  89.