1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation
2425bb815Sopenharmony_ci *
3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License.
5425bb815Sopenharmony_ci * You may obtain a copy of the License at
6425bb815Sopenharmony_ci *
7425bb815Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8425bb815Sopenharmony_ci *
9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS
11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and
13425bb815Sopenharmony_ci * limitations under the License.
14425bb815Sopenharmony_ci */
15425bb815Sopenharmony_ci
16425bb815Sopenharmony_ci#include "ecma-alloc.h"
17425bb815Sopenharmony_ci#include "ecma-conversion.h"
18425bb815Sopenharmony_ci#include "ecma-helpers.h"
19425bb815Sopenharmony_ci#include "ecma-try-catch-macro.h"
20425bb815Sopenharmony_ci#include "opcodes.h"
21425bb815Sopenharmony_ci
22425bb815Sopenharmony_ci/** \addtogroup vm Virtual machine
23425bb815Sopenharmony_ci * @{
24425bb815Sopenharmony_ci *
25425bb815Sopenharmony_ci * \addtogroup vm_opcodes Opcodes
26425bb815Sopenharmony_ci * @{
27425bb815Sopenharmony_ci */
28425bb815Sopenharmony_ci
29425bb815Sopenharmony_ci/**
30425bb815Sopenharmony_ci * Perform ECMA number logic operation.
31425bb815Sopenharmony_ci *
32425bb815Sopenharmony_ci * The algorithm of the operation is following:
33425bb815Sopenharmony_ci *   leftNum = ToNumber (leftValue);
34425bb815Sopenharmony_ci *   rightNum = ToNumber (rightValue);
35425bb815Sopenharmony_ci *   result = leftNum BitwiseLogicOp rightNum;
36425bb815Sopenharmony_ci *
37425bb815Sopenharmony_ci * @return ecma value
38425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value
39425bb815Sopenharmony_ci */
40425bb815Sopenharmony_ciecma_value_t
41425bb815Sopenharmony_cido_number_bitwise_logic (number_bitwise_logic_op op, /**< number bitwise logic operation */
42425bb815Sopenharmony_ci                         ecma_value_t left_value, /**< left value */
43425bb815Sopenharmony_ci                         ecma_value_t right_value) /**< right value */
44425bb815Sopenharmony_ci{
45425bb815Sopenharmony_ci  JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
46425bb815Sopenharmony_ci                && !ECMA_IS_VALUE_ERROR (right_value));
47425bb815Sopenharmony_ci
48425bb815Sopenharmony_ci  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
49425bb815Sopenharmony_ci
50425bb815Sopenharmony_ci  ECMA_OP_TO_NUMBER_TRY_CATCH (num_left, left_value, ret_value);
51425bb815Sopenharmony_ci  ECMA_OP_TO_NUMBER_TRY_CATCH (num_right, right_value, ret_value);
52425bb815Sopenharmony_ci
53425bb815Sopenharmony_ci  ecma_number_t result = ECMA_NUMBER_ZERO;
54425bb815Sopenharmony_ci  uint32_t right_uint32 = ecma_number_to_uint32 (num_right);
55425bb815Sopenharmony_ci
56425bb815Sopenharmony_ci  switch (op)
57425bb815Sopenharmony_ci  {
58425bb815Sopenharmony_ci    case NUMBER_BITWISE_LOGIC_AND:
59425bb815Sopenharmony_ci    {
60425bb815Sopenharmony_ci      uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
61425bb815Sopenharmony_ci      result = (ecma_number_t) ((int32_t) (left_uint32 & right_uint32));
62425bb815Sopenharmony_ci      break;
63425bb815Sopenharmony_ci    }
64425bb815Sopenharmony_ci    case NUMBER_BITWISE_LOGIC_OR:
65425bb815Sopenharmony_ci    {
66425bb815Sopenharmony_ci      uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
67425bb815Sopenharmony_ci      result = (ecma_number_t) ((int32_t) (left_uint32 | right_uint32));
68425bb815Sopenharmony_ci      break;
69425bb815Sopenharmony_ci    }
70425bb815Sopenharmony_ci    case NUMBER_BITWISE_LOGIC_XOR:
71425bb815Sopenharmony_ci    {
72425bb815Sopenharmony_ci      uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
73425bb815Sopenharmony_ci      result = (ecma_number_t) ((int32_t) (left_uint32 ^ right_uint32));
74425bb815Sopenharmony_ci      break;
75425bb815Sopenharmony_ci    }
76425bb815Sopenharmony_ci    case NUMBER_BITWISE_SHIFT_LEFT:
77425bb815Sopenharmony_ci    {
78425bb815Sopenharmony_ci      result = (ecma_number_t) (ecma_number_to_int32 (num_left) << (right_uint32 & 0x1F));
79425bb815Sopenharmony_ci      break;
80425bb815Sopenharmony_ci    }
81425bb815Sopenharmony_ci    case NUMBER_BITWISE_SHIFT_RIGHT:
82425bb815Sopenharmony_ci    {
83425bb815Sopenharmony_ci      result = (ecma_number_t) (ecma_number_to_int32 (num_left) >> (right_uint32 & 0x1F));
84425bb815Sopenharmony_ci      break;
85425bb815Sopenharmony_ci    }
86425bb815Sopenharmony_ci    case NUMBER_BITWISE_SHIFT_URIGHT:
87425bb815Sopenharmony_ci    {
88425bb815Sopenharmony_ci      uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
89425bb815Sopenharmony_ci      result = (ecma_number_t) (left_uint32 >> (right_uint32 & 0x1F));
90425bb815Sopenharmony_ci      break;
91425bb815Sopenharmony_ci    }
92425bb815Sopenharmony_ci    case NUMBER_BITWISE_NOT:
93425bb815Sopenharmony_ci    {
94425bb815Sopenharmony_ci      result = (ecma_number_t) ((int32_t) ~right_uint32);
95425bb815Sopenharmony_ci      break;
96425bb815Sopenharmony_ci    }
97425bb815Sopenharmony_ci  }
98425bb815Sopenharmony_ci
99425bb815Sopenharmony_ci  ret_value = ecma_make_number_value (result);
100425bb815Sopenharmony_ci
101425bb815Sopenharmony_ci  ECMA_OP_TO_NUMBER_FINALIZE (num_right);
102425bb815Sopenharmony_ci  ECMA_OP_TO_NUMBER_FINALIZE (num_left);
103425bb815Sopenharmony_ci
104425bb815Sopenharmony_ci  return ret_value;
105425bb815Sopenharmony_ci} /* do_number_bitwise_logic */
106425bb815Sopenharmony_ci
107425bb815Sopenharmony_ci/**
108425bb815Sopenharmony_ci * @}
109425bb815Sopenharmony_ci * @}
110425bb815Sopenharmony_ci */
111