Implement unary operators: bitwise not, pre/post increment/decrement (#4116)

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2020-08-10 22:38:34 +02:00
committed by GitHub
parent 43a82cddb9
commit 39fe04814e
11 changed files with 519 additions and 110 deletions
+132
View File
@@ -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
*
@@ -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,
+85 -11
View File
@@ -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
*
+11
View File
@@ -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);
+1 -1
View File
@@ -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.
+47 -19
View File
@@ -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))
+39 -7
View File
@@ -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 */
/**
* @}
* @}
+3 -1
View File
@@ -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);
+83 -65
View File
@@ -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))
{
+115
View File
@@ -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)
-6
View File
@@ -4202,8 +4202,6 @@
<test id="language/expressions/async-generator/yield-thenable-create-resolving-functions-reject.js"><reason></reason></test>
<test id="language/expressions/async-generator/yield-thenable-create-resolving-functions-resolve.js"><reason></reason></test>
<test id="language/expressions/await/for-await-of-interleaved.js"><reason></reason></test>
<test id="language/expressions/bitwise-not/bigint-non-primitive.js"><reason></reason></test>
<test id="language/expressions/bitwise-not/bigint.js"><reason></reason></test>
<test id="language/expressions/call/eval-realm-indirect.js"><reason></reason></test>
<test id="language/expressions/call/eval-spread-empty-leading.js"><reason></reason></test>
<test id="language/expressions/call/eval-spread-empty-trailing.js"><reason></reason></test>
@@ -6761,28 +6759,24 @@
<test id="language/expressions/postfix-decrement/S11.3.2_A5_T4.js"><reason></reason></test>
<test id="language/expressions/postfix-decrement/S11.3.2_A5_T5.js"><reason></reason></test>
<test id="language/expressions/postfix-decrement/S11.3.2_A6_T3.js"><reason></reason></test>
<test id="language/expressions/postfix-decrement/bigint.js"><reason></reason></test>
<test id="language/expressions/postfix-increment/S11.3.1_A5_T1.js"><reason></reason></test>
<test id="language/expressions/postfix-increment/S11.3.1_A5_T2.js"><reason></reason></test>
<test id="language/expressions/postfix-increment/S11.3.1_A5_T3.js"><reason></reason></test>
<test id="language/expressions/postfix-increment/S11.3.1_A5_T4.js"><reason></reason></test>
<test id="language/expressions/postfix-increment/S11.3.1_A5_T5.js"><reason></reason></test>
<test id="language/expressions/postfix-increment/S11.3.1_A6_T3.js"><reason></reason></test>
<test id="language/expressions/postfix-increment/bigint.js"><reason></reason></test>
<test id="language/expressions/prefix-decrement/S11.4.5_A5_T1.js"><reason></reason></test>
<test id="language/expressions/prefix-decrement/S11.4.5_A5_T2.js"><reason></reason></test>
<test id="language/expressions/prefix-decrement/S11.4.5_A5_T3.js"><reason></reason></test>
<test id="language/expressions/prefix-decrement/S11.4.5_A5_T4.js"><reason></reason></test>
<test id="language/expressions/prefix-decrement/S11.4.5_A5_T5.js"><reason></reason></test>
<test id="language/expressions/prefix-decrement/S11.4.5_A6_T3.js"><reason></reason></test>
<test id="language/expressions/prefix-decrement/bigint.js"><reason></reason></test>
<test id="language/expressions/prefix-increment/S11.4.4_A5_T1.js"><reason></reason></test>
<test id="language/expressions/prefix-increment/S11.4.4_A5_T2.js"><reason></reason></test>
<test id="language/expressions/prefix-increment/S11.4.4_A5_T3.js"><reason></reason></test>
<test id="language/expressions/prefix-increment/S11.4.4_A5_T4.js"><reason></reason></test>
<test id="language/expressions/prefix-increment/S11.4.4_A5_T5.js"><reason></reason></test>
<test id="language/expressions/prefix-increment/S11.4.4_A6_T3.js"><reason></reason></test>
<test id="language/expressions/prefix-increment/bigint.js"><reason></reason></test>
<test id="language/expressions/right-shift/bigint.js"><reason></reason></test>
<test id="language/expressions/strict-does-not-equals/bigint-and-number-extremes.js"><reason></reason></test>
<test id="language/expressions/strict-equals/bigint-and-number-extremes.js"><reason></reason></test>