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 @@
-
-
-
-