|
|
@@ -4,6 +4,7 @@
|
|
|
*/
|
|
|
|
|
|
#include "aot_emit_variable.h"
|
|
|
+#include "aot_emit_exception.h"
|
|
|
#include "../aot/aot_runtime.h"
|
|
|
|
|
|
#define CHECK_LOCAL(idx) do { \
|
|
|
@@ -107,7 +108,7 @@ fail:
|
|
|
|
|
|
static bool
|
|
|
compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|
|
- uint32 global_idx, bool is_set)
|
|
|
+ uint32 global_idx, bool is_set, bool is_aux_stack)
|
|
|
{
|
|
|
AOTCompData *comp_data = comp_ctx->comp_data;
|
|
|
uint32 import_global_count = comp_data->import_global_count;
|
|
|
@@ -179,6 +180,61 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|
|
}
|
|
|
else {
|
|
|
POP(global, global_type);
|
|
|
+
|
|
|
+ if (is_aux_stack && comp_ctx->enable_aux_stack_check) {
|
|
|
+ LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder);
|
|
|
+ LLVMBasicBlockRef check_overflow_succ, check_underflow_succ;
|
|
|
+ LLVMValueRef cmp;
|
|
|
+
|
|
|
+ /* Add basic blocks */
|
|
|
+ if (!(check_overflow_succ =
|
|
|
+ LLVMAppendBasicBlockInContext(comp_ctx->context,
|
|
|
+ func_ctx->func,
|
|
|
+ "check_overflow_succ"))) {
|
|
|
+ aot_set_last_error("llvm add basic block failed.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ LLVMMoveBasicBlockAfter(check_overflow_succ, block_curr);
|
|
|
+
|
|
|
+ if (!(check_underflow_succ =
|
|
|
+ LLVMAppendBasicBlockInContext(comp_ctx->context,
|
|
|
+ func_ctx->func,
|
|
|
+ "check_underflow_succ"))) {
|
|
|
+ aot_set_last_error("llvm add basic block failed.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ LLVMMoveBasicBlockAfter(check_underflow_succ, check_overflow_succ);
|
|
|
+
|
|
|
+ /* Check aux stack overflow */
|
|
|
+ if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULE,
|
|
|
+ global, func_ctx->aux_stack_bound,
|
|
|
+ "cmp"))) {
|
|
|
+ aot_set_last_error("llvm build icmp failed.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!aot_emit_exception(comp_ctx, func_ctx,
|
|
|
+ EXCE_AUX_STACK_OVERFLOW,
|
|
|
+ true, cmp, check_overflow_succ)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Check aux stack underflow */
|
|
|
+ LLVMPositionBuilderAtEnd(comp_ctx->builder, check_overflow_succ);
|
|
|
+ if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT,
|
|
|
+ global, func_ctx->aux_stack_bottom,
|
|
|
+ "cmp"))) {
|
|
|
+ aot_set_last_error("llvm build icmp failed.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!aot_emit_exception(comp_ctx, func_ctx,
|
|
|
+ EXCE_AUX_STACK_UNDERFLOW,
|
|
|
+ true, cmp, check_underflow_succ)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ LLVMPositionBuilderAtEnd(comp_ctx->builder, check_underflow_succ);
|
|
|
+ }
|
|
|
+
|
|
|
if (!(res = LLVMBuildStore(comp_ctx->builder,
|
|
|
global, global_ptr))) {
|
|
|
aot_set_last_error("llvm build store failed.");
|
|
|
@@ -197,13 +253,13 @@ bool
|
|
|
aot_compile_op_get_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|
|
uint32 global_idx)
|
|
|
{
|
|
|
- return compile_global(comp_ctx, func_ctx, global_idx, false);
|
|
|
+ return compile_global(comp_ctx, func_ctx, global_idx, false, false);
|
|
|
}
|
|
|
|
|
|
bool
|
|
|
aot_compile_op_set_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|
|
- uint32 global_idx)
|
|
|
+ uint32 global_idx, bool is_aux_stack)
|
|
|
{
|
|
|
- return compile_global(comp_ctx, func_ctx, global_idx, true);
|
|
|
+ return compile_global(comp_ctx, func_ctx, global_idx, true, is_aux_stack);
|
|
|
}
|
|
|
|