1 /* Copyright JS Foundation and other contributors, http://js.foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ecma-alloc.h"
17 #include "ecma-conversion.h"
18 #include "ecma-helpers.h"
19 #include "ecma-try-catch-macro.h"
20 #include "opcodes.h"
21
22 /** \addtogroup vm Virtual machine
23 * @{
24 *
25 * \addtogroup vm_opcodes Opcodes
26 * @{
27 */
28
29 /**
30 * Perform ECMA number logic operation.
31 *
32 * The algorithm of the operation is following:
33 * leftNum = ToNumber (leftValue);
34 * rightNum = ToNumber (rightValue);
35 * result = leftNum BitwiseLogicOp rightNum;
36 *
37 * @return ecma value
38 * Returned value must be freed with ecma_free_value
39 */
40 ecma_value_t
do_number_bitwise_logic(number_bitwise_logic_op op,ecma_value_t left_value,ecma_value_t right_value)41 do_number_bitwise_logic (number_bitwise_logic_op op, /**< number bitwise logic operation */
42 ecma_value_t left_value, /**< left value */
43 ecma_value_t right_value) /**< right value */
44 {
45 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
46 && !ECMA_IS_VALUE_ERROR (right_value));
47
48 ecma_value_t ret_value = ECMA_VALUE_EMPTY;
49
50 ECMA_OP_TO_NUMBER_TRY_CATCH (num_left, left_value, ret_value);
51 ECMA_OP_TO_NUMBER_TRY_CATCH (num_right, right_value, ret_value);
52
53 ecma_number_t result = ECMA_NUMBER_ZERO;
54 uint32_t right_uint32 = ecma_number_to_uint32 (num_right);
55
56 switch (op)
57 {
58 case NUMBER_BITWISE_LOGIC_AND:
59 {
60 uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
61 result = (ecma_number_t) ((int32_t) (left_uint32 & right_uint32));
62 break;
63 }
64 case NUMBER_BITWISE_LOGIC_OR:
65 {
66 uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
67 result = (ecma_number_t) ((int32_t) (left_uint32 | right_uint32));
68 break;
69 }
70 case NUMBER_BITWISE_LOGIC_XOR:
71 {
72 uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
73 result = (ecma_number_t) ((int32_t) (left_uint32 ^ right_uint32));
74 break;
75 }
76 case NUMBER_BITWISE_SHIFT_LEFT:
77 {
78 result = (ecma_number_t) (ecma_number_to_int32 (num_left) << (right_uint32 & 0x1F));
79 break;
80 }
81 case NUMBER_BITWISE_SHIFT_RIGHT:
82 {
83 result = (ecma_number_t) (ecma_number_to_int32 (num_left) >> (right_uint32 & 0x1F));
84 break;
85 }
86 case NUMBER_BITWISE_SHIFT_URIGHT:
87 {
88 uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
89 result = (ecma_number_t) (left_uint32 >> (right_uint32 & 0x1F));
90 break;
91 }
92 case NUMBER_BITWISE_NOT:
93 {
94 result = (ecma_number_t) ((int32_t) ~right_uint32);
95 break;
96 }
97 }
98
99 ret_value = ecma_make_number_value (result);
100
101 ECMA_OP_TO_NUMBER_FINALIZE (num_right);
102 ECMA_OP_TO_NUMBER_FINALIZE (num_left);
103
104 return ret_value;
105 } /* do_number_bitwise_logic */
106
107 /**
108 * @}
109 * @}
110 */
111