diff --git a/jerry-core/ecma/operations/ecma-big-uint.c b/jerry-core/ecma/operations/ecma-big-uint.c index 5a18ebf28..b742c45a2 100644 --- a/jerry-core/ecma/operations/ecma-big-uint.c +++ b/jerry-core/ecma/operations/ecma-big-uint.c @@ -373,6 +373,138 @@ ecma_big_uint_to_string (ecma_extended_primitive_t *value_p, /**< BigUInt value return result_p; } /* ecma_big_uint_to_string */ +/** + * Increase the value of a BigUInt value by 1 + * + * return new BigInt value, NULL on error + */ +ecma_extended_primitive_t * +ecma_big_uint_increase (ecma_extended_primitive_t *value_p) /**< BigUInt value */ +{ + uint32_t size = ECMA_BIGINT_GET_SIZE (value_p); + + JERRY_ASSERT (size > 0 && ECMA_BIGINT_GET_LAST_DIGIT (value_p, size) != 0); + + ecma_bigint_digit_t *digits_p = ECMA_BIGINT_GET_DIGITS (value_p, 0); + ecma_bigint_digit_t *digits_end_p = ECMA_BIGINT_GET_DIGITS (value_p, size); + + if (JERRY_UNLIKELY (digits_p[0] == ~((ecma_bigint_digit_t) 0) && digits_end_p[-1] == ~((ecma_bigint_digit_t) 0))) + { + do + { + digits_p++; + } + while (digits_p < digits_end_p && digits_p[0] == ~((ecma_bigint_digit_t) 0)); + + if (digits_p == digits_end_p) + { + ecma_extended_primitive_t *result_value_p; + result_value_p = ecma_bigint_create ((uint32_t) (size + sizeof (ecma_bigint_digit_t))); + + if (JERRY_UNLIKELY (result_value_p == NULL)) + { + return NULL; + } + + memset (ECMA_BIGINT_GET_DIGITS (result_value_p, 0), 0, size); + *ECMA_BIGINT_GET_DIGITS (result_value_p, size) = 1; + return result_value_p; + } + + digits_p = ECMA_BIGINT_GET_DIGITS (value_p, 0); + } + + ecma_extended_primitive_t *result_value_p = ecma_bigint_create (size); + + if (JERRY_UNLIKELY (result_value_p == NULL)) + { + return NULL; + } + + ecma_bigint_digit_t *result_p = ECMA_BIGINT_GET_DIGITS (result_value_p, 0); + + while (digits_p[0] == ~((ecma_bigint_digit_t) 0)) + { + digits_p++; + *result_p++ = 0; + } + + *result_p++ = (*digits_p++) + 1; + + if (digits_p < digits_end_p) + { + memcpy (result_p, digits_p, (size_t) ((uint8_t *) digits_end_p - (uint8_t *) digits_p)); + } + return result_value_p; +} /* ecma_big_uint_increase */ + +/** + * Decrease the value of a BigUInt value by 1 + * + * return new BigInt value, NULL on error + */ +ecma_extended_primitive_t * +ecma_big_uint_decrease (ecma_extended_primitive_t *value_p) /**< BigUInt value */ +{ + uint32_t size = ECMA_BIGINT_GET_SIZE (value_p); + + JERRY_ASSERT (size > 0 && ECMA_BIGINT_GET_LAST_DIGIT (value_p, size) != 0); + + ecma_bigint_digit_t *digits_p = ECMA_BIGINT_GET_DIGITS (value_p, 0); + ecma_bigint_digit_t *digits_end_p = ECMA_BIGINT_GET_DIGITS (value_p, size); + + JERRY_ASSERT (size > sizeof (ecma_bigint_digit_t) || *digits_p > 1); + + if (JERRY_UNLIKELY (digits_p[0] == 0 && digits_end_p[-1] == 1)) + { + do + { + digits_p++; + JERRY_ASSERT (digits_p < digits_end_p); + } + while (digits_p[0] == 0); + + if (digits_p + 1 == digits_end_p) + { + size -= (uint32_t) sizeof (ecma_bigint_digit_t); + ecma_extended_primitive_t *result_value_p = ecma_bigint_create (size); + + if (JERRY_UNLIKELY (result_value_p == NULL)) + { + return NULL; + } + + memset (ECMA_BIGINT_GET_DIGITS (result_value_p, 0), 0xff, size); + return result_value_p; + } + + digits_p = ECMA_BIGINT_GET_DIGITS (value_p, 0); + } + + ecma_extended_primitive_t *result_value_p = ecma_bigint_create (size); + + if (JERRY_UNLIKELY (result_value_p == NULL)) + { + return NULL; + } + + ecma_bigint_digit_t *result_p = ECMA_BIGINT_GET_DIGITS (result_value_p, 0); + + while (digits_p[0] == 0) + { + digits_p++; + *result_p++ = ~((ecma_bigint_digit_t) 0); + } + + *result_p++ = (*digits_p++) - 1; + + if (digits_p < digits_end_p) + { + memcpy (result_p, digits_p, (size_t) ((uint8_t *) digits_end_p - (uint8_t *) digits_p)); + } + return result_value_p; +} /* ecma_big_uint_decrease */ + /** * Add right BigUInt value to the left BigUInt value * diff --git a/jerry-core/ecma/operations/ecma-big-uint.h b/jerry-core/ecma/operations/ecma-big-uint.h index de4434d38..5d3dd8c69 100644 --- a/jerry-core/ecma/operations/ecma-big-uint.h +++ b/jerry-core/ecma/operations/ecma-big-uint.h @@ -103,6 +103,9 @@ ecma_extended_primitive_t *ecma_big_uint_mul_digit (ecma_extended_primitive_t *v uint8_t *ecma_big_uint_to_string (ecma_extended_primitive_t *value_p, uint32_t radix, uint32_t *char_start_p, uint32_t *char_size_p); +ecma_extended_primitive_t *ecma_big_uint_increase (ecma_extended_primitive_t *value_p); +ecma_extended_primitive_t *ecma_big_uint_decrease (ecma_extended_primitive_t *value_p); + ecma_extended_primitive_t *ecma_big_uint_add (ecma_extended_primitive_t *left_value_p, ecma_extended_primitive_t *right_value_p); ecma_extended_primitive_t *ecma_big_uint_sub (ecma_extended_primitive_t *left_value_p, diff --git a/jerry-core/ecma/operations/ecma-bigint.c b/jerry-core/ecma/operations/ecma-bigint.c index 77a689d43..975929654 100644 --- a/jerry-core/ecma/operations/ecma-bigint.c +++ b/jerry-core/ecma/operations/ecma-bigint.c @@ -34,6 +34,34 @@ ecma_bigint_raise_memory_error (void) return ecma_raise_range_error (ECMA_ERR_MSG ("Cannot allocate memory for a BigInt value")); } /* ecma_bigint_raise_memory_error */ +/** + * Create a single digit long BigInt value + * + * @return ecma BigInt value or ECMA_VALUE_ERROR + * Returned value must be freed with ecma_free_value. + */ +static ecma_value_t +ecma_bigint_create_from_digit (ecma_bigint_digit_t digit, /* single digit */ + bool sign) /* set ECMA_BIGINT_SIGN if true */ +{ + JERRY_ASSERT (digit != 0); + + ecma_extended_primitive_t *result_value_p = ecma_bigint_create (sizeof (ecma_bigint_digit_t)); + + if (JERRY_UNLIKELY (result_value_p == NULL)) + { + return ecma_bigint_raise_memory_error (); + } + + if (sign) + { + result_value_p->u.bigint_sign_and_size |= ECMA_BIGINT_SIGN; + } + + *ECMA_BIGINT_GET_DIGITS (result_value_p, 0) = digit; + return ecma_make_extended_primitive_value (result_value_p, ECMA_TYPE_BIGINT); +} /* ecma_bigint_create_from_digit */ + /** * Parse a string and create a BigInt value * @@ -443,17 +471,7 @@ ecma_bigint_to_bigint (ecma_value_t value, /**< any value */ } else if (ecma_is_value_true (value)) { - ecma_extended_primitive_t *result_p = ecma_bigint_create (sizeof (ecma_bigint_digit_t)); - - if (result_p != NULL) - { - *ECMA_BIGINT_GET_DIGITS (result_p, 0) = 1; - result = ecma_make_extended_primitive_value (result_p, ECMA_TYPE_BIGINT); - } - else - { - result = ecma_bigint_raise_memory_error (); - } + result = ecma_bigint_create_from_digit (1, false); } else { @@ -911,6 +929,62 @@ ecma_bigint_negate (ecma_extended_primitive_t *value_p) /**< BigInt value */ return ecma_make_extended_primitive_value (result_p, ECMA_TYPE_BIGINT); } /* ecma_bigint_negate */ +/** + * Invert all bits of a BigInt value + * + * @return ecma BigInt value or ECMA_VALUE_ERROR + * Returned value must be freed with ecma_free_value. + */ +ecma_value_t +ecma_bigint_unary (ecma_value_t value, /**< BigInt value */ + ecma_bigint_unary_operation_type type) /**< type of unary operation */ +{ + JERRY_ASSERT (ecma_is_value_bigint (value)); + + if (value == ECMA_BIGINT_ZERO) + { + return ecma_bigint_create_from_digit (1, type != ECMA_BIGINT_UNARY_INCREASE); + } + + ecma_extended_primitive_t *value_p = ecma_get_extended_primitive_from_value (value); + + uint32_t sign = (type != ECMA_BIGINT_UNARY_DECREASE) ? ECMA_BIGINT_SIGN : 0; + + if ((value_p->u.bigint_sign_and_size == (uint32_t) (sizeof (ecma_bigint_digit_t) | sign)) + && *ECMA_BIGINT_GET_DIGITS (value_p, 0) == 1) + { + return ECMA_BIGINT_ZERO; + } + + ecma_extended_primitive_t *result_p; + + if ((value_p->u.bigint_sign_and_size & ECMA_BIGINT_SIGN) == (sign ^ ECMA_BIGINT_SIGN)) + { + result_p = ecma_big_uint_increase (value_p); + + if (type != ECMA_BIGINT_UNARY_INCREASE && result_p != NULL) + { + result_p->u.bigint_sign_and_size |= ECMA_BIGINT_SIGN; + } + } + else + { + result_p = ecma_big_uint_decrease (value_p); + + if (type == ECMA_BIGINT_UNARY_INCREASE && result_p != NULL) + { + result_p->u.bigint_sign_and_size |= ECMA_BIGINT_SIGN; + } + } + + if (JERRY_UNLIKELY (result_p == NULL)) + { + return ecma_bigint_raise_memory_error (); + } + + return ecma_make_extended_primitive_value (result_p, ECMA_TYPE_BIGINT); +} /* ecma_bigint_unary */ + /** * Add/subtract right BigInt value to/from left BigInt value * diff --git a/jerry-core/ecma/operations/ecma-bigint.h b/jerry-core/ecma/operations/ecma-bigint.h index c05e96db9..70711786f 100644 --- a/jerry-core/ecma/operations/ecma-bigint.h +++ b/jerry-core/ecma/operations/ecma-bigint.h @@ -38,6 +38,16 @@ typedef enum * return with ECMA_VALUE_NULL instead */ } ecma_bigint_parse_string_options_t; +/** + * Types for unary operations + */ +typedef enum +{ + ECMA_BIGINT_UNARY_BITWISE_NOT, /**< bitwise not operation */ + ECMA_BIGINT_UNARY_INCREASE, /**< increase operation */ + ECMA_BIGINT_UNARY_DECREASE, /**< decrease operation */ +} ecma_bigint_unary_operation_type; + ecma_value_t ecma_bigint_parse_string (const lit_utf8_byte_t *string_p, lit_utf8_size_t size, uint32_t options); ecma_value_t ecma_bigint_parse_string_value (ecma_value_t string, uint32_t options); @@ -54,6 +64,7 @@ int ecma_bigint_compare_to_bigint (ecma_value_t left_value, ecma_value_t right_v int ecma_bigint_compare_to_number (ecma_value_t left_value, ecma_number_t right_value); ecma_value_t ecma_bigint_negate (ecma_extended_primitive_t *value_p); +ecma_value_t ecma_bigint_unary (ecma_value_t value, ecma_bigint_unary_operation_type type); ecma_value_t ecma_bigint_add_sub (ecma_value_t left_value, ecma_value_t right_value, bool is_add); ecma_value_t ecma_bigint_mul (ecma_value_t left_value, ecma_value_t right_value); ecma_value_t ecma_bigint_div_mod (ecma_value_t left_value, ecma_value_t right_value, bool is_mod); diff --git a/jerry-core/include/jerryscript-snapshot.h b/jerry-core/include/jerryscript-snapshot.h index 922e76b05..fde0b09ab 100644 --- a/jerry-core/include/jerryscript-snapshot.h +++ b/jerry-core/include/jerryscript-snapshot.h @@ -30,7 +30,7 @@ extern "C" /** * Jerry snapshot format version. */ -#define JERRY_SNAPSHOT_VERSION (55u) +#define JERRY_SNAPSHOT_VERSION (56u) /** * Flags for jerry_generate_snapshot and jerry_generate_function_snapshot. diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c index 6d1e215df..c620feb68 100644 --- a/jerry-core/parser/js/js-parser.c +++ b/jerry-core/parser/js/js-parser.c @@ -1074,32 +1074,60 @@ parser_post_processing (parser_context_t *context_p) /**< context */ flags = cbc_flags[last_opcode]; length++; - if (last_opcode == CBC_EXT_OPCODE) + switch (last_opcode) { - cbc_ext_opcode_t ext_opcode; + case CBC_EXT_OPCODE: + { + cbc_ext_opcode_t ext_opcode; - ext_opcode = (cbc_ext_opcode_t) page_p->bytes[offset]; - branch_offset_length = CBC_BRANCH_OFFSET_LENGTH (ext_opcode); - flags = cbc_ext_flags[ext_opcode]; - PARSER_NEXT_BYTE (page_p, offset); - length++; + ext_opcode = (cbc_ext_opcode_t) page_p->bytes[offset]; + branch_offset_length = CBC_BRANCH_OFFSET_LENGTH (ext_opcode); + flags = cbc_ext_flags[ext_opcode]; + PARSER_NEXT_BYTE (page_p, offset); + length++; #if ENABLED (JERRY_LINE_INFO) - if (ext_opcode == CBC_EXT_LINE) - { - uint8_t last_byte = 0; - - do + if (ext_opcode == CBC_EXT_LINE) { - last_byte = page_p->bytes[offset]; - PARSER_NEXT_BYTE (page_p, offset); - length++; - } - while (last_byte & CBC_HIGHEST_BIT_MASK); + uint8_t last_byte = 0; - continue; - } + do + { + last_byte = page_p->bytes[offset]; + PARSER_NEXT_BYTE (page_p, offset); + length++; + } + while (last_byte & CBC_HIGHEST_BIT_MASK); + + continue; + } #endif /* ENABLED (JERRY_LINE_INFO) */ + break; + } + case CBC_POST_DECR: + { + *opcode_p = CBC_PRE_DECR; + break; + } + case CBC_POST_INCR: + { + *opcode_p = CBC_PRE_INCR; + break; + } + case CBC_POST_DECR_IDENT: + { + *opcode_p = CBC_PRE_DECR_IDENT; + break; + } + case CBC_POST_INCR_IDENT: + { + *opcode_p = CBC_PRE_INCR_IDENT; + break; + } + default: + { + break; + } } while (flags & (CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2)) diff --git a/jerry-core/vm/opcodes-ecma-bitwise.c b/jerry-core/vm/opcodes-ecma-bitwise.c index b289f197b..63179d401 100644 --- a/jerry-core/vm/opcodes-ecma-bitwise.c +++ b/jerry-core/vm/opcodes-ecma-bitwise.c @@ -97,17 +97,14 @@ do_number_bitwise_logic (number_bitwise_logic_op op, /**< number bitwise logic o result = (ecma_number_t) (ecma_number_to_int32 (left_number) >> (right_uint32 & 0x1F)); break; } - case NUMBER_BITWISE_SHIFT_URIGHT: + default: { + JERRY_ASSERT (op == NUMBER_BITWISE_SHIFT_URIGHT); + uint32_t left_uint32 = ecma_number_to_uint32 (left_number); result = (ecma_number_t) (left_uint32 >> (right_uint32 & 0x1F)); break; } - case NUMBER_BITWISE_NOT: - { - result = (ecma_number_t) ((int32_t) ~right_uint32); - break; - } } ret_value = ecma_make_number_value (result); @@ -155,7 +152,9 @@ do_number_bitwise_logic (number_bitwise_logic_op op, /**< number bitwise logic o } default: { - ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Not supported BigInt operation")); + JERRY_ASSERT (op == NUMBER_BITWISE_SHIFT_URIGHT); + + ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Unsigned right shift is not allowed for BigInts")); break; } } @@ -171,6 +170,39 @@ do_number_bitwise_logic (number_bitwise_logic_op op, /**< number bitwise logic o return ret_value; } /* do_number_bitwise_logic */ +/** + * Perform ECMA number bitwise not operation. + * + * @return ecma value + * Returned value must be freed with ecma_free_value + */ +ecma_value_t +do_number_bitwise_not (ecma_value_t value) /**< value */ +{ + JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (value)); + + ecma_number_t number; + value = ecma_op_to_numeric (value, &number, ECMA_TO_NUMERIC_ALLOW_BIGINT); + + if (ECMA_IS_VALUE_ERROR (value)) + { + return value; + } + +#if ENABLED (JERRY_BUILTIN_BIGINT) + if (JERRY_LIKELY (!ecma_is_value_bigint (value))) + { +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ + return ecma_make_number_value ((ecma_number_t) ((int32_t) ~ecma_number_to_uint32 (number))); +#if ENABLED (JERRY_BUILTIN_BIGINT) + } + + ecma_value_t ret_value = ecma_bigint_unary (value, ECMA_BIGINT_UNARY_BITWISE_NOT); + ecma_free_value (value); + return ret_value; +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ +} /* do_number_bitwise_not */ + /** * @} * @} diff --git a/jerry-core/vm/opcodes.h b/jerry-core/vm/opcodes.h index 5766f4bb6..15c2d8540 100644 --- a/jerry-core/vm/opcodes.h +++ b/jerry-core/vm/opcodes.h @@ -51,7 +51,6 @@ typedef enum NUMBER_BITWISE_SHIFT_LEFT, /**< bitwise LEFT SHIFT calculation */ NUMBER_BITWISE_SHIFT_RIGHT, /**< bitwise RIGHT_SHIFT calculation */ NUMBER_BITWISE_SHIFT_URIGHT, /**< bitwise UNSIGNED RIGHT SHIFT calculation */ - NUMBER_BITWISE_NOT, /**< bitwise NOT calculation */ } number_bitwise_logic_op; #if ENABLED (JERRY_ESNEXT) @@ -90,6 +89,9 @@ opfunc_unary_operation (ecma_value_t left_value, bool is_plus); ecma_value_t do_number_bitwise_logic (number_bitwise_logic_op op, ecma_value_t left_value, ecma_value_t right_value); +ecma_value_t +do_number_bitwise_not (ecma_value_t value); + ecma_value_t opfunc_addition (ecma_value_t left_value, ecma_value_t right_value); diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index 68f0b8c46..f6d81b248 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -17,6 +17,7 @@ #include "ecma-alloc.h" #include "ecma-array-object.h" +#include "ecma-bigint.h" #include "ecma-builtins.h" #include "ecma-builtin-object.h" #include "ecma-comparison.h" @@ -952,6 +953,41 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ } \ while (0) +/** + * Store the original value for post increase/decrease operators + * + * @param value original value + */ +#define POST_INCREASE_DECREASE_PUT_RESULT(value) \ + if (opcode_data & VM_OC_PUT_STACK) \ + { \ + if (opcode_flags & VM_OC_IDENT_INCR_DECR_OPERATOR_FLAG) \ + { \ + JERRY_ASSERT (opcode == CBC_POST_INCR_IDENT_PUSH_RESULT \ + || opcode == CBC_POST_DECR_IDENT_PUSH_RESULT); \ + *stack_top_p++ = (value); \ + } \ + else \ + { \ + /* The parser ensures there is enough space for the \ + * extra value on the stack. See js-parser-expr.c. */ \ + JERRY_ASSERT (opcode == CBC_POST_INCR_PUSH_RESULT \ + || opcode == CBC_POST_DECR_PUSH_RESULT); \ + stack_top_p++; \ + stack_top_p[-1] = stack_top_p[-2]; \ + stack_top_p[-2] = stack_top_p[-3]; \ + stack_top_p[-3] = (value); \ + } \ + opcode_data &= (uint32_t) ~VM_OC_PUT_STACK; \ + } \ + else \ + { \ + JERRY_ASSERT (opcode_data & VM_OC_PUT_BLOCK); \ + ecma_free_value (frame_ctx_p->block_result); \ + frame_ctx_p->block_result = (value); \ + opcode_data &= (uint32_t) ~VM_OC_PUT_BLOCK; \ + } + /** * Run generic byte code. * @@ -2597,6 +2633,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ case VM_OC_POST_DECR: { uint32_t opcode_flags = VM_OC_GROUP_GET_INDEX (opcode_data) - VM_OC_PROP_PRE_INCR; + ecma_number_t result_number; byte_code_p = byte_code_start_p + 1; @@ -2625,59 +2662,68 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ /* Postfix operators require the unmodifed number value. */ if (opcode_flags & VM_OC_POST_INCR_DECR_OPERATOR_FLAG) { - if (opcode_data & VM_OC_PUT_STACK) - { - if (opcode_flags & VM_OC_IDENT_INCR_DECR_OPERATOR_FLAG) - { - JERRY_ASSERT (opcode == CBC_POST_INCR_IDENT_PUSH_RESULT - || opcode == CBC_POST_DECR_IDENT_PUSH_RESULT); - - *stack_top_p++ = result; - } - else - { - /* The parser ensures there is enough space for the - * extra value on the stack. See js-parser-expr.c. */ - - JERRY_ASSERT (opcode == CBC_POST_INCR_PUSH_RESULT - || opcode == CBC_POST_DECR_PUSH_RESULT); - - stack_top_p++; - stack_top_p[-1] = stack_top_p[-2]; - stack_top_p[-2] = stack_top_p[-3]; - stack_top_p[-3] = result; - } - opcode_data &= (uint32_t) ~VM_OC_PUT_STACK; - } - else if (opcode_data & VM_OC_PUT_BLOCK) - { - ecma_free_value (frame_ctx_p->block_result); - frame_ctx_p->block_result = result; - opcode_data &= (uint32_t) ~VM_OC_PUT_BLOCK; - } + POST_INCREASE_DECREASE_PUT_RESULT (result); } result = (ecma_value_t) (int_value + int_increase); break; } + result_number = ecma_get_integer_from_value (result); } else if (ecma_is_value_float_number (left_value)) { result = left_value; left_value = ECMA_VALUE_UNDEFINED; + result_number = ecma_get_number_from_value (result); } else { - result = ecma_op_to_number (left_value); + result = ecma_op_to_numeric (left_value, &result_number, ECMA_TO_NUMERIC_ALLOW_BIGINT); if (ECMA_IS_VALUE_ERROR (result)) { goto error; } + + ecma_free_value (left_value); + left_value = ECMA_VALUE_UNDEFINED; + +#if ENABLED (JERRY_BUILTIN_BIGINT) + if (JERRY_UNLIKELY (ecma_is_value_bigint (result))) + { + ecma_bigint_unary_operation_type operation_type = ECMA_BIGINT_UNARY_INCREASE; + + if (opcode_flags & VM_OC_DECREMENT_OPERATOR_FLAG) + { + operation_type = ECMA_BIGINT_UNARY_DECREASE; + } + + /* Postfix operators require the unmodifed number value. */ + if (opcode_flags & VM_OC_POST_INCR_DECR_OPERATOR_FLAG) + { + POST_INCREASE_DECREASE_PUT_RESULT (result); + + result = ecma_bigint_unary (result, operation_type); + } + else + { + ecma_value_t original_value = result; + result = ecma_bigint_unary (original_value, operation_type); + ecma_free_value (original_value); + } + + if (ECMA_IS_VALUE_ERROR (result)) + { + goto error; + } + break; + } +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ + + result = ecma_make_number_value (result_number); } ecma_number_t increase = ECMA_NUMBER_ONE; - ecma_number_t result_number = ecma_get_number_from_value (result); if (opcode_flags & VM_OC_DECREMENT_OPERATOR_FLAG) { @@ -2685,39 +2731,13 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ increase = ECMA_NUMBER_MINUS_ONE; } - /* Post 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_data & VM_OC_PUT_STACK) - { - if (opcode_flags & VM_OC_IDENT_INCR_DECR_OPERATOR_FLAG) - { - JERRY_ASSERT (opcode == CBC_POST_INCR_IDENT_PUSH_RESULT - || opcode == CBC_POST_DECR_IDENT_PUSH_RESULT); + POST_INCREASE_DECREASE_PUT_RESULT (result); - *stack_top_p++ = ecma_copy_value (result); - } - else - { - /* The parser ensures there is enough space for the - * extra value on the stack. See js-parser-expr.c. */ - - JERRY_ASSERT (opcode == CBC_POST_INCR_PUSH_RESULT - || opcode == CBC_POST_DECR_PUSH_RESULT); - - stack_top_p++; - stack_top_p[-1] = stack_top_p[-2]; - stack_top_p[-2] = stack_top_p[-3]; - stack_top_p[-3] = ecma_copy_value (result); - } - opcode_data &= (uint32_t) ~VM_OC_PUT_STACK; - } - else if (opcode_data & VM_OC_PUT_BLOCK) - { - ecma_free_value (frame_ctx_p->block_result); - frame_ctx_p->block_result = ecma_copy_value (result); - opcode_data &= (uint32_t) ~VM_OC_PUT_BLOCK; - } + result = ecma_make_number_value (result_number + increase); + break; } if (ecma_is_value_integer_number (result)) @@ -2975,9 +2995,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ goto free_left_value; } - result = do_number_bitwise_logic (NUMBER_BITWISE_NOT, - left_value, - left_value); + result = do_number_bitwise_not (left_value); if (ECMA_IS_VALUE_ERROR (result)) { diff --git a/tests/jerry/es.next/bigint7.js b/tests/jerry/es.next/bigint7.js new file mode 100644 index 000000000..c3008f100 --- /dev/null +++ b/tests/jerry/es.next/bigint7.js @@ -0,0 +1,115 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Bitwise not + +assert(~BigInt("0") === -1n) +assert(~BigInt("-1") === 0n) + +assert(~BigInt("0xffffffff") === -0x100000000n) +assert(~BigInt("0x100000000") === -0x100000001n) +assert(~BigInt("0x10000ffff") === -0x100010000n) +assert(~(-BigInt("0xffffffff")) === 0xfffffffen) +assert(~(-BigInt("0x100000000")) === 0xffffffffn) +assert(~(-BigInt("0x10000ffff")) === 0x10000fffen) + +assert(~BigInt("0xffffffffffffffff") === -0x10000000000000000n) +assert(~BigInt("0xffffffffffffffffffffffffffffffff") === -0x100000000000000000000000000000000n) +assert(~BigInt("0x100000000000000000000000000000000") === -0x100000000000000000000000000000001n) +assert(~BigInt("0x100000000000000ffffffffffffffffff") === -0x100000000000001000000000000000000n) +assert(~(-BigInt("0xffffffffffffffff")) === 0xfffffffffffffffen) +assert(~(-BigInt("0xffffffffffffffffffffffffffffffff")) === 0xfffffffffffffffffffffffffffffffen) +assert(~(-BigInt("0x100000000000000000000000000000000")) === 0xffffffffffffffffffffffffffffffffn) +assert(~(-BigInt("0xffffffffffffff000000000000000000")) === 0xfffffffffffffeffffffffffffffffffn) + +// Increase + +var a = 0n +assert(++a === 1n) +assert(a === 1n) + +a = -1n +assert(++a === 0n) +assert(a === 0n) + +a = 1n +assert(++a === 2n) +assert(a === 2n) + +a = 0xffffffffn +assert(++a === 0x100000000n) +assert(a === 0x100000000n) + +a = { b:0xffffffffffffffffn } +assert(++a.b === 0x10000000000000000n) +assert(a.b === 0x10000000000000000n) + +a = 0xffffffffffffffffffffffffffffffffn +assert(a++ === 0xffffffffffffffffffffffffffffffffn) +assert(a === 0x100000000000000000000000000000000n) + +a = { b:0x100000000000000ffffffffffffffffffn } +assert(a.b++ === 0x100000000000000ffffffffffffffffffn) +assert(a.b === 0x100000000000001000000000000000000n) + +a = -0x10000000000000001n; +for (var i = 0; i < 1; i++, a++) ; +assert(a === -0x10000000000000000n) + +a = { b:-0x100000000000001000000000000000000n } +for (var i = 0; i < 1; i++, ++a.b) ; +assert(a.b === -0x100000000000000ffffffffffffffffffn) + +// Decrease + +a = 0n +assert(--a === -1n) +assert(a === -1n) + +a = 1n +assert(--a === 0n) +assert(a === 0n) + +a = -1n +assert(--a === -2n) +assert(a === -2n) + +a = 0x100000000n +assert(--a === 0xffffffffn) +assert(a === 0xffffffffn) + +a = -0xffffffffffffffffn +assert(a-- === -0xffffffffffffffffn) +assert(a === -0x10000000000000000n) + +a = { b:0x10000000000000000n } +assert(--a.b === 0xffffffffffffffffn) +assert(a.b === 0xffffffffffffffffn) + +a = 0x100000000000000000000000000000000n +assert(a-- === 0x100000000000000000000000000000000n) +assert(a === 0xffffffffffffffffffffffffffffffffn) + +a = { b:0x100000000000001000000000000000000n } +assert(a.b-- === 0x100000000000001000000000000000000n) +assert(a.b === 0x100000000000000ffffffffffffffffffn) + +a = 0x10000000000000001n; +for (var i = 0; i < 1; i++, a--) ; +assert(a === 0x10000000000000000n) + +a = { b:-0x100000000000000ffffffffffffffffffn } +for (var i = 0; i < 1; i++, --a.b) ; +assert(a.b === -0x100000000000001000000000000000000n) diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml index 5b4a6fbca..9c0fa66a9 100644 --- a/tests/test262-esnext-excludelist.xml +++ b/tests/test262-esnext-excludelist.xml @@ -4202,8 +4202,6 @@ - - @@ -6761,28 +6759,24 @@ - - - -