Optimize arithmetic in VM.
Add, substract, mul, mod, and increment/decrement operators are optimized. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -732,6 +732,35 @@ ecma_value_assign_value (ecma_value_t *value_p, /**< [in, out] ecma value */
|
|||||||
}
|
}
|
||||||
} /* ecma_value_assign_value */
|
} /* ecma_value_assign_value */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the value of a float number to a new value
|
||||||
|
*
|
||||||
|
* Note:
|
||||||
|
* The original value is destroyed.
|
||||||
|
*
|
||||||
|
* @return updated ecma value
|
||||||
|
*/
|
||||||
|
ecma_value_t
|
||||||
|
ecma_update_float_number (ecma_value_t float_value, /**< original float value */
|
||||||
|
ecma_number_t new_number) /**< updated number value */
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (ecma_is_value_float_number (float_value));
|
||||||
|
|
||||||
|
ecma_integer_value_t integer_number = (ecma_integer_value_t) new_number;
|
||||||
|
ecma_number_t *number_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (float_value);
|
||||||
|
|
||||||
|
if ((ecma_number_t) integer_number == new_number
|
||||||
|
&& ((integer_number == 0) ? ecma_is_number_equal_to_positive_zero (new_number)
|
||||||
|
: ECMA_IS_INTEGER_NUMBER (integer_number)))
|
||||||
|
{
|
||||||
|
ecma_dealloc_number (number_p);
|
||||||
|
return ecma_make_integer_value (integer_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
*number_p = new_number;
|
||||||
|
return float_value;
|
||||||
|
} /* ecma_update_float_number */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign a float number to an ecma-value
|
* Assign a float number to an ecma-value
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ extern ecma_value_t ecma_make_object_value (const ecma_object_t *);
|
|||||||
extern ecma_value_t ecma_make_error_value (ecma_value_t);
|
extern ecma_value_t ecma_make_error_value (ecma_value_t);
|
||||||
extern ecma_value_t ecma_make_error_obj_value (const ecma_object_t *);
|
extern ecma_value_t ecma_make_error_obj_value (const ecma_object_t *);
|
||||||
extern ecma_integer_value_t ecma_get_integer_from_value (ecma_value_t) __attr_pure___;
|
extern ecma_integer_value_t ecma_get_integer_from_value (ecma_value_t) __attr_pure___;
|
||||||
extern ecma_number_t ecma_get_float_from_value (ecma_value_t value) __attr_pure___;
|
extern ecma_number_t ecma_get_float_from_value (ecma_value_t) __attr_pure___;
|
||||||
extern ecma_number_t ecma_get_number_from_value (ecma_value_t) __attr_pure___;
|
extern ecma_number_t ecma_get_number_from_value (ecma_value_t) __attr_pure___;
|
||||||
extern uint32_t ecma_get_uint32_from_value (ecma_value_t) __attr_pure___;
|
extern uint32_t ecma_get_uint32_from_value (ecma_value_t) __attr_pure___;
|
||||||
extern ecma_string_t *ecma_get_string_from_value (ecma_value_t) __attr_pure___;
|
extern ecma_string_t *ecma_get_string_from_value (ecma_value_t) __attr_pure___;
|
||||||
@@ -153,6 +153,7 @@ extern ecma_value_t ecma_invert_boolean_value (ecma_value_t) __attr_pure___;
|
|||||||
extern ecma_value_t ecma_copy_value (ecma_value_t);
|
extern ecma_value_t ecma_copy_value (ecma_value_t);
|
||||||
extern ecma_value_t ecma_fast_copy_value (ecma_value_t);
|
extern ecma_value_t ecma_fast_copy_value (ecma_value_t);
|
||||||
extern ecma_value_t ecma_copy_value_if_not_object (ecma_value_t);
|
extern ecma_value_t ecma_copy_value_if_not_object (ecma_value_t);
|
||||||
|
extern ecma_value_t ecma_update_float_number (ecma_value_t, ecma_number_t);
|
||||||
extern void ecma_value_assign_value (ecma_value_t *, ecma_value_t);
|
extern void ecma_value_assign_value (ecma_value_t *, ecma_value_t);
|
||||||
extern void ecma_value_assign_number (ecma_value_t *, ecma_number_t);
|
extern void ecma_value_assign_number (ecma_value_t *, ecma_number_t);
|
||||||
extern void ecma_value_assign_uint32 (ecma_value_t *, uint32_t);
|
extern void ecma_value_assign_uint32 (ecma_value_t *, uint32_t);
|
||||||
|
|||||||
@@ -46,63 +46,6 @@ do_number_arithmetic (number_arithmetic_op op, /**< number arithmetic operation
|
|||||||
ecma_value_t left_value, /**< left value */
|
ecma_value_t left_value, /**< left value */
|
||||||
ecma_value_t right_value) /**< right value */
|
ecma_value_t right_value) /**< right value */
|
||||||
{
|
{
|
||||||
JERRY_STATIC_ASSERT (ECMA_INTEGER_MULTIPLY_MAX * ECMA_INTEGER_MULTIPLY_MAX <= ECMA_INTEGER_NUMBER_MAX
|
|
||||||
&& -(ECMA_INTEGER_MULTIPLY_MAX * ECMA_INTEGER_MULTIPLY_MAX) >= ECMA_INTEGER_NUMBER_MIN,
|
|
||||||
square_of_integer_multiply_max_must_fit_into_integer_value_range);
|
|
||||||
JERRY_STATIC_ASSERT (ECMA_INTEGER_NUMBER_MAX * 2 <= INT32_MAX
|
|
||||||
&& ECMA_INTEGER_NUMBER_MIN * 2 >= INT32_MIN,
|
|
||||||
doubled_ecma_numbers_must_fit_into_int32_range);
|
|
||||||
|
|
||||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
|
|
||||||
&& !ECMA_IS_VALUE_ERROR (right_value));
|
|
||||||
|
|
||||||
if (ecma_are_values_integer_numbers (left_value, right_value))
|
|
||||||
{
|
|
||||||
switch (op)
|
|
||||||
{
|
|
||||||
case NUMBER_ARITHMETIC_SUBSTRACTION:
|
|
||||||
{
|
|
||||||
ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value);
|
|
||||||
ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value);
|
|
||||||
return ecma_make_int32_value ((int32_t) (left_integer - right_integer));
|
|
||||||
}
|
|
||||||
case NUMBER_ARITHMETIC_MULTIPLICATION:
|
|
||||||
{
|
|
||||||
ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value);
|
|
||||||
ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value);
|
|
||||||
|
|
||||||
if (-ECMA_INTEGER_MULTIPLY_MAX <= left_integer
|
|
||||||
&& left_integer <= ECMA_INTEGER_MULTIPLY_MAX
|
|
||||||
&& -ECMA_INTEGER_MULTIPLY_MAX <= right_integer
|
|
||||||
&& right_integer <= ECMA_INTEGER_MULTIPLY_MAX)
|
|
||||||
{
|
|
||||||
return ecma_make_integer_value (left_integer * right_integer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NUMBER_ARITHMETIC_DIVISION:
|
|
||||||
{
|
|
||||||
/* Not optimized since the result is likely not an integer number. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NUMBER_ARITHMETIC_REMAINDER:
|
|
||||||
{
|
|
||||||
ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value);
|
|
||||||
ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value);
|
|
||||||
if (right_integer != 0)
|
|
||||||
{
|
|
||||||
ecma_integer_value_t result = left_integer % right_integer;
|
|
||||||
|
|
||||||
if (result != 0 || left_integer >= 0)
|
|
||||||
{
|
|
||||||
return ecma_make_integer_value (result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||||
|
|
||||||
ECMA_OP_TO_NUMBER_TRY_CATCH (num_left, left_value, ret_value);
|
ECMA_OP_TO_NUMBER_TRY_CATCH (num_left, left_value, ret_value);
|
||||||
@@ -154,20 +97,6 @@ ecma_value_t
|
|||||||
opfunc_addition (ecma_value_t left_value, /**< left value */
|
opfunc_addition (ecma_value_t left_value, /**< left value */
|
||||||
ecma_value_t right_value) /**< right value */
|
ecma_value_t right_value) /**< right value */
|
||||||
{
|
{
|
||||||
if (ecma_are_values_integer_numbers (left_value, right_value))
|
|
||||||
{
|
|
||||||
ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value);
|
|
||||||
ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value);
|
|
||||||
return ecma_make_int32_value ((int32_t) (left_integer + right_integer));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ecma_is_value_number (left_value) && ecma_is_value_number (right_value))
|
|
||||||
{
|
|
||||||
ecma_number_t num_left = ecma_get_number_from_value (left_value);
|
|
||||||
ecma_number_t num_right = ecma_get_number_from_value (right_value);
|
|
||||||
return ecma_make_number_value (ecma_number_add (num_left, num_right));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool free_left_value = false;
|
bool free_left_value = false;
|
||||||
bool free_right_value = false;
|
bool free_right_value = false;
|
||||||
|
|
||||||
|
|||||||
+170
-25
@@ -1203,44 +1203,29 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
{
|
{
|
||||||
uint32_t opcode_flags = VM_OC_GROUP_GET_INDEX (opcode_data) - VM_OC_PROP_PRE_INCR;
|
uint32_t opcode_flags = VM_OC_GROUP_GET_INDEX (opcode_data) - VM_OC_PROP_PRE_INCR;
|
||||||
|
|
||||||
result = ecma_op_to_number (left_value);
|
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (result))
|
|
||||||
{
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte_code_p = byte_code_start_p + 1;
|
byte_code_p = byte_code_start_p + 1;
|
||||||
|
|
||||||
if (ecma_is_value_integer_number (result))
|
if (ecma_is_value_integer_number (left_value))
|
||||||
{
|
{
|
||||||
|
result = left_value;
|
||||||
|
left_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||||
|
|
||||||
ecma_integer_value_t int_value = (ecma_integer_value_t) result;
|
ecma_integer_value_t int_value = (ecma_integer_value_t) result;
|
||||||
ecma_integer_value_t int_increase;
|
ecma_integer_value_t int_increase = 0;
|
||||||
|
|
||||||
if (opcode_flags & VM_OC_DECREMENT_OPERATOR_FLAG)
|
if (opcode_flags & VM_OC_DECREMENT_OPERATOR_FLAG)
|
||||||
{
|
{
|
||||||
if (int_value <= (ECMA_INTEGER_NUMBER_MIN << ECMA_DIRECT_SHIFT))
|
if (int_value > (ECMA_INTEGER_NUMBER_MIN << ECMA_DIRECT_SHIFT))
|
||||||
{
|
|
||||||
int_increase = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
int_increase = -(1 << ECMA_DIRECT_SHIFT);
|
int_increase = -(1 << ECMA_DIRECT_SHIFT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (int_value < (ECMA_INTEGER_NUMBER_MAX << ECMA_DIRECT_SHIFT))
|
||||||
{
|
{
|
||||||
if (int_value >= (ECMA_INTEGER_NUMBER_MAX << ECMA_DIRECT_SHIFT))
|
int_increase = 1 << ECMA_DIRECT_SHIFT;
|
||||||
{
|
|
||||||
int_increase = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int_increase = 1 << ECMA_DIRECT_SHIFT;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (int_increase != 0)
|
if (likely (int_increase != 0))
|
||||||
{
|
{
|
||||||
/* Postfix operators require the unmodifed number value. */
|
/* Postfix operators require the unmodifed number value. */
|
||||||
if (opcode_flags & VM_OC_POST_INCR_DECR_OPERATOR_FLAG)
|
if (opcode_flags & VM_OC_POST_INCR_DECR_OPERATOR_FLAG)
|
||||||
@@ -1281,6 +1266,20 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (ecma_is_value_float_number (left_value))
|
||||||
|
{
|
||||||
|
result = left_value;
|
||||||
|
left_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = ecma_op_to_number (left_value);
|
||||||
|
|
||||||
|
if (ECMA_IS_VALUE_ERROR (result))
|
||||||
|
{
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ecma_number_t increase = ECMA_NUMBER_ONE;
|
ecma_number_t increase = ECMA_NUMBER_ONE;
|
||||||
ecma_number_t result_number = ecma_get_number_from_value (result);
|
ecma_number_t result_number = ecma_get_number_from_value (result);
|
||||||
@@ -1326,7 +1325,14 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ecma_value_assign_number (&result, result_number + increase);
|
if (ecma_is_value_integer_number (result))
|
||||||
|
{
|
||||||
|
result = ecma_make_number_value (result_number + increase);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = ecma_update_float_number (result, result_number + increase);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VM_OC_ASSIGN:
|
case VM_OC_ASSIGN:
|
||||||
@@ -1651,6 +1657,36 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
}
|
}
|
||||||
case VM_OC_ADD:
|
case VM_OC_ADD:
|
||||||
{
|
{
|
||||||
|
if (ecma_are_values_integer_numbers (left_value, right_value))
|
||||||
|
{
|
||||||
|
ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value);
|
||||||
|
ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value);
|
||||||
|
result = ecma_make_int32_value ((int32_t) (left_integer + right_integer));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ecma_is_value_float_number (left_value)
|
||||||
|
&& ecma_is_value_number (right_value))
|
||||||
|
{
|
||||||
|
ecma_number_t new_value = ecma_number_add (ecma_get_float_from_value (left_value),
|
||||||
|
ecma_get_number_from_value (right_value));
|
||||||
|
|
||||||
|
result = ecma_update_float_number (left_value, new_value);
|
||||||
|
left_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ecma_is_value_float_number (right_value)
|
||||||
|
&& ecma_is_value_integer_number (left_value))
|
||||||
|
{
|
||||||
|
ecma_number_t new_value = ecma_number_add ((ecma_number_t) ecma_get_integer_from_value (left_value),
|
||||||
|
ecma_get_float_from_value (right_value));
|
||||||
|
|
||||||
|
result = ecma_update_float_number (right_value, new_value);
|
||||||
|
right_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
result = opfunc_addition (left_value, right_value);
|
result = opfunc_addition (left_value, right_value);
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (result))
|
if (ECMA_IS_VALUE_ERROR (result))
|
||||||
@@ -1661,6 +1697,43 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
}
|
}
|
||||||
case VM_OC_SUB:
|
case VM_OC_SUB:
|
||||||
{
|
{
|
||||||
|
JERRY_STATIC_ASSERT (ECMA_INTEGER_NUMBER_MAX * 2 <= INT32_MAX
|
||||||
|
&& ECMA_INTEGER_NUMBER_MIN * 2 >= INT32_MIN,
|
||||||
|
doubled_ecma_numbers_must_fit_into_int32_range);
|
||||||
|
|
||||||
|
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
|
||||||
|
&& !ECMA_IS_VALUE_ERROR (right_value));
|
||||||
|
|
||||||
|
if (ecma_are_values_integer_numbers (left_value, right_value))
|
||||||
|
{
|
||||||
|
ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value);
|
||||||
|
ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value);
|
||||||
|
result = ecma_make_int32_value ((int32_t) (left_integer - right_integer));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ecma_is_value_float_number (left_value)
|
||||||
|
&& ecma_is_value_number (right_value))
|
||||||
|
{
|
||||||
|
ecma_number_t new_value = ecma_number_substract (ecma_get_float_from_value (left_value),
|
||||||
|
ecma_get_number_from_value (right_value));
|
||||||
|
|
||||||
|
result = ecma_update_float_number (left_value, new_value);
|
||||||
|
left_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ecma_is_value_float_number (right_value)
|
||||||
|
&& ecma_is_value_integer_number (left_value))
|
||||||
|
{
|
||||||
|
ecma_number_t new_value = ecma_number_substract ((ecma_number_t) ecma_get_integer_from_value (left_value),
|
||||||
|
ecma_get_float_from_value (right_value));
|
||||||
|
|
||||||
|
result = ecma_update_float_number (right_value, new_value);
|
||||||
|
right_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
result = do_number_arithmetic (NUMBER_ARITHMETIC_SUBSTRACTION,
|
result = do_number_arithmetic (NUMBER_ARITHMETIC_SUBSTRACTION,
|
||||||
left_value,
|
left_value,
|
||||||
right_value);
|
right_value);
|
||||||
@@ -1673,6 +1746,55 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
}
|
}
|
||||||
case VM_OC_MUL:
|
case VM_OC_MUL:
|
||||||
{
|
{
|
||||||
|
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
|
||||||
|
&& !ECMA_IS_VALUE_ERROR (right_value));
|
||||||
|
|
||||||
|
JERRY_STATIC_ASSERT (ECMA_INTEGER_MULTIPLY_MAX * ECMA_INTEGER_MULTIPLY_MAX <= ECMA_INTEGER_NUMBER_MAX
|
||||||
|
&& -(ECMA_INTEGER_MULTIPLY_MAX * ECMA_INTEGER_MULTIPLY_MAX) >= ECMA_INTEGER_NUMBER_MIN,
|
||||||
|
square_of_integer_multiply_max_must_fit_into_integer_value_range);
|
||||||
|
|
||||||
|
if (ecma_are_values_integer_numbers (left_value, right_value))
|
||||||
|
{
|
||||||
|
ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value);
|
||||||
|
ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value);
|
||||||
|
|
||||||
|
if (-ECMA_INTEGER_MULTIPLY_MAX <= left_integer
|
||||||
|
&& left_integer <= ECMA_INTEGER_MULTIPLY_MAX
|
||||||
|
&& -ECMA_INTEGER_MULTIPLY_MAX <= right_integer
|
||||||
|
&& right_integer <= ECMA_INTEGER_MULTIPLY_MAX)
|
||||||
|
{
|
||||||
|
result = ecma_make_integer_value (left_integer * right_integer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ecma_number_t multiply = ecma_number_multiply ((ecma_number_t) left_integer,
|
||||||
|
(ecma_number_t) right_integer);
|
||||||
|
result = ecma_make_number_value (multiply);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ecma_is_value_float_number (left_value)
|
||||||
|
&& ecma_is_value_number (right_value))
|
||||||
|
{
|
||||||
|
ecma_number_t new_value = ecma_number_multiply (ecma_get_float_from_value (left_value),
|
||||||
|
ecma_get_number_from_value (right_value));
|
||||||
|
|
||||||
|
result = ecma_update_float_number (left_value, new_value);
|
||||||
|
left_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ecma_is_value_float_number (right_value)
|
||||||
|
&& ecma_is_value_integer_number (left_value))
|
||||||
|
{
|
||||||
|
ecma_number_t new_value = ecma_number_multiply ((ecma_number_t) ecma_get_integer_from_value (left_value),
|
||||||
|
ecma_get_float_from_value (right_value));
|
||||||
|
|
||||||
|
result = ecma_update_float_number (right_value, new_value);
|
||||||
|
right_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
result = do_number_arithmetic (NUMBER_ARITHMETIC_MULTIPLICATION,
|
result = do_number_arithmetic (NUMBER_ARITHMETIC_MULTIPLICATION,
|
||||||
left_value,
|
left_value,
|
||||||
right_value);
|
right_value);
|
||||||
@@ -1685,6 +1807,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
}
|
}
|
||||||
case VM_OC_DIV:
|
case VM_OC_DIV:
|
||||||
{
|
{
|
||||||
|
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
|
||||||
|
&& !ECMA_IS_VALUE_ERROR (right_value));
|
||||||
|
|
||||||
result = do_number_arithmetic (NUMBER_ARITHMETIC_DIVISION,
|
result = do_number_arithmetic (NUMBER_ARITHMETIC_DIVISION,
|
||||||
left_value,
|
left_value,
|
||||||
right_value);
|
right_value);
|
||||||
@@ -1697,6 +1822,26 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
}
|
}
|
||||||
case VM_OC_MOD:
|
case VM_OC_MOD:
|
||||||
{
|
{
|
||||||
|
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
|
||||||
|
&& !ECMA_IS_VALUE_ERROR (right_value));
|
||||||
|
|
||||||
|
if (ecma_are_values_integer_numbers (left_value, right_value))
|
||||||
|
{
|
||||||
|
ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value);
|
||||||
|
ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value);
|
||||||
|
|
||||||
|
if (right_integer != 0)
|
||||||
|
{
|
||||||
|
ecma_integer_value_t mod_result = left_integer % right_integer;
|
||||||
|
|
||||||
|
if (mod_result != 0 || left_integer >= 0)
|
||||||
|
{
|
||||||
|
result = ecma_make_integer_value (mod_result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result = do_number_arithmetic (NUMBER_ARITHMETIC_REMAINDER,
|
result = do_number_arithmetic (NUMBER_ARITHMETIC_REMAINDER,
|
||||||
left_value,
|
left_value,
|
||||||
right_value);
|
right_value);
|
||||||
|
|||||||
Reference in New Issue
Block a user