November 25, 2020, 06:16:20 AM

Author Topic: [bb] Code position identity by Yasha [ 1+ years ago ]  (Read 701 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] Code position identity by Yasha [ 1+ years ago ]
« on: June 29, 2017, 12:28:39 AM »
Title : Code position identity
Author : Yasha
Posted : 1+ years ago

Description : This tiny GNU C function returns the address of its own return instruction. There are a few reasons why you might want this in C programming, but one particularly nice consequence is that it returns a unique address (i.e. integer, in B3D terms) for each place it's called in the code, without you needing to do any extra maintenance, so you can use it to e.g. ensure you do things only once, or to identify particular loops or whatever. Advanced users will think of a lot of uses for this.

The functionality itself is entirely provided by one GCC extension, so it has to be GNU C, not ISO C. The C code below is literally the entire thing.

You can also <a href="https://sites.google.com/site/nangdongseng/downloads/CodePos.zip?attredirects=0&d=1" target="_blank">download it[/url] if you don't have GCC installed.
Example:

Code: [Select]
Local i : For i = 0 To 2
Print JIT_ReturnAddress()
Print JIT_ReturnAddress()
Print Elsewhere()
Print ""
Next

WaitKey
End

Function Elsewhere()
Return JIT_ReturnAddress()
End Function

The three extra functions JIT_ReturnAddress1, ..2, ..3 do the same, but for their caller, caller's caller, and caller's caller's caller respectively. This means that you can call JIT_ReturnAddress1 from a library function and get a different identity for each place your library function was called, which is even more useful as you can hide the mechanism behind your API.

It isn't possible to provide a dynamic version, because the compiler-builtin only accepts constant integers and is inlined to the relevant assembly. You shouldn't need more than three call levels (arguably, you shouldn't need more than one, but since we're here...), and anyway you should never be using this sort of thing in a dynamic way as it's totally unsafe. [/i]

Code :
Code: BlitzBasic
  1. ; /* CodePosition.decls:
  2.  
  3. .lib "CodePosition.dll"
  4.  
  5. ; Return the current code position (a unique ID for each call point)
  6. JIT_ReturnAddress%() : "JIT_ReturnAddress@0"
  7.  
  8. ;Return the current code's caller's position, plus respective levels
  9. JIT_ReturnAddress1%() : "JIT_ReturnAddress1@0"
  10. JIT_ReturnAddress2%() : "JIT_ReturnAddress2@0"
  11. JIT_ReturnAddress3%() : "JIT_ReturnAddress3@0"
  12.  
  13. ; */
  14.  
  15.  
  16. // Requires GCC extensions
  17. #ifndef __GNUC__
  18. #  error GCC with builtins required for this to work
  19. #endif
  20. void * __stdcall JIT_ReturnAddress(void) {
  21.         return __builtin_return_address(0);
  22. }
  23.  
  24. void * __stdcall JIT_ReturnAddress1(void) {
  25.         return __builtin_return_address(1);
  26. }
  27.  
  28. void * __stdcall JIT_ReturnAddress2(void) {
  29.         return __builtin_return_address(2);
  30. }
  31.  
  32. void * __stdcall JIT_ReturnAddress3(void) {
  33.         return __builtin_return_address(3);
  34. }


Comments : none...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal