aot_emit_exception.c 4.6 KB

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