mirror of
https://github.com/google/pebble.git
synced 2025-05-28 14:03:12 +00:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
224
third_party/jerryscript/jerry-core/vm/opcodes-ecma-arithmetics.c
vendored
Normal file
224
third_party/jerryscript/jerry-core/vm/opcodes-ecma-arithmetics.c
vendored
Normal file
|
@ -0,0 +1,224 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015-2016 University of Szeged.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-conversion.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-number-arithmetic.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "opcodes.h"
|
||||
#include "jrt-libc-includes.h"
|
||||
|
||||
/** \addtogroup vm Virtual machine
|
||||
* @{
|
||||
*
|
||||
* \addtogroup vm_opcodes Opcodes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Perform ECMA number arithmetic operation.
|
||||
*
|
||||
* The algorithm of the operation is following:
|
||||
* leftNum = ToNumber (leftValue);
|
||||
* rightNum = ToNumber (rightValue);
|
||||
* result = leftNum ArithmeticOp rightNum;
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
do_number_arithmetic (number_arithmetic_op op, /**< number arithmetic operation */
|
||||
ecma_value_t left_value, /**< left value */
|
||||
ecma_value_t right_value) /**< right value */
|
||||
{
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (num_left, left_value, ret_value);
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (num_right, right_value, ret_value);
|
||||
|
||||
ecma_number_t result = ECMA_NUMBER_ZERO;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case NUMBER_ARITHMETIC_SUBSTRACTION:
|
||||
{
|
||||
result = ecma_number_substract (num_left, num_right);
|
||||
break;
|
||||
}
|
||||
case NUMBER_ARITHMETIC_MULTIPLICATION:
|
||||
{
|
||||
result = ecma_number_multiply (num_left, num_right);
|
||||
break;
|
||||
}
|
||||
case NUMBER_ARITHMETIC_DIVISION:
|
||||
{
|
||||
result = ecma_number_divide (num_left, num_right);
|
||||
break;
|
||||
}
|
||||
case NUMBER_ARITHMETIC_REMAINDER:
|
||||
{
|
||||
result = ecma_op_number_remainder (num_left, num_right);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret_value = ecma_make_number_value (result);
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (num_right);
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (num_left);
|
||||
|
||||
return ret_value;
|
||||
} /* do_number_arithmetic */
|
||||
|
||||
/**
|
||||
* 'Addition' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.6.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
opfunc_addition (ecma_value_t left_value, /**< left value */
|
||||
ecma_value_t right_value) /**< right value */
|
||||
{
|
||||
bool free_left_value = false;
|
||||
bool free_right_value = false;
|
||||
|
||||
if (ecma_is_value_object (left_value))
|
||||
{
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (left_value);
|
||||
left_value = ecma_op_object_default_value (obj_p, ECMA_PREFERRED_TYPE_NO);
|
||||
free_left_value = true;
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (left_value))
|
||||
{
|
||||
return left_value;
|
||||
}
|
||||
}
|
||||
|
||||
if (ecma_is_value_object (right_value))
|
||||
{
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (right_value);
|
||||
right_value = ecma_op_object_default_value (obj_p, ECMA_PREFERRED_TYPE_NO);
|
||||
free_right_value = true;
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (right_value))
|
||||
{
|
||||
if (free_left_value)
|
||||
{
|
||||
ecma_free_value (left_value);
|
||||
}
|
||||
return right_value;
|
||||
}
|
||||
}
|
||||
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
if (ecma_is_value_string (left_value)
|
||||
|| ecma_is_value_string (right_value))
|
||||
{
|
||||
ECMA_TRY_CATCH (str_left_value, ecma_op_to_string (left_value), ret_value);
|
||||
ECMA_TRY_CATCH (str_right_value, ecma_op_to_string (right_value), ret_value);
|
||||
|
||||
ecma_string_t *string1_p = ecma_get_string_from_value (str_left_value);
|
||||
ecma_string_t *string2_p = ecma_get_string_from_value (str_right_value);
|
||||
|
||||
ecma_string_t *concat_str_p = ecma_concat_ecma_strings (string1_p, string2_p);
|
||||
|
||||
ret_value = ecma_make_string_value (concat_str_p);
|
||||
|
||||
ECMA_FINALIZE (str_right_value);
|
||||
ECMA_FINALIZE (str_left_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (num_left, left_value, ret_value);
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (num_right, right_value, ret_value);
|
||||
|
||||
ret_value = ecma_make_number_value (ecma_number_add (num_left, num_right));
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (num_right);
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (num_left);
|
||||
}
|
||||
|
||||
if (free_left_value)
|
||||
{
|
||||
ecma_free_value (left_value);
|
||||
}
|
||||
|
||||
if (free_right_value)
|
||||
{
|
||||
ecma_free_value (right_value);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_addition */
|
||||
|
||||
/**
|
||||
* 'Unary "+"' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.4, 11.4.6
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
opfunc_unary_plus (ecma_value_t left_value) /**< left value */
|
||||
{
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (num_var_value,
|
||||
left_value,
|
||||
ret_value);
|
||||
|
||||
ret_value = ecma_make_number_value (num_var_value);
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (num_var_value);
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_unary_plus */
|
||||
|
||||
/**
|
||||
* 'Unary "-"' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.4, 11.4.7
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
opfunc_unary_minus (ecma_value_t left_value) /**< left value */
|
||||
{
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (num_var_value,
|
||||
left_value,
|
||||
ret_value);
|
||||
|
||||
ret_value = ecma_make_number_value (ecma_number_negate (num_var_value));
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (num_var_value);
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_unary_minus */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
157
third_party/jerryscript/jerry-core/vm/opcodes-ecma-bitwise.c
vendored
Normal file
157
third_party/jerryscript/jerry-core/vm/opcodes-ecma-bitwise.c
vendored
Normal file
|
@ -0,0 +1,157 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015-2016 University of Szeged.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-conversion.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
/** \addtogroup vm Virtual machine
|
||||
* @{
|
||||
*
|
||||
* \addtogroup vm_opcodes Opcodes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Perform ECMA number logic operation.
|
||||
*
|
||||
* The algorithm of the operation is following:
|
||||
* leftNum = ToNumber (leftValue);
|
||||
* rightNum = ToNumber (rightValue);
|
||||
* result = leftNum BitwiseLogicOp rightNum;
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
do_number_bitwise_logic (number_bitwise_logic_op op, /**< number bitwise logic operation */
|
||||
ecma_value_t left_value, /**< left value */
|
||||
ecma_value_t right_value) /**< right value */
|
||||
{
|
||||
JERRY_STATIC_ASSERT (ECMA_DIRECT_TYPE_INTEGER_VALUE == 0,
|
||||
ecma_direct_type_integer_value_must_be_zero_for_bitwise_logic);
|
||||
JERRY_STATIC_ASSERT ((ECMA_DIRECT_TYPE_MASK | ECMA_VALUE_ERROR_FLAG) == ((1 << ECMA_DIRECT_SHIFT) - 1),
|
||||
direct_type_mask_and_error_flag_must_fill_all_bits_before_the_value_starts);
|
||||
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
|
||||
&& !ECMA_IS_VALUE_ERROR (right_value));
|
||||
|
||||
if (ecma_are_values_integer_numbers (left_value, right_value))
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case NUMBER_BITWISE_LOGIC_AND:
|
||||
{
|
||||
return left_value & right_value;
|
||||
}
|
||||
case NUMBER_BITWISE_LOGIC_OR:
|
||||
{
|
||||
return left_value | right_value;
|
||||
}
|
||||
case NUMBER_BITWISE_LOGIC_XOR:
|
||||
{
|
||||
return (left_value ^ right_value) & (ecma_value_t) (~((1 << ECMA_DIRECT_SHIFT) - 1));
|
||||
}
|
||||
case NUMBER_BITWISE_SHIFT_LEFT:
|
||||
{
|
||||
ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value);
|
||||
ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value);
|
||||
return ecma_make_int32_value ((int32_t) (left_integer << (right_integer & 0x1f)));
|
||||
}
|
||||
case NUMBER_BITWISE_SHIFT_RIGHT:
|
||||
{
|
||||
ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value);
|
||||
ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value);
|
||||
return ecma_make_integer_value (left_integer >> (right_integer & 0x1f));
|
||||
}
|
||||
case NUMBER_BITWISE_SHIFT_URIGHT:
|
||||
{
|
||||
uint32_t left_uint32 = (uint32_t) ecma_get_integer_from_value (left_value);
|
||||
ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value);
|
||||
return ecma_make_uint32_value (left_uint32 >> (right_integer & 0x1f));
|
||||
}
|
||||
case NUMBER_BITWISE_NOT:
|
||||
{
|
||||
return (~right_value) & (ecma_value_t) (~((1 << ECMA_DIRECT_SHIFT) - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (num_left, left_value, ret_value);
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (num_right, right_value, ret_value);
|
||||
|
||||
ecma_number_t result = ECMA_NUMBER_ZERO;
|
||||
uint32_t right_uint32 = ecma_number_to_uint32 (num_right);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case NUMBER_BITWISE_LOGIC_AND:
|
||||
{
|
||||
uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
|
||||
result = (ecma_number_t) ((int32_t) (left_uint32 & right_uint32));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_LOGIC_OR:
|
||||
{
|
||||
uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
|
||||
result = (ecma_number_t) ((int32_t) (left_uint32 | right_uint32));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_LOGIC_XOR:
|
||||
{
|
||||
uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
|
||||
result = (ecma_number_t) ((int32_t) (left_uint32 ^ right_uint32));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_SHIFT_LEFT:
|
||||
{
|
||||
result = (ecma_number_t) (ecma_number_to_int32 (num_left) << (right_uint32 & 0x1F));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_SHIFT_RIGHT:
|
||||
{
|
||||
result = (ecma_number_t) (ecma_number_to_int32 (num_left) >> (right_uint32 & 0x1F));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_SHIFT_URIGHT:
|
||||
{
|
||||
uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
|
||||
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);
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (num_right);
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (num_left);
|
||||
|
||||
return ret_value;
|
||||
} /* do_number_bitwise_logic */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
91
third_party/jerryscript/jerry-core/vm/opcodes-ecma-equality.c
vendored
Normal file
91
third_party/jerryscript/jerry-core/vm/opcodes-ecma-equality.c
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015-2016 University of Szeged.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-comparison.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-function-object.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-lex-env.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "opcodes.h"
|
||||
#include "vm-defines.h"
|
||||
|
||||
/** \addtogroup vm Virtual machine
|
||||
* @{
|
||||
*
|
||||
* \addtogroup vm_opcodes Opcodes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* 'Equals' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.9.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
opfunc_equal_value (ecma_value_t left_value, /**< left value */
|
||||
ecma_value_t right_value) /**< right value */
|
||||
{
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
|
||||
&& !ECMA_IS_VALUE_ERROR (right_value));
|
||||
|
||||
ecma_value_t compare_result = ecma_op_abstract_equality_compare (left_value,
|
||||
right_value);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (compare_result)
|
||||
|| ECMA_IS_VALUE_ERROR (compare_result));
|
||||
|
||||
return compare_result;
|
||||
} /* opfunc_equal_value */
|
||||
|
||||
/**
|
||||
* 'Does-not-equals' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.9.2
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
opfunc_not_equal_value (ecma_value_t left_value, /**< left value */
|
||||
ecma_value_t right_value) /**< right value */
|
||||
{
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
|
||||
&& !ECMA_IS_VALUE_ERROR (right_value));
|
||||
|
||||
ecma_value_t compare_result = ecma_op_abstract_equality_compare (left_value,
|
||||
right_value);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (compare_result)
|
||||
|| ECMA_IS_VALUE_ERROR (compare_result));
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (compare_result))
|
||||
{
|
||||
compare_result = ecma_invert_boolean_value (compare_result);
|
||||
}
|
||||
|
||||
return compare_result;
|
||||
} /* opfunc_not_equal_value */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
249
third_party/jerryscript/jerry-core/vm/opcodes-ecma-relational.c
vendored
Normal file
249
third_party/jerryscript/jerry-core/vm/opcodes-ecma-relational.c
vendored
Normal file
|
@ -0,0 +1,249 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015-2016 University of Szeged.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ecma-comparison.h"
|
||||
#include "ecma-conversion.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
/** \addtogroup vm Virtual machine
|
||||
* @{
|
||||
*
|
||||
* \addtogroup vm_opcodes Opcodes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* 'Less-than' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.8.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
opfunc_less_than (ecma_value_t left_value, /**< left value */
|
||||
ecma_value_t right_value) /**< right value */
|
||||
{
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
|
||||
&& !ECMA_IS_VALUE_ERROR (right_value));
|
||||
|
||||
ecma_value_t ret_value = ecma_op_abstract_relational_compare (left_value, right_value, true);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
if (ecma_is_value_undefined (ret_value))
|
||||
{
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_boolean (ret_value));
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_less_than */
|
||||
|
||||
/**
|
||||
* 'Greater-than' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.8.2
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
opfunc_greater_than (ecma_value_t left_value, /**< left value */
|
||||
ecma_value_t right_value) /**< right value */
|
||||
{
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
|
||||
&& !ECMA_IS_VALUE_ERROR (right_value));
|
||||
|
||||
ecma_value_t ret_value = ecma_op_abstract_relational_compare (left_value, right_value, false);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
if (ecma_is_value_undefined (ret_value))
|
||||
{
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_boolean (ret_value));
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_greater_than */
|
||||
|
||||
/**
|
||||
* 'Less-than-or-equal' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.8.3
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
opfunc_less_or_equal_than (ecma_value_t left_value, /**< left value */
|
||||
ecma_value_t right_value) /**< right value */
|
||||
{
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
|
||||
&& !ECMA_IS_VALUE_ERROR (right_value));
|
||||
|
||||
ecma_value_t ret_value = ecma_op_abstract_relational_compare (left_value, right_value, false);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
if (ecma_is_value_undefined (ret_value))
|
||||
{
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_boolean (ret_value));
|
||||
|
||||
ret_value = ecma_invert_boolean_value (ret_value);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_less_or_equal_than */
|
||||
|
||||
/**
|
||||
* 'Greater-than-or-equal' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.8.4
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
opfunc_greater_or_equal_than (ecma_value_t left_value, /**< left value */
|
||||
ecma_value_t right_value) /**< right value */
|
||||
{
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
|
||||
&& !ECMA_IS_VALUE_ERROR (right_value));
|
||||
|
||||
ecma_value_t ret_value = ecma_op_abstract_relational_compare (left_value, right_value, true);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
if (ecma_is_value_undefined (ret_value))
|
||||
{
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_boolean (ret_value));
|
||||
|
||||
ret_value = ecma_invert_boolean_value (ret_value);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_greater_or_equal_than */
|
||||
|
||||
/**
|
||||
* 'instanceof' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.8.6
|
||||
*
|
||||
* @return ecma value
|
||||
* returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
ecma_value_t
|
||||
opfunc_instanceof (ecma_value_t left_value, /**< left value */
|
||||
ecma_value_t right_value) /**< right value */
|
||||
{
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
if (!ecma_is_value_object (right_value))
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_object_t *right_value_obj_p = ecma_get_object_from_value (right_value);
|
||||
|
||||
ECMA_TRY_CATCH (is_instance_of,
|
||||
ecma_op_object_has_instance (right_value_obj_p, left_value),
|
||||
ret_value);
|
||||
|
||||
ret_value = is_instance_of;
|
||||
|
||||
ECMA_FINALIZE (is_instance_of);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_instanceof */
|
||||
|
||||
/**
|
||||
* 'in' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.8.7
|
||||
*
|
||||
* @return ecma value
|
||||
* returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
ecma_value_t
|
||||
opfunc_in (ecma_value_t left_value, /**< left value */
|
||||
ecma_value_t right_value) /**< right value */
|
||||
{
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
if (!ecma_is_value_object (right_value))
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
ECMA_TRY_CATCH (str_left_value, ecma_op_to_string (left_value), ret_value);
|
||||
|
||||
ecma_string_t *left_value_prop_name_p = ecma_get_string_from_value (str_left_value);
|
||||
ecma_object_t *right_value_obj_p = ecma_get_object_from_value (right_value);
|
||||
|
||||
if (ecma_op_object_has_property (right_value_obj_p, left_value_prop_name_p))
|
||||
{
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (str_left_value);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_in */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
339
third_party/jerryscript/jerry-core/vm/opcodes.c
vendored
Normal file
339
third_party/jerryscript/jerry-core/vm/opcodes.c
vendored
Normal file
|
@ -0,0 +1,339 @@
|
|||
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015-2016 University of Szeged.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-conversion.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-function-object.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-lex-env.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "opcodes.h"
|
||||
#include "vm-defines.h"
|
||||
|
||||
/** \addtogroup vm Virtual machine
|
||||
* @{
|
||||
*
|
||||
* \addtogroup vm_opcodes Opcodes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* 'Variable declaration' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 10.5 - Declaration binding instantiation (block 8).
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value is simple and so need not be freed.
|
||||
* However, ecma_free_value may be called for it, but it is a no-op.
|
||||
*/
|
||||
ecma_value_t
|
||||
vm_var_decl (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context */
|
||||
ecma_string_t *var_name_str_p) /**< variable name */
|
||||
{
|
||||
if (!ecma_op_has_binding (frame_ctx_p->lex_env_p, var_name_str_p))
|
||||
{
|
||||
const bool is_configurable_bindings = frame_ctx_p->is_eval_code;
|
||||
|
||||
ecma_value_t completion_value = ecma_op_create_mutable_binding (frame_ctx_p->lex_env_p,
|
||||
var_name_str_p,
|
||||
is_configurable_bindings);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_empty (completion_value));
|
||||
|
||||
/* Skipping SetMutableBinding as we have already checked that there were not
|
||||
* any binding with specified name in current lexical environment
|
||||
* and CreateMutableBinding sets the created binding's value to undefined */
|
||||
JERRY_ASSERT (ecma_is_value_undefined (ecma_op_get_binding_value (frame_ctx_p->lex_env_p,
|
||||
var_name_str_p,
|
||||
true)));
|
||||
}
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
} /* vm_var_decl */
|
||||
|
||||
/**
|
||||
* 'Logical NOT Operator' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.4.9
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
opfunc_logical_not (ecma_value_t left_value) /**< left value */
|
||||
{
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
|
||||
if (ecma_op_to_boolean (left_value))
|
||||
{
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_logical_not */
|
||||
|
||||
/**
|
||||
* 'typeof' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.4.3
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
opfunc_typeof (ecma_value_t left_value) /**< left value */
|
||||
{
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ecma_string_t *type_str_p = NULL;
|
||||
|
||||
if (ecma_is_value_undefined (left_value))
|
||||
{
|
||||
type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_UNDEFINED);
|
||||
}
|
||||
else if (ecma_is_value_null (left_value))
|
||||
{
|
||||
type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_OBJECT);
|
||||
}
|
||||
else if (ecma_is_value_boolean (left_value))
|
||||
{
|
||||
type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_BOOLEAN);
|
||||
}
|
||||
else if (ecma_is_value_number (left_value))
|
||||
{
|
||||
type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_NUMBER);
|
||||
}
|
||||
else if (ecma_is_value_string (left_value))
|
||||
{
|
||||
type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_STRING);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_object (left_value));
|
||||
|
||||
if (ecma_op_is_callable (left_value))
|
||||
{
|
||||
type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_FUNCTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_OBJECT);
|
||||
}
|
||||
}
|
||||
|
||||
ret_value = ecma_make_string_value (type_str_p);
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_typeof */
|
||||
|
||||
/**
|
||||
* Update getter or setter for object literals.
|
||||
*/
|
||||
void
|
||||
opfunc_set_accessor (bool is_getter, /**< is getter accessor */
|
||||
ecma_value_t object, /**< object value */
|
||||
ecma_value_t accessor_name, /**< accessor name value */
|
||||
ecma_value_t accessor) /**< accessor value */
|
||||
{
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (object);
|
||||
JERRY_ASSERT (ecma_is_value_string (accessor_name) || ecma_is_value_number (accessor_name));
|
||||
ecma_string_t *accessor_name_p = ecma_get_string_from_value (ecma_op_to_string (accessor_name));
|
||||
ecma_property_t *property_p = ecma_find_named_property (object_p, accessor_name_p);
|
||||
|
||||
if (property_p != NULL
|
||||
&& ECMA_PROPERTY_GET_TYPE (*property_p) != ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
|
||||
{
|
||||
ecma_delete_property (object_p, ECMA_PROPERTY_VALUE_PTR (property_p));
|
||||
property_p = NULL;
|
||||
}
|
||||
|
||||
if (property_p == NULL)
|
||||
{
|
||||
ecma_object_t *getter_func_p = NULL;
|
||||
ecma_object_t *setter_func_p = NULL;
|
||||
|
||||
if (is_getter)
|
||||
{
|
||||
getter_func_p = ecma_get_object_from_value (accessor);
|
||||
}
|
||||
else
|
||||
{
|
||||
setter_func_p = ecma_get_object_from_value (accessor);
|
||||
}
|
||||
|
||||
ecma_create_named_accessor_property (object_p,
|
||||
accessor_name_p,
|
||||
getter_func_p,
|
||||
setter_func_p,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE);
|
||||
}
|
||||
else if (is_getter)
|
||||
{
|
||||
ecma_object_t *getter_func_p = ecma_get_object_from_value (accessor);
|
||||
|
||||
ecma_set_named_accessor_property_getter (object_p,
|
||||
ECMA_PROPERTY_VALUE_PTR (property_p),
|
||||
getter_func_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_object_t *setter_func_p = ecma_get_object_from_value (accessor);
|
||||
|
||||
ecma_set_named_accessor_property_setter (object_p,
|
||||
ECMA_PROPERTY_VALUE_PTR (property_p),
|
||||
setter_func_p);
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (accessor_name_p);
|
||||
} /* opfunc_set_accessor */
|
||||
|
||||
/**
|
||||
* Deletes an object property.
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
vm_op_delete_prop (ecma_value_t object, /**< base object */
|
||||
ecma_value_t property, /**< property name */
|
||||
bool is_strict) /**< strict mode */
|
||||
{
|
||||
ecma_value_t completion_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
if (ecma_is_value_undefined (object))
|
||||
{
|
||||
completion_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
completion_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ECMA_TRY_CATCH (check_coercible_ret,
|
||||
ecma_op_check_object_coercible (object),
|
||||
completion_value);
|
||||
ECMA_TRY_CATCH (str_name_value,
|
||||
ecma_op_to_string (property),
|
||||
completion_value);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_string (str_name_value));
|
||||
ecma_string_t *name_string_p = ecma_get_string_from_value (str_name_value);
|
||||
|
||||
ECMA_TRY_CATCH (obj_value, ecma_op_to_object (object), completion_value);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_object (obj_value));
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_value);
|
||||
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
|
||||
|
||||
ECMA_TRY_CATCH (delete_op_ret_val,
|
||||
ecma_op_object_delete (obj_p, name_string_p, is_strict),
|
||||
completion_value);
|
||||
|
||||
completion_value = delete_op_ret_val;
|
||||
|
||||
ECMA_FINALIZE (delete_op_ret_val);
|
||||
ECMA_FINALIZE (obj_value);
|
||||
ECMA_FINALIZE (str_name_value);
|
||||
ECMA_FINALIZE (check_coercible_ret);
|
||||
}
|
||||
|
||||
return completion_value;
|
||||
} /* vm_op_delete_prop */
|
||||
|
||||
/**
|
||||
* Deletes a variable.
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
vm_op_delete_var (jmem_cpointer_t name_literal, /**< name literal */
|
||||
ecma_object_t *lex_env_p) /**< lexical environment */
|
||||
{
|
||||
ecma_value_t completion_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ecma_string_t *var_name_str_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, name_literal);
|
||||
|
||||
ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (lex_env_p, var_name_str_p);
|
||||
|
||||
if (ref_base_lex_env_p == NULL)
|
||||
{
|
||||
completion_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_lexical_environment (ref_base_lex_env_p));
|
||||
|
||||
completion_value = ecma_op_delete_binding (ref_base_lex_env_p, var_name_str_p);
|
||||
}
|
||||
|
||||
return completion_value;
|
||||
} /* vm_op_delete_var */
|
||||
|
||||
/**
|
||||
* 'for-in' opcode handler
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 12.6.4
|
||||
*
|
||||
* @return completion value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_collection_header_t *
|
||||
opfunc_for_in (ecma_value_t left_value, /**< left value */
|
||||
ecma_value_t *result_obj_p) /**< expression object */
|
||||
{
|
||||
ecma_value_t compl_val = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
ecma_collection_header_t *prop_names_p = NULL;
|
||||
|
||||
/* 3. */
|
||||
if (!ecma_is_value_undefined (left_value)
|
||||
&& !ecma_is_value_null (left_value))
|
||||
{
|
||||
/* 4. */
|
||||
ECMA_TRY_CATCH (obj_expr_value,
|
||||
ecma_op_to_object (left_value),
|
||||
compl_val);
|
||||
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_expr_value);
|
||||
prop_names_p = ecma_op_object_get_property_names (obj_p, false, true, true);
|
||||
|
||||
if (prop_names_p->unit_number != 0)
|
||||
{
|
||||
ecma_ref_object (obj_p);
|
||||
*result_obj_p = ecma_make_object_value (obj_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_dealloc_collection_header (prop_names_p);
|
||||
prop_names_p = NULL;
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (obj_expr_value);
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_empty (compl_val));
|
||||
|
||||
return prop_names_p;
|
||||
} /* opfunc_for_in */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
120
third_party/jerryscript/jerry-core/vm/opcodes.h
vendored
Normal file
120
third_party/jerryscript/jerry-core/vm/opcodes.h
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015-2016 University of Szeged.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef OPCODES_H
|
||||
#define OPCODES_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
#include "vm-defines.h"
|
||||
|
||||
/** \addtogroup vm Virtual machine
|
||||
* @{
|
||||
*
|
||||
* \addtogroup vm_opcodes Opcodes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Number arithmetic operations.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NUMBER_ARITHMETIC_SUBSTRACTION, /**< substraction */
|
||||
NUMBER_ARITHMETIC_MULTIPLICATION, /**< multiplication */
|
||||
NUMBER_ARITHMETIC_DIVISION, /**< division */
|
||||
NUMBER_ARITHMETIC_REMAINDER, /**< remainder calculation */
|
||||
} number_arithmetic_op;
|
||||
|
||||
/**
|
||||
* Number bitwise logic operations.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NUMBER_BITWISE_LOGIC_AND, /**< bitwise AND calculation */
|
||||
NUMBER_BITWISE_LOGIC_OR, /**< bitwise OR calculation */
|
||||
NUMBER_BITWISE_LOGIC_XOR, /**< bitwise XOR calculation */
|
||||
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;
|
||||
|
||||
ecma_value_t
|
||||
vm_var_decl (vm_frame_ctx_t *, ecma_string_t *);
|
||||
|
||||
ecma_value_t
|
||||
opfunc_equal_value (ecma_value_t, ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
opfunc_not_equal_value (ecma_value_t, ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
do_number_arithmetic (number_arithmetic_op, ecma_value_t, ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
opfunc_unary_plus (ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
opfunc_unary_minus (ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
do_number_bitwise_logic (number_bitwise_logic_op, ecma_value_t, ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
opfunc_addition (ecma_value_t, ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
opfunc_less_than (ecma_value_t, ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
opfunc_greater_than (ecma_value_t, ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
opfunc_less_or_equal_than (ecma_value_t, ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
opfunc_greater_or_equal_than (ecma_value_t, ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
opfunc_in (ecma_value_t, ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
opfunc_instanceof (ecma_value_t, ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
opfunc_logical_not (ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
opfunc_typeof (ecma_value_t);
|
||||
|
||||
void
|
||||
opfunc_set_accessor (bool, ecma_value_t, ecma_value_t, ecma_value_t);
|
||||
|
||||
ecma_value_t
|
||||
vm_op_delete_prop (ecma_value_t, ecma_value_t, bool);
|
||||
|
||||
ecma_value_t
|
||||
vm_op_delete_var (jmem_cpointer_t, ecma_object_t *);
|
||||
|
||||
ecma_collection_header_t *
|
||||
opfunc_for_in (ecma_value_t, ecma_value_t *);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !OPCODES_H */
|
64
third_party/jerryscript/jerry-core/vm/vm-defines.h
vendored
Normal file
64
third_party/jerryscript/jerry-core/vm/vm-defines.h
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015-2016 University of Szeged.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef VM_DEFINES_H
|
||||
#define VM_DEFINES_H
|
||||
|
||||
#include "byte-code.h"
|
||||
#include "ecma-globals.h"
|
||||
|
||||
/** \addtogroup vm Virtual machine
|
||||
* @{
|
||||
*
|
||||
* \addtogroup vm_executor Executor
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Helpers for updating uint16_t values.
|
||||
*/
|
||||
#define VM_PLUS_EQUAL_U16(base, value) (base) = (uint16_t) ((base) + (value))
|
||||
#define VM_MINUS_EQUAL_U16(base, value) (base) = (uint16_t) ((base) - (value))
|
||||
|
||||
/**
|
||||
* Instruction counter / position
|
||||
*/
|
||||
typedef const uint8_t *vm_instr_counter_t;
|
||||
|
||||
/**
|
||||
* Context of interpreter, related to a JS stack frame
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const ecma_compiled_code_t *bytecode_header_p; /**< currently executed byte-code data */
|
||||
uint8_t *byte_code_p; /**< current byte code pointer */
|
||||
uint8_t *byte_code_start_p; /**< byte code start pointer */
|
||||
ecma_value_t *registers_p; /**< register start pointer */
|
||||
ecma_value_t *stack_top_p; /**< stack top pointer */
|
||||
jmem_cpointer_t *literal_start_p; /**< literal list start pointer */
|
||||
ecma_object_t *lex_env_p; /**< current lexical environment */
|
||||
ecma_value_t this_binding; /**< this binding */
|
||||
ecma_value_t call_block_result; /**< preserve block result during a call */
|
||||
uint16_t context_depth; /**< current context depth */
|
||||
uint8_t is_eval_code; /**< eval mode flag */
|
||||
uint8_t call_operation; /**< perform a call or construct operation */
|
||||
} vm_frame_ctx_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !VM_DEFINES_H */
|
256
third_party/jerryscript/jerry-core/vm/vm-stack.c
vendored
Normal file
256
third_party/jerryscript/jerry-core/vm/vm-stack.c
vendored
Normal file
|
@ -0,0 +1,256 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015-2016 University of Szeged.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "vm-defines.h"
|
||||
#include "vm-stack.h"
|
||||
|
||||
/** \addtogroup vm Virtual machine
|
||||
* @{
|
||||
*
|
||||
* \addtogroup stack VM stack
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abort (finalize) the current stack context, and remove it.
|
||||
*
|
||||
* @return new stack top
|
||||
*/
|
||||
ecma_value_t *
|
||||
vm_stack_context_abort (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
ecma_value_t *vm_stack_top_p) /**< current stack top */
|
||||
{
|
||||
switch (VM_GET_CONTEXT_TYPE (vm_stack_top_p[-1]))
|
||||
{
|
||||
case VM_CONTEXT_FINALLY_THROW:
|
||||
case VM_CONTEXT_FINALLY_RETURN:
|
||||
{
|
||||
ecma_free_value (vm_stack_top_p[-2]);
|
||||
|
||||
VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
|
||||
vm_stack_top_p -= PARSER_TRY_CONTEXT_STACK_ALLOCATION;
|
||||
break;
|
||||
}
|
||||
case VM_CONTEXT_FINALLY_JUMP:
|
||||
case VM_CONTEXT_TRY:
|
||||
{
|
||||
VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
|
||||
vm_stack_top_p -= PARSER_TRY_CONTEXT_STACK_ALLOCATION;
|
||||
break;
|
||||
}
|
||||
case VM_CONTEXT_CATCH:
|
||||
case VM_CONTEXT_WITH:
|
||||
{
|
||||
ecma_deref_object (frame_ctx_p->lex_env_p);
|
||||
frame_ctx_p->lex_env_p = ecma_get_object_from_value (vm_stack_top_p[-2]);
|
||||
|
||||
JERRY_ASSERT (PARSER_TRY_CONTEXT_STACK_ALLOCATION == PARSER_WITH_CONTEXT_STACK_ALLOCATION);
|
||||
|
||||
VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
|
||||
vm_stack_top_p -= PARSER_TRY_CONTEXT_STACK_ALLOCATION;
|
||||
break;
|
||||
}
|
||||
case VM_CONTEXT_FOR_IN:
|
||||
{
|
||||
jmem_cpointer_t current = (jmem_cpointer_t) vm_stack_top_p[-2];
|
||||
|
||||
while (current != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_collection_chunk_t *chunk_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
|
||||
current);
|
||||
|
||||
lit_utf8_byte_t *data_ptr = chunk_p->data;
|
||||
ecma_free_value (*(ecma_value_t *) data_ptr);
|
||||
|
||||
current = chunk_p->next_chunk_cp;
|
||||
ecma_dealloc_collection_chunk (chunk_p);
|
||||
}
|
||||
|
||||
ecma_free_value (vm_stack_top_p[-3]);
|
||||
|
||||
VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION);
|
||||
vm_stack_top_p -= PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return vm_stack_top_p;
|
||||
} /* vm_stack_context_abort */
|
||||
|
||||
/**
|
||||
* Decode branch offset.
|
||||
*
|
||||
* @return branch offset
|
||||
*/
|
||||
static uint32_t
|
||||
vm_decode_branch_offset (uint8_t *branch_offset_p, /**< start offset of byte code */
|
||||
uint32_t length) /**< length of the branch */
|
||||
{
|
||||
uint32_t branch_offset = *branch_offset_p;
|
||||
|
||||
JERRY_ASSERT (length >= 1 && length <= 3);
|
||||
|
||||
switch (length)
|
||||
{
|
||||
case 3:
|
||||
{
|
||||
branch_offset <<= 8;
|
||||
branch_offset |= *(branch_offset_p++);
|
||||
/* FALLTHRU */
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
branch_offset <<= 8;
|
||||
branch_offset |= *(branch_offset_p++);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return branch_offset;
|
||||
} /* vm_decode_branch_offset */
|
||||
|
||||
/**
|
||||
* Find a finally up to the end position.
|
||||
*
|
||||
* @return true if 'finally' found,
|
||||
* false otherwise
|
||||
*/
|
||||
bool
|
||||
vm_stack_find_finally (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
ecma_value_t **vm_stack_top_ref_p, /**< current stack top */
|
||||
vm_stack_context_type_t finally_type, /**< searching this finally */
|
||||
uint32_t search_limit) /**< search up-to this byte code */
|
||||
{
|
||||
ecma_value_t *vm_stack_top_p = *vm_stack_top_ref_p;
|
||||
|
||||
JERRY_ASSERT (finally_type <= VM_CONTEXT_FINALLY_RETURN);
|
||||
|
||||
if (finally_type != VM_CONTEXT_FINALLY_JUMP)
|
||||
{
|
||||
search_limit = 0xffffffffu;
|
||||
}
|
||||
|
||||
while (frame_ctx_p->context_depth > 0)
|
||||
{
|
||||
vm_stack_context_type_t context_type;
|
||||
uint32_t context_end = VM_GET_CONTEXT_END (vm_stack_top_p[-1]);
|
||||
|
||||
if (search_limit < context_end)
|
||||
{
|
||||
*vm_stack_top_ref_p = vm_stack_top_p;
|
||||
return false;
|
||||
}
|
||||
|
||||
context_type = VM_GET_CONTEXT_TYPE (vm_stack_top_p[-1]);
|
||||
if (context_type == VM_CONTEXT_TRY || context_type == VM_CONTEXT_CATCH)
|
||||
{
|
||||
uint8_t *byte_code_p;
|
||||
uint32_t branch_offset_length;
|
||||
uint32_t branch_offset;
|
||||
|
||||
if (search_limit == context_end)
|
||||
{
|
||||
*vm_stack_top_ref_p = vm_stack_top_p;
|
||||
return false;
|
||||
}
|
||||
|
||||
byte_code_p = frame_ctx_p->byte_code_start_p + VM_GET_CONTEXT_END (vm_stack_top_p[-1]);
|
||||
|
||||
if (context_type == VM_CONTEXT_TRY)
|
||||
{
|
||||
JERRY_ASSERT (byte_code_p[0] == CBC_EXT_OPCODE);
|
||||
|
||||
if (byte_code_p[1] >= CBC_EXT_CATCH
|
||||
&& byte_code_p[1] <= CBC_EXT_CATCH_3)
|
||||
{
|
||||
branch_offset_length = CBC_BRANCH_OFFSET_LENGTH (byte_code_p[1]);
|
||||
branch_offset = vm_decode_branch_offset (byte_code_p + 2,
|
||||
branch_offset_length);
|
||||
|
||||
if (finally_type == VM_CONTEXT_FINALLY_THROW)
|
||||
{
|
||||
branch_offset += (uint32_t) (byte_code_p - frame_ctx_p->byte_code_start_p);
|
||||
|
||||
vm_stack_top_p[-1] = VM_CREATE_CONTEXT (VM_CONTEXT_CATCH, branch_offset);
|
||||
|
||||
byte_code_p += 2 + branch_offset_length;
|
||||
frame_ctx_p->byte_code_p = byte_code_p;
|
||||
|
||||
*vm_stack_top_ref_p = vm_stack_top_p;
|
||||
return true;
|
||||
}
|
||||
|
||||
byte_code_p += branch_offset;
|
||||
|
||||
if (*byte_code_p == CBC_CONTEXT_END)
|
||||
{
|
||||
VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
|
||||
vm_stack_top_p -= PARSER_TRY_CONTEXT_STACK_ALLOCATION;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_deref_object (frame_ctx_p->lex_env_p);
|
||||
frame_ctx_p->lex_env_p = ecma_get_object_from_value (vm_stack_top_p[-2]);
|
||||
|
||||
if (byte_code_p[0] == CBC_CONTEXT_END)
|
||||
{
|
||||
VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
|
||||
vm_stack_top_p -= PARSER_TRY_CONTEXT_STACK_ALLOCATION;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
JERRY_ASSERT (byte_code_p[0] == CBC_EXT_OPCODE);
|
||||
JERRY_ASSERT (byte_code_p[1] >= CBC_EXT_FINALLY
|
||||
&& byte_code_p[1] <= CBC_EXT_FINALLY_3);
|
||||
|
||||
branch_offset_length = CBC_BRANCH_OFFSET_LENGTH (byte_code_p[1]);
|
||||
branch_offset = vm_decode_branch_offset (byte_code_p + 2,
|
||||
branch_offset_length);
|
||||
|
||||
branch_offset += (uint32_t) (byte_code_p - frame_ctx_p->byte_code_start_p);
|
||||
|
||||
vm_stack_top_p[-1] = VM_CREATE_CONTEXT ((uint32_t) finally_type, branch_offset);
|
||||
|
||||
byte_code_p += 2 + branch_offset_length;
|
||||
frame_ctx_p->byte_code_p = byte_code_p;
|
||||
|
||||
*vm_stack_top_ref_p = vm_stack_top_p;
|
||||
return true;
|
||||
}
|
||||
|
||||
vm_stack_top_p = vm_stack_context_abort (frame_ctx_p, vm_stack_top_p);
|
||||
}
|
||||
|
||||
*vm_stack_top_ref_p = vm_stack_top_p;
|
||||
return false;
|
||||
} /* vm_stack_find_finally */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
79
third_party/jerryscript/jerry-core/vm/vm-stack.h
vendored
Normal file
79
third_party/jerryscript/jerry-core/vm/vm-stack.h
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015-2016 University of Szeged.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef VM_STACK_H
|
||||
#define VM_STACK_H
|
||||
|
||||
#include "config.h"
|
||||
#include "ecma-globals.h"
|
||||
|
||||
/** \addtogroup vm Virtual machine
|
||||
* @{
|
||||
*
|
||||
* \addtogroup stack VM stack
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Number of ecma values inlined into stack frame
|
||||
*/
|
||||
#define VM_STACK_FRAME_INLINED_VALUES_NUMBER CONFIG_VM_STACK_FRAME_INLINED_VALUES_NUMBER
|
||||
|
||||
/**
|
||||
* Header of a ECMA stack frame's chunk
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t prev_chunk_p; /**< previous chunk of same frame */
|
||||
} vm_stack_chunk_header_t;
|
||||
|
||||
/**
|
||||
* ECMA stack frame
|
||||
*/
|
||||
typedef struct vm_stack_frame_t
|
||||
{
|
||||
struct vm_stack_frame_t *prev_frame_p; /**< previous frame */
|
||||
uint32_t regs_number; /**< number of register variables */
|
||||
} vm_stack_frame_t;
|
||||
|
||||
#define VM_CREATE_CONTEXT(type, end_offset) ((ecma_value_t) ((type) | (end_offset) << 4))
|
||||
#define VM_GET_CONTEXT_TYPE(value) ((vm_stack_context_type_t) ((value) & 0xf))
|
||||
#define VM_GET_CONTEXT_END(value) ((value) >> 4)
|
||||
|
||||
/**
|
||||
* Context types for the vm stack.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
VM_CONTEXT_FINALLY_JUMP, /**< finally context with a jump */
|
||||
VM_CONTEXT_FINALLY_THROW, /**< finally context with a throw */
|
||||
VM_CONTEXT_FINALLY_RETURN, /**< finally context with a return */
|
||||
VM_CONTEXT_TRY, /**< try context */
|
||||
VM_CONTEXT_CATCH, /**< catch context */
|
||||
VM_CONTEXT_WITH, /**< with context */
|
||||
VM_CONTEXT_FOR_IN, /**< for-in context */
|
||||
} vm_stack_context_type_t;
|
||||
|
||||
extern ecma_value_t *vm_stack_context_abort (vm_frame_ctx_t *, ecma_value_t *);
|
||||
extern bool vm_stack_find_finally (vm_frame_ctx_t *, ecma_value_t **,
|
||||
vm_stack_context_type_t, uint32_t);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !VM_STACK_H */
|
2755
third_party/jerryscript/jerry-core/vm/vm.c
vendored
Normal file
2755
third_party/jerryscript/jerry-core/vm/vm.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
293
third_party/jerryscript/jerry-core/vm/vm.h
vendored
Normal file
293
third_party/jerryscript/jerry-core/vm/vm.h
vendored
Normal file
|
@ -0,0 +1,293 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015-2016 University of Szeged.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef VM_H
|
||||
#define VM_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
#include "jrt.h"
|
||||
#include "vm-defines.h"
|
||||
|
||||
/** \addtogroup vm Virtual machine
|
||||
* @{
|
||||
*
|
||||
* \addtogroup vm_executor Executor
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Each CBC opcode is transformed to three vm opcodes:
|
||||
*
|
||||
* - first opcode is a "get arguments" opcode which specifies
|
||||
* the type (register, literal, stack, etc.) and number
|
||||
* (from 0 to 2) of input arguments
|
||||
* - second opcode is a "group" opcode which specifies
|
||||
* the actual operation (add, increment, call, etc.)
|
||||
* - third opcode is a "put result" opcode which specifies
|
||||
* the destination where the result is stored (register,
|
||||
* stack, etc.)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Branch argument is a backward branch
|
||||
*/
|
||||
#define VM_OC_BACKWARD_BRANCH 0x4000
|
||||
|
||||
/**
|
||||
* Position of "get arguments" opcode.
|
||||
*/
|
||||
#define VM_OC_GET_ARGS_SHIFT 7
|
||||
|
||||
/**
|
||||
* Mask of "get arguments" opcode.
|
||||
*/
|
||||
#define VM_OC_GET_ARGS_MASK 0x7
|
||||
|
||||
/**
|
||||
* Generate the binary representation of a "get arguments" opcode.
|
||||
*/
|
||||
#define VM_OC_GET_ARGS_CREATE_INDEX(V) (((V) & VM_OC_GET_ARGS_MASK) << VM_OC_GET_ARGS_SHIFT)
|
||||
|
||||
/**
|
||||
* Extract the "get arguments" opcode.
|
||||
*/
|
||||
#define VM_OC_GET_ARGS_INDEX(O) ((O) & (VM_OC_GET_ARGS_MASK << VM_OC_GET_ARGS_SHIFT))
|
||||
|
||||
/**
|
||||
* Checks whether the result is stored somewhere.
|
||||
*/
|
||||
#define VM_OC_HAS_GET_ARGS(V) ((V) & (VM_OC_GET_ARGS_MASK << VM_OC_GET_ARGS_SHIFT))
|
||||
|
||||
/**
|
||||
* Argument getters that are part of the opcodes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
VM_OC_GET_NONE = VM_OC_GET_ARGS_CREATE_INDEX (0), /**< do nothing */
|
||||
VM_OC_GET_BRANCH = VM_OC_GET_ARGS_CREATE_INDEX (1), /**< branch argument */
|
||||
VM_OC_GET_STACK = VM_OC_GET_ARGS_CREATE_INDEX (2), /**< pop one element from the stack */
|
||||
VM_OC_GET_STACK_STACK = VM_OC_GET_ARGS_CREATE_INDEX (3), /**< pop two elements from the stack */
|
||||
|
||||
VM_OC_GET_LITERAL = VM_OC_GET_ARGS_CREATE_INDEX (4), /**< resolve literal */
|
||||
VM_OC_GET_LITERAL_LITERAL = VM_OC_GET_ARGS_CREATE_INDEX (5), /**< resolve two literals */
|
||||
VM_OC_GET_STACK_LITERAL = VM_OC_GET_ARGS_CREATE_INDEX (6), /**< pop one element from the stack
|
||||
* and resolve a literal */
|
||||
VM_OC_GET_THIS_LITERAL = VM_OC_GET_ARGS_CREATE_INDEX (7), /**< get this and resolve a literal */
|
||||
} vm_oc_get_types;
|
||||
|
||||
/**
|
||||
* Mask of "group" opcode.
|
||||
*/
|
||||
#define VM_OC_GROUP_MASK 0x7f
|
||||
|
||||
/**
|
||||
* Extract the "group" opcode.
|
||||
*/
|
||||
#define VM_OC_GROUP_GET_INDEX(O) ((O) & VM_OC_GROUP_MASK)
|
||||
|
||||
/**
|
||||
* Opcodes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
VM_OC_NONE, /**< do nothing */
|
||||
VM_OC_POP, /**< pop from stack */
|
||||
VM_OC_POP_BLOCK, /**< pop block */
|
||||
VM_OC_PUSH, /**< push one element */
|
||||
VM_OC_PUSH_TWO, /**< push two elements onto the stack */
|
||||
VM_OC_PUSH_THREE, /**< push three elements onto the stack */
|
||||
VM_OC_PUSH_UNDEFINED, /**< push undefined value */
|
||||
VM_OC_PUSH_TRUE, /**< push true value */
|
||||
VM_OC_PUSH_FALSE, /**< push false value */
|
||||
VM_OC_PUSH_NULL, /**< push null value */
|
||||
VM_OC_PUSH_THIS, /**< push this */
|
||||
VM_OC_PUSH_NUMBER_0, /**< push number zero */
|
||||
VM_OC_PUSH_NUMBER_POS_BYTE, /**< push number between 1 and 256 */
|
||||
VM_OC_PUSH_NUMBER_NEG_BYTE, /**< push number between -1 and -256 */
|
||||
VM_OC_PUSH_OBJECT, /**< push object */
|
||||
VM_OC_SET_PROPERTY, /**< set property */
|
||||
VM_OC_SET_GETTER, /**< set getter */
|
||||
VM_OC_SET_SETTER, /**< set setter */
|
||||
VM_OC_PUSH_UNDEFINED_BASE, /**< push undefined base */
|
||||
VM_OC_PUSH_ARRAY, /**< push array */
|
||||
VM_OC_PUSH_ELISON, /**< push elison */
|
||||
VM_OC_APPEND_ARRAY, /**< append array */
|
||||
VM_OC_IDENT_REFERENCE, /**< ident reference */
|
||||
VM_OC_PROP_REFERENCE, /**< prop reference */
|
||||
VM_OC_PROP_GET, /**< prop get */
|
||||
|
||||
/* These eight opcodes must be in this order. */
|
||||
VM_OC_PROP_PRE_INCR, /**< prefix increment of a property */
|
||||
VM_OC_PROP_PRE_DECR, /**< prop prefix decrement of a property */
|
||||
VM_OC_PROP_POST_INCR, /**< prop postfix increment of a property */
|
||||
VM_OC_PROP_POST_DECR, /**< prop postfix decrement of a property */
|
||||
VM_OC_PRE_INCR, /**< prefix increment */
|
||||
VM_OC_PRE_DECR, /**< prefix decrement */
|
||||
VM_OC_POST_INCR, /**< postfix increment */
|
||||
VM_OC_POST_DECR, /**< postfix decrement */
|
||||
|
||||
VM_OC_PROP_DELETE, /**< delete property */
|
||||
VM_OC_DELETE, /**< delete */
|
||||
|
||||
VM_OC_ASSIGN, /**< assign */
|
||||
VM_OC_ASSIGN_PROP, /**< assign property */
|
||||
VM_OC_ASSIGN_PROP_THIS, /**< assign prop this */
|
||||
|
||||
VM_OC_RET, /**< return */
|
||||
VM_OC_THROW, /**< throw */
|
||||
VM_OC_THROW_REFERENCE_ERROR, /**< throw reference error */
|
||||
|
||||
VM_OC_EVAL, /**< eval */
|
||||
VM_OC_CALL, /**< call */
|
||||
VM_OC_NEW, /**< new */
|
||||
|
||||
VM_OC_JUMP, /**< jump */
|
||||
VM_OC_BRANCH_IF_STRICT_EQUAL, /**< branch if stric equal */
|
||||
|
||||
/* These four opcodes must be in this order. */
|
||||
VM_OC_BRANCH_IF_TRUE, /**< branch if true */
|
||||
VM_OC_BRANCH_IF_FALSE, /**< branch if false */
|
||||
VM_OC_BRANCH_IF_LOGICAL_TRUE, /**< branch if logical true */
|
||||
VM_OC_BRANCH_IF_LOGICAL_FALSE, /**< branch if logical false */
|
||||
|
||||
VM_OC_PLUS, /**< unary plus */
|
||||
VM_OC_MINUS, /**< unary minus */
|
||||
VM_OC_NOT, /**< not */
|
||||
VM_OC_BIT_NOT, /**< bitwise not */
|
||||
VM_OC_VOID, /**< void */
|
||||
VM_OC_TYPEOF_IDENT, /**< typeof identifier */
|
||||
VM_OC_TYPEOF, /**< typeof */
|
||||
|
||||
VM_OC_ADD, /**< binary add */
|
||||
VM_OC_SUB, /**< binary sub */
|
||||
VM_OC_MUL, /**< mul */
|
||||
VM_OC_DIV, /**< div */
|
||||
VM_OC_MOD, /**< mod */
|
||||
|
||||
VM_OC_EQUAL, /**< equal */
|
||||
VM_OC_NOT_EQUAL, /**< not equal */
|
||||
VM_OC_STRICT_EQUAL, /**< strict equal */
|
||||
VM_OC_STRICT_NOT_EQUAL, /**< strict not equal */
|
||||
VM_OC_LESS, /**< less */
|
||||
VM_OC_GREATER, /**< greater */
|
||||
VM_OC_LESS_EQUAL, /**< less equal */
|
||||
VM_OC_GREATER_EQUAL, /**< greater equal */
|
||||
VM_OC_IN, /**< in */
|
||||
VM_OC_INSTANCEOF, /**< instanceof */
|
||||
|
||||
VM_OC_BIT_OR, /**< bitwise or */
|
||||
VM_OC_BIT_XOR, /**< bitwise xor */
|
||||
VM_OC_BIT_AND, /**< bitwise and */
|
||||
VM_OC_LEFT_SHIFT, /**< left shift */
|
||||
VM_OC_RIGHT_SHIFT, /**< right shift */
|
||||
VM_OC_UNS_RIGHT_SHIFT, /**< unsigned right shift */
|
||||
|
||||
VM_OC_WITH, /**< with */
|
||||
VM_OC_FOR_IN_CREATE_CONTEXT, /**< for in create context */
|
||||
VM_OC_FOR_IN_GET_NEXT, /**< get next */
|
||||
VM_OC_FOR_IN_HAS_NEXT, /**< has next */
|
||||
VM_OC_TRY, /**< try */
|
||||
VM_OC_CATCH, /**< catch */
|
||||
VM_OC_FINALLY, /**< finally */
|
||||
VM_OC_CONTEXT_END, /**< context end */
|
||||
VM_OC_JUMP_AND_EXIT_CONTEXT, /**< jump and exit context */
|
||||
} vm_oc_types;
|
||||
|
||||
/**
|
||||
* Decrement operator.
|
||||
*/
|
||||
#define VM_OC_DECREMENT_OPERATOR_FLAG 0x1
|
||||
|
||||
/**
|
||||
* Postfix increment/decrement operator.
|
||||
*/
|
||||
#define VM_OC_POST_INCR_DECR_OPERATOR_FLAG 0x2
|
||||
|
||||
/**
|
||||
* An named variable is updated by the increment/decrement operator.
|
||||
*/
|
||||
#define VM_OC_IDENT_INCR_DECR_OPERATOR_FLAG 0x4
|
||||
|
||||
/**
|
||||
* Jump to target offset if input value is logical false.
|
||||
*/
|
||||
#define VM_OC_BRANCH_IF_FALSE_FLAG 0x1
|
||||
|
||||
/**
|
||||
* Branch optimized for logical and/or opcodes.
|
||||
*/
|
||||
#define VM_OC_LOGICAL_BRANCH_FLAG 0x2
|
||||
|
||||
/**
|
||||
* Position of "put result" opcode.
|
||||
*/
|
||||
#define VM_OC_PUT_RESULT_SHIFT 10
|
||||
|
||||
/**
|
||||
* Mask of "put result" opcode.
|
||||
*/
|
||||
#define VM_OC_PUT_RESULT_MASK 0xf
|
||||
|
||||
/**
|
||||
* Generate a "put result" opcode flag bit.
|
||||
*/
|
||||
#define VM_OC_PUT_RESULT_CREATE_FLAG(V) (((V) & VM_OC_PUT_RESULT_MASK) << VM_OC_PUT_RESULT_SHIFT)
|
||||
|
||||
/**
|
||||
* Checks whether the result is stored somewhere.
|
||||
*/
|
||||
#define VM_OC_HAS_PUT_RESULT(V) ((V) & (VM_OC_PUT_RESULT_MASK << VM_OC_PUT_RESULT_SHIFT))
|
||||
|
||||
/**
|
||||
* Specify where the result is stored
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
VM_OC_PUT_IDENT = VM_OC_PUT_RESULT_CREATE_FLAG (0x1),
|
||||
VM_OC_PUT_REFERENCE = VM_OC_PUT_RESULT_CREATE_FLAG (0x2),
|
||||
VM_OC_PUT_STACK = VM_OC_PUT_RESULT_CREATE_FLAG (0x4),
|
||||
VM_OC_PUT_BLOCK = VM_OC_PUT_RESULT_CREATE_FLAG (0x8),
|
||||
} vm_oc_put_types;
|
||||
|
||||
/**
|
||||
* Non-recursive vm_loop: the vm_loop can be suspended
|
||||
* to execute a call /construct operation. These return
|
||||
* types of the vm_loop tells whether a call operation
|
||||
* is in progress or the vm_loop is finished.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
VM_NO_EXEC_OP, /**< do nothing */
|
||||
VM_EXEC_CALL, /**< invoke a function */
|
||||
VM_EXEC_CONSTRUCT, /**< construct a new object */
|
||||
} vm_call_operation;
|
||||
|
||||
extern ecma_value_t vm_run_global (const ecma_compiled_code_t *);
|
||||
extern ecma_value_t vm_run_eval (ecma_compiled_code_t *, bool);
|
||||
|
||||
extern ecma_value_t vm_run (const ecma_compiled_code_t *, ecma_value_t,
|
||||
ecma_object_t *, bool, const ecma_value_t *,
|
||||
ecma_length_t);
|
||||
|
||||
extern bool vm_is_strict_mode (void);
|
||||
extern bool vm_is_direct_eval_form_call (void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !VM_H */
|
Loading…
Add table
Add a link
Reference in a new issue