aot_emit_exception.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "aot_emit_exception.h"
  6. #include "../aot/aot_runtime.h"
  7. bool
  8. aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  9. int32 exception_id, bool is_cond_br, LLVMValueRef cond_br_if,
  10. LLVMBasicBlockRef cond_br_else_block)
  11. {
  12. LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder);
  13. LLVMValueRef exce_id = I32_CONST((uint32)exception_id), func_const, func;
  14. LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
  15. LLVMValueRef param_values[2];
  16. bh_assert(exception_id >= 0 && exception_id < EXCE_NUM);
  17. CHECK_LLVM_CONST(exce_id);
  18. /* Create got_exception block if needed */
  19. if (!func_ctx->got_exception_block) {
  20. if (!(func_ctx->got_exception_block = LLVMAppendBasicBlockInContext(
  21. comp_ctx->context, func_ctx->func, "got_exception"))) {
  22. aot_set_last_error("add LLVM basic block failed.");
  23. return false;
  24. }
  25. LLVMPositionBuilderAtEnd(comp_ctx->builder,
  26. func_ctx->got_exception_block);
  27. /* Create exection id phi */
  28. if (!(func_ctx->exception_id_phi = LLVMBuildPhi(
  29. comp_ctx->builder, I32_TYPE, "exception_id_phi"))) {
  30. aot_set_last_error("llvm build phi failed.");
  31. return false;
  32. }
  33. /* Call aot_set_exception_with_id() to throw exception */
  34. param_types[0] = INT8_PTR_TYPE;
  35. param_types[1] = I32_TYPE;
  36. ret_type = VOID_TYPE;
  37. /* Create function type */
  38. if (!(func_type = LLVMFunctionType(ret_type, param_types, 2, false))) {
  39. aot_set_last_error("create LLVM function type failed.");
  40. return false;
  41. }
  42. if (comp_ctx->is_jit_mode) {
  43. /* Create function type */
  44. if (!(func_ptr_type = LLVMPointerType(func_type, 0))) {
  45. aot_set_last_error("create LLVM function type failed.");
  46. return false;
  47. }
  48. /* Create LLVM function with const function pointer */
  49. if (!(func_const =
  50. I64_CONST((uint64)(uintptr_t)aot_set_exception_with_id))
  51. || !(func = LLVMConstIntToPtr(func_const, func_ptr_type))) {
  52. aot_set_last_error("create LLVM value failed.");
  53. return false;
  54. }
  55. }
  56. else if (comp_ctx->is_indirect_mode) {
  57. int32 func_index;
  58. if (!(func_ptr_type = LLVMPointerType(func_type, 0))) {
  59. aot_set_last_error("create LLVM function type failed.");
  60. return false;
  61. }
  62. func_index = aot_get_native_symbol_index(
  63. comp_ctx, "aot_set_exception_with_id");
  64. if (func_index < 0) {
  65. return false;
  66. }
  67. if (!(func =
  68. aot_get_func_from_table(comp_ctx, func_ctx->native_symbol,
  69. func_ptr_type, func_index))) {
  70. return false;
  71. }
  72. }
  73. else {
  74. /* Create LLVM function with external function pointer */
  75. if (!(func = LLVMGetNamedFunction(func_ctx->module,
  76. "aot_set_exception_with_id"))
  77. && !(func = LLVMAddFunction(func_ctx->module,
  78. "aot_set_exception_with_id",
  79. func_type))) {
  80. aot_set_last_error("add LLVM function failed.");
  81. return false;
  82. }
  83. }
  84. /* Call the aot_set_exception_with_id() function */
  85. param_values[0] = func_ctx->aot_inst;
  86. param_values[1] = func_ctx->exception_id_phi;
  87. if (!LLVMBuildCall(comp_ctx->builder, func, param_values, 2, "")) {
  88. aot_set_last_error("llvm build call failed.");
  89. return false;
  90. }
  91. /* Create return IR */
  92. AOTFuncType *aot_func_type = func_ctx->aot_func->func_type;
  93. if (!aot_build_zero_function_ret(comp_ctx, func_ctx, aot_func_type)) {
  94. return false;
  95. }
  96. /* Resume the builder position */
  97. LLVMPositionBuilderAtEnd(comp_ctx->builder, block_curr);
  98. }
  99. /* Add phi incoming value to got_exception block */
  100. LLVMAddIncoming(func_ctx->exception_id_phi, &exce_id, &block_curr, 1);
  101. if (!is_cond_br) {
  102. /* not condition br, create br IR */
  103. if (!LLVMBuildBr(comp_ctx->builder, func_ctx->got_exception_block)) {
  104. aot_set_last_error("llvm build br failed.");
  105. return false;
  106. }
  107. }
  108. else {
  109. /* Create condition br */
  110. if (!LLVMBuildCondBr(comp_ctx->builder, cond_br_if,
  111. func_ctx->got_exception_block,
  112. cond_br_else_block)) {
  113. aot_set_last_error("llvm build cond br failed.");
  114. return false;
  115. }
  116. /* Start to translate the else block */
  117. LLVMPositionBuilderAtEnd(comp_ctx->builder, cond_br_else_block);
  118. }
  119. return true;
  120. fail:
  121. return false;
  122. }