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 */
40ecma_value_t
41do_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