ソースを参照

Add check for code section size, fix interp float operations (#1480)

And enable classic interpreter instead fast interpreter when llvm jit is enabled,
so as to fix the issue that llvm jit cannot handle opcode drop_64/select_64.
Wenyong Huang 3 年 前
コミット
ab929c20a3

+ 1 - 1
build-scripts/runtime_lib.cmake

@@ -52,7 +52,7 @@ endif ()
 ################ optional according to settings ################
 if (WAMR_BUILD_INTERP EQUAL 1 OR WAMR_BUILD_JIT EQUAL 1
     OR WAMR_BUILD_FAST_JIT EQUAL 1)
-    if (WAMR_BUILD_FAST_JIT EQUAL 1)
+    if (WAMR_BUILD_FAST_JIT EQUAL 1 OR WAMR_BUILD_JIT EQUAL 1)
         set (WAMR_BUILD_FAST_INTERP 0)
     endif ()
     include (${IWASM_DIR}/interpreter/iwasm_interp.cmake)

+ 32 - 8
core/iwasm/interpreter/wasm_interp_classic.c

@@ -198,6 +198,30 @@ popcount64(uint64 u)
     return ret;
 }
 
+static float
+local_copysignf(float x, float y)
+{
+    union {
+        float f;
+        uint32_t i;
+    } ux = { x }, uy = { y };
+    ux.i &= 0x7fffffff;
+    ux.i |= uy.i & 0x80000000;
+    return ux.f;
+}
+
+static double
+local_copysign(double x, double y)
+{
+    union {
+        double f;
+        uint64_t i;
+    } ux = { x }, uy = { y };
+    ux.i &= -1ULL / 2;
+    ux.i |= uy.i & 1ULL << 63;
+    return ux.f;
+}
+
 static uint64
 read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
 {
@@ -2580,7 +2604,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
             /* numberic instructions of f32 */
             HANDLE_OP(WASM_OP_F32_ABS)
             {
-                DEF_OP_MATH(float32, F32, fabs);
+                DEF_OP_MATH(float32, F32, fabsf);
                 HANDLE_OP_END();
             }
 
@@ -2597,31 +2621,31 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 
             HANDLE_OP(WASM_OP_F32_CEIL)
             {
-                DEF_OP_MATH(float32, F32, ceil);
+                DEF_OP_MATH(float32, F32, ceilf);
                 HANDLE_OP_END();
             }
 
             HANDLE_OP(WASM_OP_F32_FLOOR)
             {
-                DEF_OP_MATH(float32, F32, floor);
+                DEF_OP_MATH(float32, F32, floorf);
                 HANDLE_OP_END();
             }
 
             HANDLE_OP(WASM_OP_F32_TRUNC)
             {
-                DEF_OP_MATH(float32, F32, trunc);
+                DEF_OP_MATH(float32, F32, truncf);
                 HANDLE_OP_END();
             }
 
             HANDLE_OP(WASM_OP_F32_NEAREST)
             {
-                DEF_OP_MATH(float32, F32, rint);
+                DEF_OP_MATH(float32, F32, rintf);
                 HANDLE_OP_END();
             }
 
             HANDLE_OP(WASM_OP_F32_SQRT)
             {
-                DEF_OP_MATH(float32, F32, sqrt);
+                DEF_OP_MATH(float32, F32, sqrtf);
                 HANDLE_OP_END();
             }
 
@@ -2687,7 +2711,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 
                 b = POP_F32();
                 a = POP_F32();
-                PUSH_F32(signbit(b) ? -fabs(a) : fabs(a));
+                PUSH_F32(local_copysignf(a, b));
                 HANDLE_OP_END();
             }
 
@@ -2801,7 +2825,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 
                 b = POP_F64();
                 a = POP_F64();
-                PUSH_F64(signbit(b) ? -fabs(a) : fabs(a));
+                PUSH_F64(local_copysign(a, b));
                 HANDLE_OP_END();
             }
 

+ 32 - 9
core/iwasm/interpreter/wasm_interp_fast.c

@@ -189,6 +189,30 @@ popcount64(uint64 u)
     return ret;
 }
 
+static float
+local_copysignf(float x, float y)
+{
+    union {
+        float f;
+        uint32_t i;
+    } ux = { x }, uy = { y };
+    ux.i &= 0x7fffffff;
+    ux.i |= uy.i & 0x80000000;
+    return ux.f;
+}
+
+static double
+local_copysign(double x, double y)
+{
+    union {
+        double f;
+        uint64_t i;
+    } ux = { x }, uy = { y };
+    ux.i &= -1ULL / 2;
+    ux.i |= uy.i & 1ULL << 63;
+    return ux.f;
+}
+
 #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
 #define LOAD_U32_WITH_2U16S(addr) (*(uint32 *)(addr))
 #define LOAD_PTR(addr) (*(void **)(addr))
@@ -2415,7 +2439,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
             /* numberic instructions of f32 */
             HANDLE_OP(WASM_OP_F32_ABS)
             {
-                DEF_OP_MATH(float32, F32, fabs);
+                DEF_OP_MATH(float32, F32, fabsf);
                 HANDLE_OP_END();
             }
 
@@ -2433,31 +2457,31 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 
             HANDLE_OP(WASM_OP_F32_CEIL)
             {
-                DEF_OP_MATH(float32, F32, ceil);
+                DEF_OP_MATH(float32, F32, ceilf);
                 HANDLE_OP_END();
             }
 
             HANDLE_OP(WASM_OP_F32_FLOOR)
             {
-                DEF_OP_MATH(float32, F32, floor);
+                DEF_OP_MATH(float32, F32, floorf);
                 HANDLE_OP_END();
             }
 
             HANDLE_OP(WASM_OP_F32_TRUNC)
             {
-                DEF_OP_MATH(float32, F32, trunc);
+                DEF_OP_MATH(float32, F32, truncf);
                 HANDLE_OP_END();
             }
 
             HANDLE_OP(WASM_OP_F32_NEAREST)
             {
-                DEF_OP_MATH(float32, F32, rint);
+                DEF_OP_MATH(float32, F32, rintf);
                 HANDLE_OP_END();
             }
 
             HANDLE_OP(WASM_OP_F32_SQRT)
             {
-                DEF_OP_MATH(float32, F32, sqrt);
+                DEF_OP_MATH(float32, F32, sqrtf);
                 HANDLE_OP_END();
             }
 
@@ -2525,8 +2549,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 
                 b = *(float32 *)(frame_lp + GET_OFFSET());
                 a = *(float32 *)(frame_lp + GET_OFFSET());
-                *(float32 *)(frame_lp + GET_OFFSET()) =
-                    (float32)(signbit(b) ? -fabs(a) : fabs(a));
+                *(float32 *)(frame_lp + GET_OFFSET()) = local_copysignf(a, b);
                 HANDLE_OP_END();
             }
 
@@ -2642,7 +2665,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 
                 b = POP_F64();
                 a = POP_F64();
-                PUSH_F64(signbit(b) ? -fabs(a) : fabs(a));
+                PUSH_F64(local_copysign(a, b));
                 HANDLE_OP_END();
             }
 

+ 9 - 2
core/iwasm/interpreter/wasm_loader.c

@@ -3278,6 +3278,13 @@ load_from_sections(WASMModule *module, WASMSection *sections,
                                           error_buf_size)) {
             return false;
         }
+
+        if (i == module->function_count - 1
+            && func->code + func->code_size != buf_code_end) {
+            set_error_buf(error_buf, error_buf_size,
+                          "code section size mismatch");
+            return false;
+        }
     }
 
     if (!module->possible_memory_grow) {
@@ -7344,7 +7351,7 @@ re_scan:
                     else if (is_64bit_type(*(loader_ctx->frame_ref - 1))) {
                         loader_ctx->frame_ref -= 2;
                         loader_ctx->stack_cell_num -= 2;
-#if (WASM_ENABLE_FAST_INTERP == 0) || (WASM_ENABLE_JIT != 0)
+#if WASM_ENABLE_FAST_INTERP == 0
                         *(p - 1) = WASM_OP_DROP_64;
 #endif
 #if WASM_ENABLE_FAST_INTERP != 0
@@ -7406,7 +7413,7 @@ re_scan:
                             break;
                         case REF_I64_2:
                         case REF_F64_2:
-#if (WASM_ENABLE_FAST_INTERP == 0) || (WASM_ENABLE_JIT != 0)
+#if WASM_ENABLE_FAST_INTERP == 0
                             *(p - 1) = WASM_OP_SELECT_64;
 #endif
 #if WASM_ENABLE_FAST_INTERP != 0

+ 6 - 2
core/iwasm/interpreter/wasm_mini_loader.c

@@ -2115,6 +2115,10 @@ load_from_sections(WASMModule *module, WASMSection *sections,
                                           error_buf_size)) {
             return false;
         }
+
+        if (i == module->function_count - 1) {
+            bh_assert(func->code + func->code_size == buf_code_end);
+        }
     }
 
     if (!module->possible_memory_grow) {
@@ -5545,7 +5549,7 @@ re_scan:
                     else if (is_64bit_type(*(loader_ctx->frame_ref - 1))) {
                         loader_ctx->frame_ref -= 2;
                         loader_ctx->stack_cell_num -= 2;
-#if (WASM_ENABLE_FAST_INTERP == 0) || (WASM_ENABLE_JIT != 0)
+#if WASM_ENABLE_FAST_INTERP == 0
                         *(p - 1) = WASM_OP_DROP_64;
 #endif
 #if WASM_ENABLE_FAST_INTERP != 0
@@ -5591,7 +5595,7 @@ re_scan:
                             break;
                         case REF_I64_2:
                         case REF_F64_2:
-#if (WASM_ENABLE_FAST_INTERP == 0) || (WASM_ENABLE_JIT != 0)
+#if WASM_ENABLE_FAST_INTERP == 0
                             *(p - 1) = WASM_OP_SELECT_64;
 #endif
 #if WASM_ENABLE_FAST_INTERP != 0

+ 2 - 0
core/shared/platform/alios/platform_internal.h

@@ -52,11 +52,13 @@ double fmax(double x, double y);
 double rint(double x);
 double fabs(double x);
 double trunc(double x);
+float sqrtf(float x);
 float floorf(float x);
 float ceilf(float x);
 float fminf(float x, float y);
 float fmaxf(float x, float y);
 float rintf(float x);
+float fabsf(float x);
 float truncf(float x);
 int signbit(double x);
 int isnan(double x);

+ 89 - 0
core/shared/platform/common/math/math.c

@@ -622,6 +622,74 @@ freebsd_atan2(double y, double x)
     }
 }
 
+static float
+freebsd_sqrtf(float x)
+{
+    float z;
+    int32_t sign = (int)0x80000000;
+    int32_t ix, s, q, m, t, i;
+    u_int32_t r;
+
+    GET_FLOAT_WORD(ix, x);
+
+    /* take care of Inf and NaN */
+    if ((ix & 0x7f800000) == 0x7f800000) {
+        return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
+                     sqrt(-inf)=sNaN */
+    }
+    /* take care of zero */
+    if (ix <= 0) {
+        if ((ix & (~sign)) == 0)
+            return x; /* sqrt(+-0) = +-0 */
+        else if (ix < 0)
+            return (x - x) / (x - x); /* sqrt(-ve) = sNaN */
+    }
+    /* normalize x */
+    m = (ix >> 23);
+    if (m == 0) { /* subnormal x */
+        for (i = 0; (ix & 0x00800000) == 0; i++)
+            ix <<= 1;
+        m -= i - 1;
+    }
+    m -= 127; /* unbias exponent */
+    ix = (ix & 0x007fffff) | 0x00800000;
+    if (m & 1) /* odd m, double x to make it even */
+        ix += ix;
+    m >>= 1; /* m = [m/2] */
+
+    /* generate sqrt(x) bit by bit */
+    ix += ix;
+    q = s = 0;      /* q = sqrt(x) */
+    r = 0x01000000; /* r = moving bit from right to left */
+
+    while (r != 0) {
+        t = s + r;
+        if (t <= ix) {
+            s = t + r;
+            ix -= t;
+            q += r;
+        }
+        ix += ix;
+        r >>= 1;
+    }
+
+    /* use floating add to find out rounding direction */
+    if (ix != 0) {
+        z = one - tiny; /* trigger inexact flag */
+        if (z >= one) {
+            z = one + tiny;
+            if (z > one)
+                q += 2;
+            else
+                q += (q & 1);
+        }
+    }
+    ix = (q >> 1) + 0x3f000000;
+    ix += (m << 23);
+    SET_FLOAT_WORD(z, ix);
+    return z;
+}
+
 static double
 freebsd_sqrt(double x) /* wrapper sqrt */
 {
@@ -935,6 +1003,15 @@ freebsd_isnan(double d)
     }
 }
 
+static float
+freebsd_fabsf(float x)
+{
+    u_int32_t ix;
+    GET_FLOAT_WORD(ix, x);
+    SET_FLOAT_WORD(x, ix & 0x7fffffff);
+    return x;
+}
+
 static double
 freebsd_fabs(double x)
 {
@@ -1537,6 +1614,12 @@ signbit(double x)
     return ((__HI(x) & 0x80000000) >> 31);
 }
 
+float
+fabsf(float x)
+{
+    return freebsd_fabsf(x);
+}
+
 float
 truncf(float x)
 {
@@ -1573,6 +1656,12 @@ fmaxf(float x, float y)
     return freebsd_fmaxf(x, y);
 }
 
+float
+sqrtf(float x)
+{
+    return freebsd_sqrtf(x);
+}
+
 double
 pow(double x, double y)
 {

+ 2 - 0
core/shared/platform/riot/platform_internal.h

@@ -63,11 +63,13 @@ double fmax(double x, double y);
 double rint(double x);
 double fabs(double x);
 double trunc(double x);
+float sqrtf(float x);
 float floorf(float x);
 float ceilf(float x);
 float fminf(float x, float y);
 float fmaxf(float x, float y);
 float rintf(float x);
+float fabsf(float x);
 float truncf(float x);
 int signbit(double x);
 int isnan(double x);

+ 2 - 0
core/shared/platform/zephyr/platform_internal.h

@@ -78,11 +78,13 @@ double fmax(double x, double y);
 double rint(double x);
 double fabs(double x);
 double trunc(double x);
+float sqrtf(float x);
 float floorf(float x);
 float ceilf(float x);
 float fminf(float x, float y);
 float fmaxf(float x, float y);
 float rintf(float x);
+float fabsf(float x);
 float truncf(float x);
 int signbit(double x);
 int isnan(double x);