il2cpp-codegen-common.cpp 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "il2cpp-config.h"
  2. #include "gc/GarbageCollector.h"
  3. #if IL2CPP_ENABLE_WRITE_BARRIERS
  4. void Il2CppCodeGenWriteBarrier(void** targetAddress, void* object)
  5. {
  6. il2cpp::gc::GarbageCollector::SetWriteBarrier(targetAddress);
  7. }
  8. #endif
  9. #if !RUNTIME_TINY
  10. #include "utils/Runtime.h"
  11. #include "vm/Class.h"
  12. #include "vm/Field.h"
  13. #include "vm/Type.h"
  14. // This function exists to help with generation of callstacks for exceptions
  15. // on iOS and MacOS x64 with clang 6.0 (newer versions of clang don't have this
  16. // problem on x64). There we call the backtrace function, which does not play nicely
  17. // with NORETURN, since the compiler eliminates the method prologue code setting up
  18. // the address of the return frame (which makes sense). So on iOS we need to make
  19. // the NORETURN define do nothing, then we use this dummy method which has the
  20. // attribute for clang on iOS defined to prevent clang compiler errors for
  21. // method that end by throwing a managed exception.
  22. REAL_NORETURN IL2CPP_NO_INLINE void il2cpp_codegen_no_return()
  23. {
  24. IL2CPP_UNREACHABLE;
  25. }
  26. REAL_NORETURN void il2cpp_codegen_abort()
  27. {
  28. il2cpp::utils::Runtime::Abort();
  29. il2cpp_codegen_no_return();
  30. }
  31. #if IL2CPP_ENABLE_WRITE_BARRIERS
  32. void Il2CppCodeGenWriteBarrierForType(const Il2CppType* type, void** targetAddress, void* object)
  33. {
  34. #if IL2CPP_ENABLE_STRICT_WRITE_BARRIERS
  35. if (il2cpp::vm::Type::IsPointerType(type))
  36. return;
  37. if (il2cpp::vm::Type::IsStruct(type))
  38. {
  39. Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type);
  40. FieldInfo* field;
  41. void* iter = NULL;
  42. while ((field = il2cpp::vm::Class::GetFields(klass, &iter)))
  43. {
  44. if (il2cpp::vm::Field::GetFlags(field) & FIELD_ATTRIBUTE_STATIC)
  45. continue;
  46. void* fieldTargetAddress = il2cpp::vm::Field::GetInstanceFieldDataPointer((void*)targetAddress, field);
  47. Il2CppCodeGenWriteBarrierForType(field->type, (void**)fieldTargetAddress, NULL);
  48. }
  49. }
  50. else
  51. {
  52. il2cpp::gc::GarbageCollector::SetWriteBarrier(targetAddress);
  53. }
  54. #else
  55. il2cpp::gc::GarbageCollector::SetWriteBarrier(targetAddress);
  56. #endif
  57. }
  58. void Il2CppCodeGenWriteBarrierForClass(Il2CppClass* klass, void** targetAddress, void* object)
  59. {
  60. #if IL2CPP_ENABLE_STRICT_WRITE_BARRIERS
  61. Il2CppCodeGenWriteBarrierForType(il2cpp::vm::Class::GetType(klass), targetAddress, object);
  62. #else
  63. il2cpp::gc::GarbageCollector::SetWriteBarrier(targetAddress);
  64. #endif
  65. }
  66. #endif // IL2CPP_ENABLE_WRITE_BARRIERS
  67. #endif // !RUNTIME_TINY
  68. #if IL2CPP_TINY
  69. #include <cstdio>
  70. int il2cpp_codegen_double_to_string(double value, uint8_t* format, uint8_t* buffer, int bufferLength)
  71. {
  72. // return number of characters written to the buffer. if the return value greater than bufferLength
  73. // means the number of characters would be written to the buffer if there is enough space
  74. return snprintf(reinterpret_cast<char*>(buffer), bufferLength, reinterpret_cast<char*>(format), value);
  75. }
  76. #endif