bcc icon indicating copy to clipboard operation
bcc copied to clipboard

Reflection wrapper generation

Open HurryStarfish opened this issue 5 years ago • 28 comments

A rather technical question regarding the bcc internals: Now that #411 was solved, I wanted to improve the C generation for reflection wrappers to prevent name collisions... but I got stuck and am not sure how to do this.

With the reflection changes I commited to the bcc_reflect branch, I added "reflection wrappers": for every function (or method) visible to reflection, an additional wrapper function is generated. This is so the functions can be called via BRL.Reflection.TFunction.Invoke/BRL.Reflection.TMethod.Invoke: the reflection module calls the wrapper (which has a known signature) and the wrapper then forwards the call to the "original" function. Currently, the code generation for these reflection wrappers happens at the end of TCTranslator.EmitFuncDecl and TCTranslator.EmitClassDeclNew. The name of the wrapper is the munged identifier of the original function, with "_ReflectionWrapper" appended to it. Unfortunately this means that the wrapper can collide with BlitzMax functions whose name ends in "_ReflectionWrapper". I'd now like to "mung" the name of the wrapper to prevent these collisions. My initial idea was to create a TFuncDecl for the wrapper along with that of the original function. I added a Field reflectionWrapperDecl:TFuncDecl to TFuncDecl, and called reflectionWrapperDecl.Semant inside TFuncDecl.OnSemant. But this causes the wrapper to get emitted alongside the original function, which creates two problems:

  1. the wrapper is empty because it doesn't contain any BlitzMax statements - it's supposed to contain specific C code
  2. the wrapper gets emitted before the original function (because it finished semanting first) - it's supposed to be emitted after the original function because it calls it

How do I get around this?

  • I could leave the reflection wrapper unsemanted, but that seems dirty, and I don't know whether that will create other problems
  • I could create, mung and emit the TFuncDecl for the wrapper "at the last moment", during TCTranslator.EmitFuncDecl/TCTranslator.EmitClassDeclNew, but creating and processing new decls during the C code generation stage also seems dirty
  • if there is some way to create, semant and "mung" a TFuncDecl without it being emitted, I could do that (but I currently don't know how)

What do you think would be the best approach here?

HurryStarfish avatar Mar 21 '19 15:03 HurryStarfish