mirror of
https://github.com/google/pebble.git
synced 2025-07-04 22:00:38 -04:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
456
third_party/jerryscript/jerry-core/ecma/operations/ecma-array-object.c
vendored
Normal file
456
third_party/jerryscript/jerry-core/ecma/operations/ecma-array-object.c
vendored
Normal file
|
@ -0,0 +1,456 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 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-array-object.h"
|
||||
#include "ecma-builtin-helpers.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-number-arithmetic.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmaarrayobject ECMA Array object related routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Array object creation operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.4.2.1
|
||||
* ECMA-262 v5, 15.4.2.2
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of arguments that
|
||||
are passed to Array constructor */
|
||||
ecma_length_t arguments_list_len, /**< length of the arguments' list */
|
||||
bool is_treat_single_arg_as_length) /**< if the value is true,
|
||||
arguments_list_len is 1
|
||||
and single argument is Number,
|
||||
then treat the single argument
|
||||
as new Array's length rather
|
||||
than as single item of the Array */
|
||||
{
|
||||
JERRY_ASSERT (arguments_list_len == 0
|
||||
|| arguments_list_p != NULL);
|
||||
|
||||
uint32_t length;
|
||||
const ecma_value_t *array_items_p;
|
||||
ecma_length_t array_items_count;
|
||||
|
||||
if (is_treat_single_arg_as_length
|
||||
&& arguments_list_len == 1
|
||||
&& ecma_is_value_number (arguments_list_p[0]))
|
||||
{
|
||||
ecma_number_t num = ecma_get_number_from_value (arguments_list_p[0]);
|
||||
uint32_t num_uint32 = ecma_number_to_uint32 (num);
|
||||
if (num != ((ecma_number_t) num_uint32))
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
length = num_uint32;
|
||||
array_items_p = NULL;
|
||||
array_items_count = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
length = arguments_list_len;
|
||||
array_items_p = arguments_list_p;
|
||||
array_items_count = arguments_list_len;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DISABLE_ARRAY_BUILTIN
|
||||
ecma_object_t *array_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_ARRAY_PROTOTYPE);
|
||||
#else /* CONFIG_DISABLE_ARRAY_BUILTIN */
|
||||
ecma_object_t *array_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
#endif /* !CONFIG_DISABLE_ARRAY_BUILTIN */
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (array_prototype_obj_p,
|
||||
false,
|
||||
true,
|
||||
ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
ecma_deref_object (array_prototype_obj_p);
|
||||
|
||||
/*
|
||||
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_ARRAY type.
|
||||
*
|
||||
* See also: ecma_object_get_class_name
|
||||
*/
|
||||
|
||||
ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string ();
|
||||
|
||||
ecma_property_value_t *length_prop_value_p;
|
||||
length_prop_value_p = ecma_create_named_data_property (obj_p,
|
||||
length_magic_string_p,
|
||||
ECMA_PROPERTY_FLAG_WRITABLE,
|
||||
NULL);
|
||||
|
||||
length_prop_value_p->value = ecma_make_number_value ((ecma_number_t) length);
|
||||
|
||||
ecma_deref_ecma_string (length_magic_string_p);
|
||||
|
||||
for (uint32_t index = 0;
|
||||
index < array_items_count;
|
||||
index++)
|
||||
{
|
||||
if (ecma_is_value_array_hole (array_items_p[index]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ecma_string_t *item_name_string_p = ecma_new_ecma_string_from_uint32 (index);
|
||||
|
||||
ecma_builtin_helper_def_prop (obj_p,
|
||||
item_name_string_p,
|
||||
array_items_p[index],
|
||||
true, /* Writable */
|
||||
true, /* Enumerable */
|
||||
true, /* Configurable */
|
||||
false); /* Failure handling */
|
||||
|
||||
ecma_deref_ecma_string (item_name_string_p);
|
||||
}
|
||||
|
||||
return ecma_make_object_value (obj_p);
|
||||
} /* ecma_op_create_array_object */
|
||||
|
||||
/**
|
||||
* [[DefineOwnProperty]] ecma array object's operation
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
|
||||
* ECMA-262 v5, 15.4.5.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array object */
|
||||
ecma_string_t *property_name_p, /**< property name */
|
||||
const ecma_property_descriptor_t *property_desc_p, /**< property descriptor */
|
||||
bool is_throw) /**< flag that controls failure handling */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
// 1.
|
||||
ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string ();
|
||||
ecma_property_t *len_prop_p = ecma_find_named_property (obj_p, magic_string_length_p);
|
||||
|
||||
JERRY_ASSERT (len_prop_p != NULL
|
||||
&& ECMA_PROPERTY_GET_TYPE (*len_prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
|
||||
|
||||
// 2.
|
||||
ecma_value_t old_len_value = ECMA_PROPERTY_VALUE_PTR (len_prop_p)->value;
|
||||
|
||||
uint32_t old_len_uint32 = ecma_get_uint32_from_value (old_len_value);
|
||||
|
||||
// 3.
|
||||
bool is_property_name_equal_length = ecma_compare_ecma_strings (property_name_p,
|
||||
magic_string_length_p);
|
||||
|
||||
ecma_deref_ecma_string (magic_string_length_p);
|
||||
|
||||
if (is_property_name_equal_length)
|
||||
{
|
||||
// a.
|
||||
if (!property_desc_p->is_value_defined)
|
||||
{
|
||||
// i.
|
||||
return ecma_op_general_object_define_own_property (obj_p, property_name_p, property_desc_p, is_throw);
|
||||
}
|
||||
|
||||
// c.
|
||||
ecma_value_t completion = ecma_op_to_number (property_desc_p->value);
|
||||
if (ECMA_IS_VALUE_ERROR (completion))
|
||||
{
|
||||
return completion;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (completion)
|
||||
&& ecma_is_value_number (completion));
|
||||
|
||||
ecma_number_t new_len_num = ecma_get_number_from_value (completion);
|
||||
|
||||
ecma_free_value (completion);
|
||||
|
||||
uint32_t new_len_uint32 = ecma_number_to_uint32 (new_len_num);
|
||||
|
||||
// d.
|
||||
if (ecma_is_value_object (property_desc_p->value))
|
||||
{
|
||||
ecma_value_t compared_num_val = ecma_op_to_number (property_desc_p->value);
|
||||
new_len_num = ecma_get_number_from_value (compared_num_val);
|
||||
ecma_free_value (compared_num_val);
|
||||
}
|
||||
|
||||
if (((ecma_number_t) new_len_uint32) != new_len_num)
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
// b., e.
|
||||
ecma_property_descriptor_t new_len_property_desc = *property_desc_p;
|
||||
new_len_property_desc.value = ecma_make_number_value (new_len_num);
|
||||
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
// f.
|
||||
if (new_len_uint32 >= old_len_uint32)
|
||||
{
|
||||
// i.
|
||||
magic_string_length_p = ecma_new_ecma_length_string ();
|
||||
ret_value = ecma_op_general_object_define_own_property (obj_p,
|
||||
magic_string_length_p,
|
||||
&new_len_property_desc,
|
||||
is_throw);
|
||||
ecma_deref_ecma_string (magic_string_length_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
// g.
|
||||
if (!ecma_is_property_writable (*len_prop_p))
|
||||
{
|
||||
ret_value = ecma_reject (is_throw);
|
||||
}
|
||||
else
|
||||
{
|
||||
// h.
|
||||
bool new_writable;
|
||||
if (!new_len_property_desc.is_writable_defined
|
||||
|| new_len_property_desc.is_writable)
|
||||
{
|
||||
new_writable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ii.
|
||||
new_writable = false;
|
||||
|
||||
// iii.
|
||||
new_len_property_desc.is_writable_defined = true;
|
||||
new_len_property_desc.is_writable = true;
|
||||
}
|
||||
|
||||
// j.
|
||||
magic_string_length_p = ecma_new_ecma_length_string ();
|
||||
ecma_value_t succeeded = ecma_op_general_object_define_own_property (obj_p,
|
||||
magic_string_length_p,
|
||||
&new_len_property_desc,
|
||||
is_throw);
|
||||
ecma_deref_ecma_string (magic_string_length_p);
|
||||
|
||||
/* Handling normal false and throw values */
|
||||
if (!ecma_is_value_true (succeeded))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_false (succeeded)
|
||||
|| ECMA_IS_VALUE_ERROR (succeeded));
|
||||
|
||||
// k.
|
||||
ret_value = succeeded;
|
||||
}
|
||||
else
|
||||
{
|
||||
// l
|
||||
JERRY_ASSERT (new_len_uint32 < old_len_uint32);
|
||||
|
||||
/*
|
||||
* Item i. is replaced with faster iteration: only indices that actually exist in the array, are iterated
|
||||
*/
|
||||
bool is_reduce_succeeded = true;
|
||||
|
||||
ecma_collection_header_t *array_index_props_p = ecma_op_object_get_property_names (obj_p,
|
||||
true,
|
||||
false,
|
||||
false);
|
||||
|
||||
ecma_length_t array_index_props_num = array_index_props_p->unit_number;
|
||||
|
||||
JMEM_DEFINE_LOCAL_ARRAY (array_index_values_p, array_index_props_num, uint32_t);
|
||||
|
||||
ecma_collection_iterator_t iter;
|
||||
ecma_collection_iterator_init (&iter, array_index_props_p);
|
||||
|
||||
uint32_t array_index_values_pos = 0;
|
||||
|
||||
while (ecma_collection_iterator_next (&iter))
|
||||
{
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
|
||||
|
||||
uint32_t index;
|
||||
bool is_index = ecma_string_get_array_index (property_name_p, &index);
|
||||
JERRY_ASSERT (is_index);
|
||||
JERRY_ASSERT (index < old_len_uint32);
|
||||
|
||||
array_index_values_p[array_index_values_pos++] = index;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (array_index_values_pos == array_index_props_num);
|
||||
|
||||
while (array_index_values_pos != 0
|
||||
&& array_index_values_p[--array_index_values_pos] >= new_len_uint32)
|
||||
{
|
||||
uint32_t index = array_index_values_p[array_index_values_pos];
|
||||
|
||||
// ii.
|
||||
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
|
||||
ecma_value_t delete_succeeded = ecma_op_object_delete (obj_p, index_string_p, false);
|
||||
ecma_deref_ecma_string (index_string_p);
|
||||
|
||||
if (ecma_is_value_false (delete_succeeded))
|
||||
{
|
||||
// iii.
|
||||
new_len_uint32 = (index + 1u);
|
||||
|
||||
// 1.
|
||||
ecma_number_t new_len_num = ((ecma_number_t) index + 1u);
|
||||
ecma_value_assign_number (&new_len_property_desc.value, new_len_num);
|
||||
|
||||
// 2.
|
||||
if (!new_writable)
|
||||
{
|
||||
new_len_property_desc.is_writable_defined = true;
|
||||
new_len_property_desc.is_writable = false;
|
||||
}
|
||||
|
||||
// 3.
|
||||
ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string ();
|
||||
ecma_value_t completion = ecma_op_general_object_define_own_property (obj_p,
|
||||
magic_string_length_p,
|
||||
&new_len_property_desc,
|
||||
false);
|
||||
ecma_deref_ecma_string (magic_string_length_p);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (completion));
|
||||
|
||||
is_reduce_succeeded = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
JMEM_FINALIZE_LOCAL_ARRAY (array_index_values_p);
|
||||
|
||||
ecma_free_values_collection (array_index_props_p, true);
|
||||
|
||||
if (!is_reduce_succeeded)
|
||||
{
|
||||
ret_value = ecma_reject (is_throw);
|
||||
}
|
||||
else
|
||||
{
|
||||
// m.
|
||||
if (!new_writable)
|
||||
{
|
||||
ecma_property_descriptor_t prop_desc_not_writable = ecma_make_empty_property_descriptor ();
|
||||
|
||||
prop_desc_not_writable.is_writable_defined = true;
|
||||
prop_desc_not_writable.is_writable = false;
|
||||
|
||||
ecma_value_t completion_set_not_writable;
|
||||
magic_string_length_p = ecma_new_ecma_length_string ();
|
||||
completion_set_not_writable = ecma_op_general_object_define_own_property (obj_p,
|
||||
magic_string_length_p,
|
||||
&prop_desc_not_writable,
|
||||
false);
|
||||
ecma_deref_ecma_string (magic_string_length_p);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion_set_not_writable));
|
||||
}
|
||||
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ecma_free_value (new_len_property_desc.value);
|
||||
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4.a.
|
||||
uint32_t index;
|
||||
|
||||
if (!ecma_string_get_array_index (property_name_p, &index))
|
||||
{
|
||||
// 5.
|
||||
return ecma_op_general_object_define_own_property (obj_p,
|
||||
property_name_p,
|
||||
property_desc_p,
|
||||
is_throw);
|
||||
}
|
||||
|
||||
// 4.
|
||||
|
||||
// b.
|
||||
if (index >= old_len_uint32
|
||||
&& !ecma_is_property_writable (*len_prop_p))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
|
||||
// c.
|
||||
ecma_value_t succeeded = ecma_op_general_object_define_own_property (obj_p,
|
||||
property_name_p,
|
||||
property_desc_p,
|
||||
false);
|
||||
// d.
|
||||
JERRY_ASSERT (ecma_is_value_boolean (succeeded));
|
||||
|
||||
if (ecma_is_value_false (succeeded))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
|
||||
// e.
|
||||
if (index < UINT32_MAX
|
||||
&& index >= old_len_uint32)
|
||||
{
|
||||
ecma_property_value_t *len_prop_value_p = ECMA_PROPERTY_VALUE_PTR (len_prop_p);
|
||||
|
||||
// i., ii.
|
||||
/* Setting the length property is always successful. */
|
||||
ecma_value_assign_uint32 (&len_prop_value_p->value, index + 1);
|
||||
}
|
||||
|
||||
// f.
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
}
|
||||
|
||||
JERRY_UNREACHABLE ();
|
||||
} /* ecma_op_array_object_define_own_property */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
39
third_party/jerryscript/jerry-core/ecma/operations/ecma-array-object.h
vendored
Normal file
39
third_party/jerryscript/jerry-core/ecma/operations/ecma-array-object.h
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_ARRAY_OBJECT_H
|
||||
#define ECMA_ARRAY_OBJECT_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmaarrayobject ECMA Array object related routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern ecma_value_t
|
||||
ecma_op_create_array_object (const ecma_value_t *, ecma_length_t, bool);
|
||||
|
||||
extern ecma_value_t
|
||||
ecma_op_array_object_define_own_property (ecma_object_t *, ecma_string_t *, const ecma_property_descriptor_t *, bool);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_ARRAY_OBJECT_H */
|
69
third_party/jerryscript/jerry-core/ecma/operations/ecma-boolean-object.c
vendored
Normal file
69
third_party/jerryscript/jerry-core/ecma/operations/ecma-boolean-object.c
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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-boolean-object.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmabooleanobject ECMA Boolean object related routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Boolean object creation operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.6.2.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_create_boolean_object (ecma_value_t arg) /**< argument passed to the Boolean constructor */
|
||||
{
|
||||
bool boolean_value = ecma_op_to_boolean (arg);
|
||||
|
||||
#ifndef CONFIG_DISABLE_BOOLEAN_BUILTIN
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE);
|
||||
#else /* CONFIG_DISABLE_BOOLEAN_BUILTIN */
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
#endif /* !CONFIG_DISABLE_BOOLEAN_BUILTIN */
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
|
||||
ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
*class_prop_p = LIT_MAGIC_STRING_BOOLEAN_UL;
|
||||
|
||||
ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
|
||||
|
||||
*prim_value_p = ecma_make_boolean_value (boolean_value);
|
||||
|
||||
return ecma_make_object_value (obj_p);
|
||||
} /* ecma_op_create_boolean_object */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
35
third_party/jerryscript/jerry-core/ecma/operations/ecma-boolean-object.h
vendored
Normal file
35
third_party/jerryscript/jerry-core/ecma/operations/ecma-boolean-object.h
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_BOOLEAN_OBJECT_H
|
||||
#define ECMA_BOOLEAN_OBJECT_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmabooleanobject ECMA Boolean object related routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern ecma_value_t ecma_op_create_boolean_object (ecma_value_t);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_BOOLEAN_OBJECT_H */
|
405
third_party/jerryscript/jerry-core/ecma/operations/ecma-comparison.c
vendored
Normal file
405
third_party/jerryscript/jerry-core/ecma/operations/ecma-comparison.c
vendored
Normal file
|
@ -0,0 +1,405 @@
|
|||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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-globals.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "jrt.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmacomparison ECMA comparison
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* ECMA abstract equality comparison routine.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.9.3
|
||||
*
|
||||
* @return true - if values are equal,
|
||||
* false - otherwise.
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_abstract_equality_compare (ecma_value_t x, /**< first operand */
|
||||
ecma_value_t y) /**< second operand */
|
||||
{
|
||||
if (x == y)
|
||||
{
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
}
|
||||
|
||||
if (ecma_are_values_integer_numbers (x, y))
|
||||
{
|
||||
/* Note: the (x == y) comparison captures the true case. */
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
}
|
||||
|
||||
if (ecma_is_value_number (x))
|
||||
{
|
||||
if (ecma_is_value_number (y))
|
||||
{
|
||||
// 1.c
|
||||
ecma_number_t x_num = ecma_get_number_from_value (x);
|
||||
ecma_number_t y_num = ecma_get_number_from_value (y);
|
||||
|
||||
bool is_x_equal_to_y = (x_num == y_num);
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
bool is_x_equal_to_y_check;
|
||||
|
||||
if (ecma_number_is_nan (x_num)
|
||||
|| ecma_number_is_nan (y_num))
|
||||
{
|
||||
is_x_equal_to_y_check = false;
|
||||
}
|
||||
else if (x_num == y_num
|
||||
|| (ecma_number_is_zero (x_num)
|
||||
&& ecma_number_is_zero (y_num)))
|
||||
{
|
||||
is_x_equal_to_y_check = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
is_x_equal_to_y_check = false;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (is_x_equal_to_y == is_x_equal_to_y_check);
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
return ecma_make_boolean_value (is_x_equal_to_y);
|
||||
}
|
||||
|
||||
/* Swap values. */
|
||||
ecma_value_t tmp = x;
|
||||
x = y;
|
||||
y = tmp;
|
||||
}
|
||||
|
||||
if (ecma_is_value_string (x))
|
||||
{
|
||||
if (ecma_is_value_string (y))
|
||||
{
|
||||
// 1., d.
|
||||
ecma_string_t *x_str_p = ecma_get_string_from_value (x);
|
||||
ecma_string_t *y_str_p = ecma_get_string_from_value (y);
|
||||
|
||||
bool is_equal = ecma_compare_ecma_strings (x_str_p, y_str_p);
|
||||
|
||||
return ecma_make_boolean_value (is_equal);
|
||||
}
|
||||
|
||||
if (ecma_is_value_number (y))
|
||||
{
|
||||
// 4.
|
||||
ecma_value_t x_num_value = ecma_op_to_number (x);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (x_num_value))
|
||||
{
|
||||
return x_num_value;
|
||||
}
|
||||
|
||||
ecma_value_t compare_result = ecma_op_abstract_equality_compare (x_num_value, y);
|
||||
|
||||
ecma_free_value (x_num_value);
|
||||
return compare_result;
|
||||
}
|
||||
|
||||
/* Swap values. */
|
||||
ecma_value_t tmp = x;
|
||||
x = y;
|
||||
y = tmp;
|
||||
}
|
||||
|
||||
if (ecma_is_value_boolean (y))
|
||||
{
|
||||
if (ecma_is_value_boolean (x))
|
||||
{
|
||||
// 1., e.
|
||||
/* Note: the (x == y) comparison captures the true case. */
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
}
|
||||
|
||||
// 7.
|
||||
return ecma_op_abstract_equality_compare (x, ecma_make_integer_value (ecma_is_value_true (y) ? 1 : 0));
|
||||
}
|
||||
|
||||
if (ecma_is_value_object (x))
|
||||
{
|
||||
if (ecma_is_value_string (y)
|
||||
|| ecma_is_value_number (y))
|
||||
{
|
||||
// 9.
|
||||
ecma_value_t x_prim_value = ecma_op_to_primitive (x, ECMA_PREFERRED_TYPE_NO);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (x_prim_value))
|
||||
{
|
||||
return x_prim_value;
|
||||
}
|
||||
|
||||
ecma_value_t compare_result = ecma_op_abstract_equality_compare (x_prim_value, y);
|
||||
|
||||
ecma_free_value (x_prim_value);
|
||||
return compare_result;
|
||||
}
|
||||
|
||||
// 1., f.
|
||||
/* Note: the (x == y) comparison captures the true case. */
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
}
|
||||
|
||||
if (ecma_is_value_boolean (x))
|
||||
{
|
||||
// 6.
|
||||
return ecma_op_abstract_equality_compare (ecma_make_integer_value (ecma_is_value_true (x) ? 1 : 0), y);
|
||||
}
|
||||
|
||||
if (ecma_is_value_undefined (x)
|
||||
|| ecma_is_value_null (x))
|
||||
{
|
||||
// 1. a., b.
|
||||
// 2., 3.
|
||||
bool is_equal = ecma_is_value_undefined (y) || ecma_is_value_null (y);
|
||||
|
||||
return ecma_make_boolean_value (is_equal);
|
||||
}
|
||||
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
} /* ecma_op_abstract_equality_compare */
|
||||
|
||||
/**
|
||||
* ECMA strict equality comparison routine.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.9.6
|
||||
*
|
||||
* @return true - if values are strict equal,
|
||||
* false - otherwise.
|
||||
*/
|
||||
bool
|
||||
ecma_op_strict_equality_compare (ecma_value_t x, /**< first operand */
|
||||
ecma_value_t y) /**< second operand */
|
||||
{
|
||||
if (ecma_is_value_direct (x)
|
||||
|| ecma_is_value_direct (y)
|
||||
|| ecma_is_value_object (x)
|
||||
|| ecma_is_value_object (y))
|
||||
{
|
||||
JERRY_ASSERT (!ecma_is_value_direct (x)
|
||||
|| ecma_is_value_undefined (x)
|
||||
|| ecma_is_value_null (x)
|
||||
|| ecma_is_value_boolean (x)
|
||||
|| ecma_is_value_integer_number (x));
|
||||
|
||||
JERRY_ASSERT (!ecma_is_value_direct (y)
|
||||
|| ecma_is_value_undefined (y)
|
||||
|| ecma_is_value_null (y)
|
||||
|| ecma_is_value_boolean (y)
|
||||
|| ecma_is_value_integer_number (y));
|
||||
|
||||
if ((x != ecma_make_integer_value (0) || !ecma_is_value_float_number (y))
|
||||
&& (y != ecma_make_integer_value (0) || !ecma_is_value_float_number (x)))
|
||||
{
|
||||
return (x == y);
|
||||
}
|
||||
|
||||
/* The +0 === -0 case handled below. */
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_number (x) || ecma_is_value_string (x));
|
||||
JERRY_ASSERT (ecma_is_value_number (y) || ecma_is_value_string (y));
|
||||
|
||||
if (ecma_is_value_string (x))
|
||||
{
|
||||
if (!ecma_is_value_string (y))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_string_t *x_str_p = ecma_get_string_from_value (x);
|
||||
ecma_string_t *y_str_p = ecma_get_string_from_value (y);
|
||||
|
||||
return ecma_compare_ecma_strings (x_str_p, y_str_p);
|
||||
}
|
||||
|
||||
if (!ecma_is_value_number (y))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_number_t x_num = ecma_get_number_from_value (x);
|
||||
ecma_number_t y_num = ecma_get_number_from_value (y);
|
||||
|
||||
bool is_x_equal_to_y = (x_num == y_num);
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
bool is_x_equal_to_y_check;
|
||||
|
||||
if (ecma_number_is_nan (x_num)
|
||||
|| ecma_number_is_nan (y_num))
|
||||
{
|
||||
is_x_equal_to_y_check = false;
|
||||
}
|
||||
else if (x_num == y_num
|
||||
|| (ecma_number_is_zero (x_num)
|
||||
&& ecma_number_is_zero (y_num)))
|
||||
{
|
||||
is_x_equal_to_y_check = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
is_x_equal_to_y_check = false;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (is_x_equal_to_y == is_x_equal_to_y_check);
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
return is_x_equal_to_y;
|
||||
} /* ecma_op_strict_equality_compare */
|
||||
|
||||
/**
|
||||
* ECMA abstract relational comparison routine.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.8.5
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_abstract_relational_compare (ecma_value_t x, /**< first operand */
|
||||
ecma_value_t y, /**< second operand */
|
||||
bool left_first) /**< 'LeftFirst' flag */
|
||||
{
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
// 1., 2.
|
||||
ECMA_TRY_CATCH (prim_first_converted_value,
|
||||
ecma_op_to_primitive (x, ECMA_PREFERRED_TYPE_NUMBER),
|
||||
ret_value);
|
||||
ECMA_TRY_CATCH (prim_second_converted_value,
|
||||
ecma_op_to_primitive (y, ECMA_PREFERRED_TYPE_NUMBER),
|
||||
ret_value);
|
||||
|
||||
const ecma_value_t px = left_first ? prim_first_converted_value : prim_second_converted_value;
|
||||
const ecma_value_t py = left_first ? prim_second_converted_value : prim_first_converted_value;
|
||||
|
||||
const bool is_px_string = ecma_is_value_string (px);
|
||||
const bool is_py_string = ecma_is_value_string (py);
|
||||
|
||||
if (!(is_px_string && is_py_string))
|
||||
{
|
||||
// 3.
|
||||
|
||||
// a.
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (nx, px, ret_value);
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (ny, py, ret_value);
|
||||
|
||||
// b.
|
||||
if (ecma_number_is_nan (nx)
|
||||
|| ecma_number_is_nan (ny))
|
||||
{
|
||||
// c., d.
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool is_x_less_than_y = (nx < ny);
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
bool is_x_less_than_y_check;
|
||||
|
||||
if (nx == ny
|
||||
|| (ecma_number_is_zero (nx)
|
||||
&& ecma_number_is_zero (ny)))
|
||||
{
|
||||
// e., f., g.
|
||||
is_x_less_than_y_check = false;
|
||||
}
|
||||
else if (ecma_number_is_infinity (nx)
|
||||
&& !ecma_number_is_negative (nx))
|
||||
{
|
||||
// h.
|
||||
is_x_less_than_y_check = false;
|
||||
}
|
||||
else if (ecma_number_is_infinity (ny)
|
||||
&& !ecma_number_is_negative (ny))
|
||||
{
|
||||
// i.
|
||||
is_x_less_than_y_check = true;
|
||||
}
|
||||
else if (ecma_number_is_infinity (ny)
|
||||
&& ecma_number_is_negative (ny))
|
||||
{
|
||||
// j.
|
||||
is_x_less_than_y_check = false;
|
||||
}
|
||||
else if (ecma_number_is_infinity (nx)
|
||||
&& ecma_number_is_negative (nx))
|
||||
{
|
||||
// k.
|
||||
is_x_less_than_y_check = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// l.
|
||||
JERRY_ASSERT (!ecma_number_is_nan (nx)
|
||||
&& !ecma_number_is_infinity (nx));
|
||||
JERRY_ASSERT (!ecma_number_is_nan (ny)
|
||||
&& !ecma_number_is_infinity (ny));
|
||||
JERRY_ASSERT (!(ecma_number_is_zero (nx)
|
||||
&& ecma_number_is_zero (ny)));
|
||||
|
||||
if (nx < ny)
|
||||
{
|
||||
is_x_less_than_y_check = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
is_x_less_than_y_check = false;
|
||||
}
|
||||
}
|
||||
|
||||
JERRY_ASSERT (is_x_less_than_y_check == is_x_less_than_y);
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
ret_value = ecma_make_boolean_value (is_x_less_than_y);
|
||||
}
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (ny);
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (nx);
|
||||
}
|
||||
else
|
||||
{ // 4.
|
||||
JERRY_ASSERT (is_px_string && is_py_string);
|
||||
|
||||
ecma_string_t *str_x_p = ecma_get_string_from_value (px);
|
||||
ecma_string_t *str_y_p = ecma_get_string_from_value (py);
|
||||
|
||||
bool is_px_less = ecma_compare_ecma_strings_relational (str_x_p, str_y_p);
|
||||
|
||||
ret_value = ecma_make_boolean_value (is_px_less);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (prim_second_converted_value);
|
||||
ECMA_FINALIZE (prim_first_converted_value);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_abstract_relational_compare */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
38
third_party/jerryscript/jerry-core/ecma/operations/ecma-comparison.h
vendored
Normal file
38
third_party/jerryscript/jerry-core/ecma/operations/ecma-comparison.h
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_COMPARISON_H
|
||||
#define ECMA_COMPARISON_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmacomparison ECMA comparison
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern ecma_value_t ecma_op_abstract_equality_compare (ecma_value_t, ecma_value_t);
|
||||
extern bool ecma_op_strict_equality_compare (ecma_value_t, ecma_value_t);
|
||||
extern ecma_value_t ecma_op_abstract_relational_compare (ecma_value_t, ecma_value_t, bool);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_COMPARISON_H */
|
786
third_party/jerryscript/jerry-core/ecma/operations/ecma-conversion.c
vendored
Normal file
786
third_party/jerryscript/jerry-core/ecma/operations/ecma-conversion.c
vendored
Normal file
|
@ -0,0 +1,786 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of ECMA-defined conversion routines
|
||||
*/
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-boolean-object.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-number-object.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-string-object.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "jrt-libc-includes.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmaconversion ECMA conversion routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* CheckObjectCoercible operation.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 9.10
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_check_object_coercible (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
ecma_check_value_type_is_spec_defined (value);
|
||||
|
||||
if (ecma_is_value_undefined (value)
|
||||
|| ecma_is_value_null (value))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
}
|
||||
} /* ecma_op_check_object_coercible */
|
||||
|
||||
/**
|
||||
* SameValue operation.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 9.12
|
||||
*
|
||||
* @return true - if the value are same according to ECMA-defined SameValue algorithm,
|
||||
* false - otherwise.
|
||||
*/
|
||||
bool
|
||||
ecma_op_same_value (ecma_value_t x, /**< ecma value */
|
||||
ecma_value_t y) /**< ecma value */
|
||||
{
|
||||
const bool is_x_undefined = ecma_is_value_undefined (x);
|
||||
const bool is_x_null = ecma_is_value_null (x);
|
||||
const bool is_x_boolean = ecma_is_value_boolean (x);
|
||||
const bool is_x_number = ecma_is_value_number (x);
|
||||
const bool is_x_string = ecma_is_value_string (x);
|
||||
const bool is_x_object = ecma_is_value_object (x);
|
||||
|
||||
const bool is_y_undefined = ecma_is_value_undefined (y);
|
||||
const bool is_y_null = ecma_is_value_null (y);
|
||||
const bool is_y_boolean = ecma_is_value_boolean (y);
|
||||
const bool is_y_number = ecma_is_value_number (y);
|
||||
const bool is_y_string = ecma_is_value_string (y);
|
||||
const bool is_y_object = ecma_is_value_object (y);
|
||||
|
||||
const bool is_types_equal = ((is_x_undefined && is_y_undefined)
|
||||
|| (is_x_null && is_y_null)
|
||||
|| (is_x_boolean && is_y_boolean)
|
||||
|| (is_x_number && is_y_number)
|
||||
|| (is_x_string && is_y_string)
|
||||
|| (is_x_object && is_y_object));
|
||||
|
||||
if (!is_types_equal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (is_x_undefined || is_x_null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (is_x_number)
|
||||
{
|
||||
ecma_number_t x_num = ecma_get_number_from_value (x);
|
||||
ecma_number_t y_num = ecma_get_number_from_value (y);
|
||||
|
||||
bool is_x_nan = ecma_number_is_nan (x_num);
|
||||
bool is_y_nan = ecma_number_is_nan (y_num);
|
||||
|
||||
if (is_x_nan || is_y_nan)
|
||||
{
|
||||
/*
|
||||
* If both are NaN
|
||||
* return true;
|
||||
* else
|
||||
* // one of the numbers is NaN, and another - is not
|
||||
* return false;
|
||||
*/
|
||||
return (is_x_nan && is_y_nan);
|
||||
}
|
||||
else if (ecma_number_is_zero (x_num)
|
||||
&& ecma_number_is_zero (y_num)
|
||||
&& ecma_number_is_negative (x_num) != ecma_number_is_negative (y_num))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (x_num == y_num);
|
||||
}
|
||||
}
|
||||
else if (is_x_string)
|
||||
{
|
||||
ecma_string_t *x_str_p = ecma_get_string_from_value (x);
|
||||
ecma_string_t *y_str_p = ecma_get_string_from_value (y);
|
||||
|
||||
return ecma_compare_ecma_strings (x_str_p, y_str_p);
|
||||
}
|
||||
else if (is_x_boolean)
|
||||
{
|
||||
return (ecma_is_value_true (x) == ecma_is_value_true (y));
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (is_x_object);
|
||||
|
||||
return (ecma_get_object_from_value (x) == ecma_get_object_from_value (y));
|
||||
}
|
||||
} /* ecma_op_same_value */
|
||||
|
||||
/**
|
||||
* ToPrimitive operation.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 9.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_to_primitive (ecma_value_t value, /**< ecma value */
|
||||
ecma_preferred_type_hint_t preferred_type) /**< preferred type hint */
|
||||
{
|
||||
ecma_check_value_type_is_spec_defined (value);
|
||||
|
||||
if (ecma_is_value_object (value))
|
||||
{
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (value);
|
||||
|
||||
return ecma_op_object_default_value (obj_p, preferred_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ecma_copy_value (value);
|
||||
}
|
||||
} /* ecma_op_to_primitive */
|
||||
|
||||
/**
|
||||
* ToBoolean operation. Cannot throw an exception.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 9.2
|
||||
*
|
||||
* @return true if the logical value is true
|
||||
* false otherwise
|
||||
*/
|
||||
bool
|
||||
ecma_op_to_boolean (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
ecma_check_value_type_is_spec_defined (value);
|
||||
|
||||
if (ecma_is_value_simple (value))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_boolean (value)
|
||||
|| ecma_is_value_undefined (value)
|
||||
|| ecma_is_value_null (value));
|
||||
|
||||
return ecma_is_value_true (value);
|
||||
}
|
||||
|
||||
if (ecma_is_value_integer_number (value))
|
||||
{
|
||||
return (value != ecma_make_integer_value (0));
|
||||
}
|
||||
|
||||
if (ecma_is_value_float_number (value))
|
||||
{
|
||||
ecma_number_t num = ecma_get_float_from_value (value);
|
||||
|
||||
return (!ecma_number_is_nan (num) && !ecma_number_is_zero (num));
|
||||
}
|
||||
|
||||
if (ecma_is_value_string (value))
|
||||
{
|
||||
ecma_string_t *str_p = ecma_get_string_from_value (value);
|
||||
|
||||
return !ecma_string_is_empty (str_p);
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_object (value));
|
||||
|
||||
return true;
|
||||
} /* ecma_op_to_boolean */
|
||||
|
||||
/**
|
||||
* ToNumber operation.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 9.3
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_to_number (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
ecma_check_value_type_is_spec_defined (value);
|
||||
|
||||
if (ecma_is_value_integer_number (value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
else if (ecma_is_value_float_number (value))
|
||||
{
|
||||
return ecma_copy_value (value);
|
||||
}
|
||||
else if (ecma_is_value_string (value))
|
||||
{
|
||||
ecma_string_t *str_p = ecma_get_string_from_value (value);
|
||||
return ecma_make_number_value (ecma_string_to_number (str_p));
|
||||
}
|
||||
else if (ecma_is_value_object (value))
|
||||
{
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ECMA_TRY_CATCH (primitive_value,
|
||||
ecma_op_to_primitive (value, ECMA_PREFERRED_TYPE_NUMBER),
|
||||
ret_value);
|
||||
|
||||
ret_value = ecma_op_to_number (primitive_value);
|
||||
|
||||
ECMA_FINALIZE (primitive_value);
|
||||
|
||||
return ret_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
int16_t num = 0;
|
||||
|
||||
if (ecma_is_value_undefined (value))
|
||||
{
|
||||
return ecma_make_nan_value ();
|
||||
}
|
||||
else if (ecma_is_value_null (value))
|
||||
{
|
||||
num = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_boolean (value));
|
||||
|
||||
if (ecma_is_value_true (value))
|
||||
{
|
||||
num = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ecma_make_integer_value (num);
|
||||
}
|
||||
} /* ecma_op_to_number */
|
||||
|
||||
/**
|
||||
* ToString operation.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 9.8
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_to_string (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
ecma_check_value_type_is_spec_defined (value);
|
||||
|
||||
if (unlikely (ecma_is_value_object (value)))
|
||||
{
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ECMA_TRY_CATCH (prim_value,
|
||||
ecma_op_to_primitive (value, ECMA_PREFERRED_TYPE_STRING),
|
||||
ret_value);
|
||||
|
||||
ret_value = ecma_op_to_string (prim_value);
|
||||
|
||||
ECMA_FINALIZE (prim_value);
|
||||
|
||||
return ret_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_string_t *res_p = NULL;
|
||||
|
||||
if (ecma_is_value_string (value))
|
||||
{
|
||||
res_p = ecma_get_string_from_value (value);
|
||||
ecma_ref_ecma_string (res_p);
|
||||
}
|
||||
else if (ecma_is_value_integer_number (value))
|
||||
{
|
||||
ecma_integer_value_t num = ecma_get_integer_from_value (value);
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
res_p = ecma_new_ecma_string_from_number ((ecma_number_t) num);
|
||||
}
|
||||
else
|
||||
{
|
||||
res_p = ecma_new_ecma_string_from_uint32 ((uint32_t) num);
|
||||
}
|
||||
}
|
||||
else if (ecma_is_value_float_number (value))
|
||||
{
|
||||
ecma_number_t num = ecma_get_float_from_value (value);
|
||||
res_p = ecma_new_ecma_string_from_number (num);
|
||||
}
|
||||
else if (ecma_is_value_undefined (value))
|
||||
{
|
||||
res_p = ecma_get_magic_string (LIT_MAGIC_STRING_UNDEFINED);
|
||||
}
|
||||
else if (ecma_is_value_null (value))
|
||||
{
|
||||
res_p = ecma_get_magic_string (LIT_MAGIC_STRING_NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_boolean (value));
|
||||
|
||||
if (ecma_is_value_true (value))
|
||||
{
|
||||
res_p = ecma_get_magic_string (LIT_MAGIC_STRING_TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
res_p = ecma_get_magic_string (LIT_MAGIC_STRING_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return ecma_make_string_value (res_p);
|
||||
}
|
||||
} /* ecma_op_to_string */
|
||||
|
||||
/**
|
||||
* ToObject operation.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 9.9
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_to_object (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
ecma_check_value_type_is_spec_defined (value);
|
||||
|
||||
if (ecma_is_value_number (value))
|
||||
{
|
||||
return ecma_op_create_number_object (value);
|
||||
}
|
||||
else if (ecma_is_value_string (value))
|
||||
{
|
||||
return ecma_op_create_string_object (&value, 1);
|
||||
}
|
||||
else if (ecma_is_value_object (value))
|
||||
{
|
||||
return ecma_copy_value (value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ecma_is_value_undefined (value)
|
||||
|| ecma_is_value_null (value))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_boolean (value));
|
||||
|
||||
return ecma_op_create_boolean_object (value);
|
||||
}
|
||||
}
|
||||
} /* ecma_op_to_object */
|
||||
|
||||
/**
|
||||
* FromPropertyDescriptor operation.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 8.10.4
|
||||
*
|
||||
* @return constructed object
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_op_from_property_descriptor (const ecma_property_descriptor_t *src_prop_desc_p) /**< property descriptor */
|
||||
{
|
||||
// 2.
|
||||
ecma_object_t *obj_p = ecma_op_create_object_object_noarg ();
|
||||
|
||||
ecma_value_t completion;
|
||||
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
|
||||
{
|
||||
prop_desc.is_value_defined = true;
|
||||
|
||||
prop_desc.is_writable_defined = true;
|
||||
prop_desc.is_writable = true;
|
||||
|
||||
prop_desc.is_enumerable_defined = true;
|
||||
prop_desc.is_enumerable = true;
|
||||
|
||||
prop_desc.is_configurable_defined = true;
|
||||
prop_desc.is_configurable = true;
|
||||
}
|
||||
|
||||
// 3.
|
||||
if (src_prop_desc_p->is_value_defined
|
||||
|| src_prop_desc_p->is_writable_defined)
|
||||
{
|
||||
JERRY_ASSERT (prop_desc.is_value_defined && prop_desc.is_writable_defined);
|
||||
|
||||
// a.
|
||||
prop_desc.value = src_prop_desc_p->value;
|
||||
|
||||
ecma_string_t *value_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_VALUE);
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
value_magic_string_p,
|
||||
&prop_desc,
|
||||
false);
|
||||
ecma_deref_ecma_string (value_magic_string_p);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
// b.
|
||||
const bool is_writable = (src_prop_desc_p->is_writable);
|
||||
prop_desc.value = ecma_make_boolean_value (is_writable);
|
||||
|
||||
ecma_string_t *writable_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_WRITABLE);
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
writable_magic_string_p,
|
||||
&prop_desc,
|
||||
false);
|
||||
ecma_deref_ecma_string (writable_magic_string_p);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4.
|
||||
JERRY_ASSERT (src_prop_desc_p->is_get_defined
|
||||
|| src_prop_desc_p->is_set_defined);
|
||||
|
||||
// a.
|
||||
if (src_prop_desc_p->get_p == NULL)
|
||||
{
|
||||
prop_desc.value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
}
|
||||
else
|
||||
{
|
||||
prop_desc.value = ecma_make_object_value (src_prop_desc_p->get_p);
|
||||
}
|
||||
|
||||
ecma_string_t *get_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GET);
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
get_magic_string_p,
|
||||
&prop_desc,
|
||||
false);
|
||||
ecma_deref_ecma_string (get_magic_string_p);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
// b.
|
||||
if (src_prop_desc_p->set_p == NULL)
|
||||
{
|
||||
prop_desc.value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
}
|
||||
else
|
||||
{
|
||||
prop_desc.value = ecma_make_object_value (src_prop_desc_p->set_p);
|
||||
}
|
||||
|
||||
ecma_string_t *set_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SET);
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
set_magic_string_p,
|
||||
&prop_desc,
|
||||
false);
|
||||
ecma_deref_ecma_string (set_magic_string_p);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
}
|
||||
|
||||
const bool is_enumerable = src_prop_desc_p->is_enumerable;
|
||||
prop_desc.value = ecma_make_boolean_value (is_enumerable);
|
||||
|
||||
ecma_string_t *enumerable_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ENUMERABLE);
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
enumerable_magic_string_p,
|
||||
&prop_desc,
|
||||
false);
|
||||
ecma_deref_ecma_string (enumerable_magic_string_p);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
const bool is_configurable = src_prop_desc_p->is_configurable;
|
||||
prop_desc.value = ecma_make_boolean_value (is_configurable);
|
||||
|
||||
ecma_string_t *configurable_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_CONFIGURABLE);
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
configurable_magic_string_p,
|
||||
&prop_desc,
|
||||
false);
|
||||
ecma_deref_ecma_string (configurable_magic_string_p);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
return obj_p;
|
||||
} /* ecma_op_from_property_descriptor */
|
||||
|
||||
/**
|
||||
* ToPropertyDescriptor operation.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 8.10.5
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */
|
||||
ecma_property_descriptor_t *out_prop_desc_p) /**< [out] filled property descriptor
|
||||
if return value is normal
|
||||
empty completion value */
|
||||
{
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
// 1.
|
||||
if (!ecma_is_value_object (obj_value))
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_value);
|
||||
|
||||
// 2.
|
||||
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
|
||||
|
||||
// 3.
|
||||
ecma_string_t *enumerable_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ENUMERABLE);
|
||||
|
||||
ECMA_TRY_CATCH (enumerable_prop_value,
|
||||
ecma_op_object_find (obj_p, enumerable_magic_string_p),
|
||||
ret_value);
|
||||
|
||||
if (ecma_is_value_found (enumerable_prop_value))
|
||||
{
|
||||
prop_desc.is_enumerable_defined = true;
|
||||
prop_desc.is_enumerable = ecma_op_to_boolean (enumerable_prop_value);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (enumerable_prop_value);
|
||||
|
||||
ecma_deref_ecma_string (enumerable_magic_string_p);
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_empty (ret_value));
|
||||
|
||||
// 4.
|
||||
ecma_string_t *configurable_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_CONFIGURABLE);
|
||||
|
||||
ECMA_TRY_CATCH (configurable_prop_value,
|
||||
ecma_op_object_find (obj_p, configurable_magic_string_p),
|
||||
ret_value);
|
||||
|
||||
if (ecma_is_value_found (configurable_prop_value))
|
||||
{
|
||||
prop_desc.is_configurable_defined = true;
|
||||
prop_desc.is_configurable = ecma_op_to_boolean (configurable_prop_value);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (configurable_prop_value);
|
||||
|
||||
ecma_deref_ecma_string (configurable_magic_string_p);
|
||||
}
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_empty (ret_value));
|
||||
|
||||
// 5.
|
||||
ecma_string_t *value_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_VALUE);
|
||||
|
||||
ECMA_TRY_CATCH (value_prop_value,
|
||||
ecma_op_object_find (obj_p, value_magic_string_p),
|
||||
ret_value);
|
||||
|
||||
if (ecma_is_value_found (value_prop_value))
|
||||
{
|
||||
prop_desc.is_value_defined = true;
|
||||
prop_desc.value = ecma_copy_value (value_prop_value);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (value_prop_value);
|
||||
|
||||
ecma_deref_ecma_string (value_magic_string_p);
|
||||
}
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_empty (ret_value));
|
||||
|
||||
// 6.
|
||||
ecma_string_t *writable_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_WRITABLE);
|
||||
|
||||
ECMA_TRY_CATCH (writable_prop_value,
|
||||
ecma_op_object_find (obj_p, writable_magic_string_p),
|
||||
ret_value);
|
||||
|
||||
if (ecma_is_value_found (writable_prop_value))
|
||||
{
|
||||
prop_desc.is_writable_defined = true;
|
||||
prop_desc.is_writable = ecma_op_to_boolean (writable_prop_value);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (writable_prop_value);
|
||||
|
||||
ecma_deref_ecma_string (writable_magic_string_p);
|
||||
}
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_empty (ret_value));
|
||||
|
||||
// 7.
|
||||
ecma_string_t *get_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GET);
|
||||
|
||||
ECMA_TRY_CATCH (get_prop_value,
|
||||
ecma_op_object_find (obj_p, get_magic_string_p),
|
||||
ret_value);
|
||||
|
||||
if (ecma_is_value_found (get_prop_value))
|
||||
{
|
||||
if (!ecma_op_is_callable (get_prop_value)
|
||||
&& !ecma_is_value_undefined (get_prop_value))
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
prop_desc.is_get_defined = true;
|
||||
|
||||
if (ecma_is_value_undefined (get_prop_value))
|
||||
{
|
||||
prop_desc.get_p = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_object (get_prop_value));
|
||||
|
||||
ecma_object_t *get_p = ecma_get_object_from_value (get_prop_value);
|
||||
ecma_ref_object (get_p);
|
||||
|
||||
prop_desc.get_p = get_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (get_prop_value);
|
||||
|
||||
ecma_deref_ecma_string (get_magic_string_p);
|
||||
}
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_empty (ret_value));
|
||||
|
||||
// 8.
|
||||
|
||||
ecma_string_t *set_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SET);
|
||||
|
||||
ECMA_TRY_CATCH (set_prop_value,
|
||||
ecma_op_object_find (obj_p, set_magic_string_p),
|
||||
ret_value);
|
||||
|
||||
if (ecma_is_value_found (set_prop_value))
|
||||
{
|
||||
if (!ecma_op_is_callable (set_prop_value)
|
||||
&& !ecma_is_value_undefined (set_prop_value))
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
prop_desc.is_set_defined = true;
|
||||
|
||||
if (ecma_is_value_undefined (set_prop_value))
|
||||
{
|
||||
prop_desc.set_p = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_object (set_prop_value));
|
||||
|
||||
ecma_object_t *set_p = ecma_get_object_from_value (set_prop_value);
|
||||
ecma_ref_object (set_p);
|
||||
|
||||
prop_desc.set_p = set_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (set_prop_value);
|
||||
|
||||
ecma_deref_ecma_string (set_magic_string_p);
|
||||
}
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_empty (ret_value));
|
||||
|
||||
// 9.
|
||||
if (prop_desc.is_get_defined
|
||||
|| prop_desc.is_set_defined)
|
||||
{
|
||||
if (prop_desc.is_value_defined
|
||||
|| prop_desc.is_writable_defined)
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_empty (ret_value));
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
}
|
||||
|
||||
*out_prop_desc_p = prop_desc;
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_to_property_descriptor */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
56
third_party/jerryscript/jerry-core/ecma/operations/ecma-conversion.h
vendored
Normal file
56
third_party/jerryscript/jerry-core/ecma/operations/ecma-conversion.h
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_CONVERSION_H
|
||||
#define ECMA_CONVERSION_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmaconversion ECMA conversion routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Second argument of 'ToPrimitive' operation that is a hint,
|
||||
* specifying the preferred type of conversion result.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_PREFERRED_TYPE_NO, /**< no preferred type is specified */
|
||||
ECMA_PREFERRED_TYPE_NUMBER, /**< Number */
|
||||
ECMA_PREFERRED_TYPE_STRING /**< String */
|
||||
} ecma_preferred_type_hint_t;
|
||||
|
||||
extern ecma_value_t ecma_op_check_object_coercible (ecma_value_t);
|
||||
extern bool ecma_op_same_value (ecma_value_t, ecma_value_t);
|
||||
extern ecma_value_t ecma_op_to_primitive (ecma_value_t, ecma_preferred_type_hint_t);
|
||||
extern bool ecma_op_to_boolean (ecma_value_t);
|
||||
extern ecma_value_t ecma_op_to_number (ecma_value_t);
|
||||
extern ecma_value_t ecma_op_to_string (ecma_value_t);
|
||||
extern ecma_value_t ecma_op_to_object (ecma_value_t);
|
||||
|
||||
extern ecma_object_t *ecma_op_from_property_descriptor (const ecma_property_descriptor_t *);
|
||||
extern ecma_value_t ecma_op_to_property_descriptor (ecma_value_t, ecma_property_descriptor_t *);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_CONVERSION_H */
|
112
third_party/jerryscript/jerry-core/ecma/operations/ecma-eval.c
vendored
Normal file
112
third_party/jerryscript/jerry-core/ecma/operations/ecma-eval.c
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 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-exceptions.h"
|
||||
#include "ecma-eval.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-lex-env.h"
|
||||
#include "js-parser.h"
|
||||
#include "vm.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup eval eval
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Perform 'eval' with code stored in ecma-string
|
||||
*
|
||||
* See also:
|
||||
* ecma_op_eval_chars_buffer
|
||||
* ECMA-262 v5, 15.1.2.1 (steps 2 to 8)
|
||||
*
|
||||
* @return ecma value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_eval (ecma_string_t *code_p, /**< code string */
|
||||
bool is_direct, /**< is eval called directly (ECMA-262 v5, 15.1.2.1.1) */
|
||||
bool is_called_from_strict_mode_code) /**< is eval is called from strict mode code */
|
||||
{
|
||||
ecma_value_t ret_value;
|
||||
|
||||
lit_utf8_size_t chars_num = ecma_string_get_size (code_p);
|
||||
if (chars_num == 0)
|
||||
{
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
}
|
||||
else
|
||||
{
|
||||
ECMA_STRING_TO_UTF8_STRING (code_p, code_utf8_buffer_p, code_utf8_buffer_size);
|
||||
|
||||
ret_value = ecma_op_eval_chars_buffer (code_utf8_buffer_p,
|
||||
chars_num,
|
||||
is_direct,
|
||||
is_called_from_strict_mode_code);
|
||||
|
||||
ECMA_FINALIZE_UTF8_STRING (code_utf8_buffer_p, code_utf8_buffer_size);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_eval */
|
||||
|
||||
/**
|
||||
* Perform 'eval' with code stored in continuous character buffer
|
||||
*
|
||||
* See also:
|
||||
* ecma_op_eval
|
||||
* ECMA-262 v5, 15.1.2.1 (steps 2 to 8)
|
||||
*
|
||||
* @return ecma value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_eval_chars_buffer (const lit_utf8_byte_t *code_p, /**< code characters buffer */
|
||||
size_t code_buffer_size, /**< size of the buffer */
|
||||
bool is_direct, /**< is eval called directly (ECMA-262 v5, 15.1.2.1.1) */
|
||||
bool is_called_from_strict_mode_code) /**< is eval is called from strict mode code */
|
||||
{
|
||||
JERRY_ASSERT (code_p != NULL);
|
||||
|
||||
ecma_compiled_code_t *bytecode_data_p;
|
||||
|
||||
bool is_strict_call = (is_direct && is_called_from_strict_mode_code);
|
||||
|
||||
// uncomment these log lines to get a way to measure timing
|
||||
// jerry_port_logmsg(NULL, "before parse");
|
||||
ecma_value_t parse_status = parser_parse_script (code_p,
|
||||
code_buffer_size,
|
||||
is_strict_call,
|
||||
&bytecode_data_p);
|
||||
// jerry_port_logmsg(NULL, "after parse");
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (parse_status))
|
||||
{
|
||||
return parse_status;
|
||||
}
|
||||
|
||||
ecma_value_t result = vm_run_eval (bytecode_data_p, is_direct);
|
||||
// jerry_port_logmsg(NULL, "after eval");
|
||||
return result;
|
||||
} /* ecma_op_eval_chars_buffer */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
40
third_party/jerryscript/jerry-core/ecma/operations/ecma-eval.h
vendored
Normal file
40
third_party/jerryscript/jerry-core/ecma/operations/ecma-eval.h
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 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 ECMA_EVAL_H
|
||||
#define ECMA_EVAL_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup eval eval
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern ecma_value_t
|
||||
ecma_op_eval (ecma_string_t *, bool, bool);
|
||||
|
||||
extern ecma_value_t
|
||||
ecma_op_eval_chars_buffer (const lit_utf8_byte_t *, size_t, bool, bool);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_EVAL_H */
|
261
third_party/jerryscript/jerry-core/ecma/operations/ecma-exceptions.c
vendored
Normal file
261
third_party/jerryscript/jerry-core/ecma/operations/ecma-exceptions.c
vendored
Normal file
|
@ -0,0 +1,261 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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-exceptions.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "jrt.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup exceptions Exceptions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Standard ecma-error object constructor.
|
||||
*
|
||||
* @return pointer to ecma-object representing specified error
|
||||
* with reference counter set to one.
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_new_standard_error (ecma_standard_error_t error_type) /**< native error type */
|
||||
{
|
||||
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
|
||||
ecma_builtin_id_t prototype_id = ECMA_BUILTIN_ID__COUNT;
|
||||
|
||||
switch (error_type)
|
||||
{
|
||||
case ECMA_ERROR_COMMON:
|
||||
{
|
||||
prototype_id = ECMA_BUILTIN_ID_ERROR_PROTOTYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
case ECMA_ERROR_EVAL:
|
||||
{
|
||||
prototype_id = ECMA_BUILTIN_ID_EVAL_ERROR_PROTOTYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
case ECMA_ERROR_RANGE:
|
||||
{
|
||||
prototype_id = ECMA_BUILTIN_ID_RANGE_ERROR_PROTOTYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
case ECMA_ERROR_REFERENCE:
|
||||
{
|
||||
prototype_id = ECMA_BUILTIN_ID_REFERENCE_ERROR_PROTOTYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
case ECMA_ERROR_TYPE:
|
||||
{
|
||||
prototype_id = ECMA_BUILTIN_ID_TYPE_ERROR_PROTOTYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
case ECMA_ERROR_URI:
|
||||
{
|
||||
prototype_id = ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
case ECMA_ERROR_SYNTAX:
|
||||
{
|
||||
prototype_id = ECMA_BUILTIN_ID_SYNTAX_ERROR_PROTOTYPE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
JERRY_UNUSED (error_type);
|
||||
ecma_builtin_id_t prototype_id = ECMA_BUILTIN_ID_ERROR_PROTOTYPE;
|
||||
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */
|
||||
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (prototype_id);
|
||||
|
||||
ecma_object_t *new_error_obj_p = ecma_create_object (prototype_obj_p,
|
||||
false,
|
||||
true,
|
||||
ECMA_OBJECT_TYPE_GENERAL);
|
||||
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
|
||||
ecma_value_t *class_prop_p = ecma_create_internal_property (new_error_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
*class_prop_p = LIT_MAGIC_STRING_ERROR_UL;
|
||||
|
||||
return new_error_obj_p;
|
||||
} /* ecma_new_standard_error */
|
||||
|
||||
/**
|
||||
* Standard ecma-error object constructor.
|
||||
*
|
||||
* @return pointer to ecma-object representing specified error
|
||||
* with reference counter set to one.
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_new_standard_error_with_message (ecma_standard_error_t error_type, /**< native error type */
|
||||
ecma_string_t *message_string_p) /**< message string */
|
||||
{
|
||||
ecma_object_t *new_error_obj_p = ecma_new_standard_error (error_type);
|
||||
|
||||
ecma_string_t *message_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MESSAGE);
|
||||
|
||||
ecma_property_value_t *prop_value_p;
|
||||
prop_value_p = ecma_create_named_data_property (new_error_obj_p,
|
||||
message_magic_string_p,
|
||||
ECMA_PROPERTY_CONFIGURABLE_WRITABLE,
|
||||
NULL);
|
||||
ecma_deref_ecma_string (message_magic_string_p);
|
||||
|
||||
ecma_ref_ecma_string (message_string_p);
|
||||
prop_value_p->value = ecma_make_string_value (message_string_p);
|
||||
|
||||
return new_error_obj_p;
|
||||
} /* ecma_new_standard_error_with_message */
|
||||
|
||||
/**
|
||||
* Raise a standard ecma-error with the given type and message.
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_raise_standard_error (ecma_standard_error_t error_type, /**< error type */
|
||||
const lit_utf8_byte_t *msg_p) /**< error message */
|
||||
{
|
||||
ecma_object_t *error_obj_p;
|
||||
|
||||
if (msg_p != NULL)
|
||||
{
|
||||
ecma_string_t *error_msg_p = ecma_new_ecma_string_from_utf8 (msg_p,
|
||||
lit_zt_utf8_string_size (msg_p));
|
||||
error_obj_p = ecma_new_standard_error_with_message (error_type, error_msg_p);
|
||||
ecma_deref_ecma_string (error_msg_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
error_obj_p = ecma_new_standard_error (error_type);
|
||||
}
|
||||
|
||||
return ecma_make_error_obj_value (error_obj_p);
|
||||
} /* ecma_raise_standard_error */
|
||||
|
||||
/**
|
||||
* Raise a common error with the given message.
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_raise_common_error (const char *msg_p) /**< error message */
|
||||
{
|
||||
return ecma_raise_standard_error (ECMA_ERROR_COMMON, (const lit_utf8_byte_t *) msg_p);
|
||||
} /* ecma_raise_common_error */
|
||||
|
||||
/**
|
||||
* Raise an EvalError with the given message.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.11.6.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_raise_eval_error (const char *msg_p) /**< error message */
|
||||
{
|
||||
return ecma_raise_standard_error (ECMA_ERROR_EVAL, (const lit_utf8_byte_t *) msg_p);
|
||||
} /* ecma_raise_eval_error */
|
||||
|
||||
/**
|
||||
* Raise a RangeError with the given message.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.11.6.2
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_raise_range_error (const char *msg_p) /**< error message */
|
||||
{
|
||||
return ecma_raise_standard_error (ECMA_ERROR_RANGE, (const lit_utf8_byte_t *) msg_p);
|
||||
} /* ecma_raise_range_error */
|
||||
|
||||
/**
|
||||
* Raise a ReferenceError with the given message.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.11.6.3
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_raise_reference_error (const char *msg_p) /**< error message */
|
||||
{
|
||||
return ecma_raise_standard_error (ECMA_ERROR_REFERENCE, (const lit_utf8_byte_t *) msg_p);
|
||||
} /* ecma_raise_reference_error */
|
||||
|
||||
/**
|
||||
* Raise a SyntaxError with the given message.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.11.6.4
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_raise_syntax_error (const char *msg_p) /**< error message */
|
||||
{
|
||||
return ecma_raise_standard_error (ECMA_ERROR_SYNTAX, (const lit_utf8_byte_t *) msg_p);
|
||||
} /* ecma_raise_syntax_error */
|
||||
|
||||
/**
|
||||
* Raise a TypeError with the given message.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.11.6.5
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_raise_type_error (const char *msg_p) /**< error message */
|
||||
{
|
||||
return ecma_raise_standard_error (ECMA_ERROR_TYPE, (const lit_utf8_byte_t *) msg_p);
|
||||
} /* ecma_raise_type_error */
|
||||
|
||||
/**
|
||||
* Raise a URIError with the given message.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.11.6.6
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_raise_uri_error (const char *msg_p) /**< error message */
|
||||
{
|
||||
return ecma_raise_standard_error (ECMA_ERROR_URI, (const lit_utf8_byte_t *) msg_p);
|
||||
} /* ecma_raise_uri_error */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
67
third_party/jerryscript/jerry-core/ecma/operations/ecma-exceptions.h
vendored
Normal file
67
third_party/jerryscript/jerry-core/ecma/operations/ecma-exceptions.h
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_EXCEPTIONS_H
|
||||
#define ECMA_EXCEPTIONS_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
#include "jrt.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup exceptions Exceptions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef JERRY_ENABLE_ERROR_MESSAGES
|
||||
#define ECMA_ERR_MSG(msg) msg
|
||||
#else /* !JERRY_ENABLE_ERROR_MESSAGES */
|
||||
#define ECMA_ERR_MSG(msg) NULL
|
||||
#endif /* JERRY_ENABLE_ERROR_MESSAGES */
|
||||
|
||||
/**
|
||||
* Native errors.
|
||||
*
|
||||
* See also: 15.11.1, 15.11.6
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_ERROR_COMMON, /**< Error */
|
||||
ECMA_ERROR_EVAL, /**< EvalError */
|
||||
ECMA_ERROR_RANGE, /**< RangeError */
|
||||
ECMA_ERROR_REFERENCE, /**< ReferenceError */
|
||||
ECMA_ERROR_SYNTAX, /**< SyntaxError */
|
||||
ECMA_ERROR_TYPE, /**< TypeError */
|
||||
ECMA_ERROR_URI /**< URIError */
|
||||
} ecma_standard_error_t;
|
||||
|
||||
extern ecma_object_t *ecma_new_standard_error (ecma_standard_error_t);
|
||||
extern ecma_object_t *ecma_new_standard_error_with_message (ecma_standard_error_t, ecma_string_t *);
|
||||
extern ecma_value_t ecma_raise_standard_error (ecma_standard_error_t, const lit_utf8_byte_t *);
|
||||
extern ecma_value_t ecma_raise_common_error (const char *);
|
||||
extern ecma_value_t ecma_raise_eval_error (const char *);
|
||||
extern ecma_value_t ecma_raise_range_error (const char *);
|
||||
extern ecma_value_t ecma_raise_reference_error (const char *);
|
||||
extern ecma_value_t ecma_raise_syntax_error (const char *);
|
||||
extern ecma_value_t ecma_raise_type_error (const char *);
|
||||
extern ecma_value_t ecma_raise_uri_error (const char *);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_EXCEPTIONS_H */
|
839
third_party/jerryscript/jerry-core/ecma/operations/ecma-function-object.c
vendored
Normal file
839
third_party/jerryscript/jerry-core/ecma/operations/ecma-function-object.c
vendored
Normal file
|
@ -0,0 +1,839 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 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-builtin-helpers.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-function-object.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-lex-env.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-objects-arguments.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "jcontext.h"
|
||||
|
||||
#define JERRY_INTERNAL
|
||||
#include "jerry-internal.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmafunctionobject ECMA Function object related routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* IsCallable operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 9.11
|
||||
*
|
||||
* @return true, if value is callable object;
|
||||
* false - otherwise.
|
||||
*/
|
||||
bool
|
||||
ecma_op_is_callable (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
if (!ecma_is_value_object (value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (value);
|
||||
|
||||
JERRY_ASSERT (obj_p != NULL);
|
||||
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
|
||||
|
||||
return (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION
|
||||
|| ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION
|
||||
|| ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
|
||||
} /* ecma_op_is_callable */
|
||||
|
||||
/**
|
||||
* Check whether the value is Object that implements [[Construct]].
|
||||
*
|
||||
* @return true, if value is constructor object;
|
||||
* false - otherwise.
|
||||
*/
|
||||
bool
|
||||
ecma_is_constructor (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
if (!ecma_is_value_object (value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (value);
|
||||
|
||||
JERRY_ASSERT (obj_p != NULL);
|
||||
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
|
||||
|
||||
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION)
|
||||
{
|
||||
return (!ecma_get_object_is_builtin (obj_p)
|
||||
|| !ecma_builtin_function_is_routine (obj_p));
|
||||
}
|
||||
|
||||
return (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION
|
||||
|| ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
|
||||
} /* ecma_is_constructor */
|
||||
|
||||
/**
|
||||
* Helper function to merge argument lists
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 15.3.4.5.1 step 4
|
||||
* ECMA-262 v5, 15.3.4.5.2 step 4
|
||||
*
|
||||
* Used by:
|
||||
* - [[Call]] implementation for Function objects.
|
||||
* - [[Construct]] implementation for Function objects.
|
||||
*/
|
||||
static void
|
||||
ecma_function_bind_merge_arg_lists (ecma_value_t *merged_args_list_p, /**< destination argument list */
|
||||
ecma_collection_header_t *bound_arg_list_p, /**< bound argument list */
|
||||
const ecma_value_t *arguments_list_p, /**< source arguments list */
|
||||
ecma_length_t arguments_list_len) /**< length of source arguments list */
|
||||
{
|
||||
/* Performance optimization: only the values are copied. This is
|
||||
* enough, since the original references keep these objects alive. */
|
||||
|
||||
ecma_collection_iterator_t bound_args_iterator;
|
||||
ecma_collection_iterator_init (&bound_args_iterator, bound_arg_list_p);
|
||||
|
||||
for (ecma_length_t i = bound_arg_list_p->unit_number; i > 0; i--)
|
||||
{
|
||||
bool is_moved = ecma_collection_iterator_next (&bound_args_iterator);
|
||||
JERRY_ASSERT (is_moved);
|
||||
|
||||
*merged_args_list_p++ = *bound_args_iterator.current_value_p;
|
||||
}
|
||||
|
||||
while (arguments_list_len > 0)
|
||||
{
|
||||
*merged_args_list_p++ = *arguments_list_p++;
|
||||
arguments_list_len--;
|
||||
}
|
||||
} /* ecma_function_bind_merge_arg_lists */
|
||||
|
||||
/**
|
||||
* Function object creation operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 13.2
|
||||
*
|
||||
* @return pointer to newly created Function object
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
|
||||
bool is_decl_in_strict_mode, /**< is function declared in strict mode code? */
|
||||
const ecma_compiled_code_t *bytecode_data_p) /**< byte-code array */
|
||||
{
|
||||
bool is_strict_mode_code = is_decl_in_strict_mode;
|
||||
|
||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE)
|
||||
{
|
||||
is_strict_mode_code = true;
|
||||
}
|
||||
|
||||
// 1., 4., 13.
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
|
||||
|
||||
ecma_object_t *func_p = ecma_create_object (prototype_obj_p, true, true, ECMA_OBJECT_TYPE_FUNCTION);
|
||||
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
|
||||
// 2., 6., 7., 8.
|
||||
/*
|
||||
* We don't setup [[Get]], [[Call]], [[Construct]], [[HasInstance]] for each function object.
|
||||
* Instead we set the object's type to ECMA_OBJECT_TYPE_FUNCTION
|
||||
* that defines which version of the routine should be used on demand.
|
||||
*/
|
||||
|
||||
// 3.
|
||||
/*
|
||||
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_FUNCTION type.
|
||||
*
|
||||
* See also: ecma_object_get_class_name
|
||||
*/
|
||||
|
||||
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_p;
|
||||
|
||||
// 9.
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (ext_func_p->u.function.scope_cp, scope_p);
|
||||
|
||||
// 10., 11., 12.
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (ext_func_p->u.function.bytecode_cp, bytecode_data_p);
|
||||
ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p);
|
||||
|
||||
// 14., 15., 16., 17., 18.
|
||||
/*
|
||||
* 'length' and 'prototype' properties are instantiated lazily
|
||||
*
|
||||
* See also: ecma_op_function_try_lazy_instantiate_property
|
||||
*/
|
||||
|
||||
// 19.
|
||||
if (is_strict_mode_code)
|
||||
{
|
||||
ecma_object_t *thrower_p = ecma_builtin_get (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER);
|
||||
|
||||
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
|
||||
{
|
||||
prop_desc.is_enumerable_defined = true;
|
||||
prop_desc.is_enumerable = false;
|
||||
|
||||
prop_desc.is_configurable_defined = true;
|
||||
prop_desc.is_configurable = false;
|
||||
|
||||
prop_desc.is_get_defined = true;
|
||||
prop_desc.get_p = thrower_p;
|
||||
|
||||
prop_desc.is_set_defined = true;
|
||||
prop_desc.set_p = thrower_p;
|
||||
}
|
||||
|
||||
ecma_string_t *magic_string_caller_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLER);
|
||||
ecma_op_object_define_own_property (func_p,
|
||||
magic_string_caller_p,
|
||||
&prop_desc,
|
||||
false);
|
||||
ecma_deref_ecma_string (magic_string_caller_p);
|
||||
|
||||
ecma_string_t *magic_string_arguments_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS);
|
||||
ecma_op_object_define_own_property (func_p,
|
||||
magic_string_arguments_p,
|
||||
&prop_desc,
|
||||
false);
|
||||
ecma_deref_ecma_string (magic_string_arguments_p);
|
||||
|
||||
ecma_deref_object (thrower_p);
|
||||
}
|
||||
|
||||
return func_p;
|
||||
} /* ecma_op_create_function_object */
|
||||
|
||||
/**
|
||||
* List names of a Function object's lazy instantiated properties,
|
||||
* adding them to corresponding string collections
|
||||
*
|
||||
* See also:
|
||||
* ecma_op_function_try_lazy_instantiate_property
|
||||
*/
|
||||
void
|
||||
ecma_op_function_list_lazy_property_names (bool separate_enumerable, /**< true - list enumerable properties into
|
||||
* main collection and non-enumerable
|
||||
* to collection of 'skipped
|
||||
* non-enumerable' properties,
|
||||
* false - list all properties into main
|
||||
* collection.
|
||||
*/
|
||||
ecma_collection_header_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_header_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
{
|
||||
ecma_collection_header_t *for_enumerable_p = main_collection_p;
|
||||
JERRY_UNUSED (for_enumerable_p);
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
|
||||
ecma_string_t *name_p;
|
||||
|
||||
/* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */
|
||||
name_p = ecma_new_ecma_length_string ();
|
||||
ecma_append_to_values_collection (for_non_enumerable_p, ecma_make_string_value (name_p), true);
|
||||
ecma_deref_ecma_string (name_p);
|
||||
|
||||
/* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */
|
||||
name_p = ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE);
|
||||
ecma_append_to_values_collection (for_non_enumerable_p, ecma_make_string_value (name_p), true);
|
||||
ecma_deref_ecma_string (name_p);
|
||||
} /* ecma_op_function_list_lazy_property_names */
|
||||
|
||||
/**
|
||||
* Lazy instantation of non-builtin ecma function object's properties
|
||||
*
|
||||
* Warning:
|
||||
* Only non-configurable properties could be instantiated lazily in this function,
|
||||
* as configurable properties could be deleted and it would be incorrect
|
||||
* to reinstantiate them in the function in second time.
|
||||
*
|
||||
* @return pointer to newly instantiated property, if a property was instantiated,
|
||||
* NULL - otherwise
|
||||
*/
|
||||
ecma_property_t *
|
||||
ecma_op_function_try_lazy_instantiate_property (ecma_object_t *object_p, /**< the function object */
|
||||
ecma_string_t *property_name_p) /**< property name */
|
||||
{
|
||||
static const char prototype_str_p[] = "prototype";
|
||||
|
||||
JERRY_ASSERT (!ecma_get_object_is_builtin (object_p));
|
||||
|
||||
ecma_string_container_t container = ECMA_STRING_GET_CONTAINER (property_name_p);
|
||||
|
||||
/* Check whether the property_name_p is prototype */
|
||||
if (container == ECMA_STRING_CONTAINER_MAGIC_STRING)
|
||||
{
|
||||
if (property_name_p->u.magic_string_id != LIT_MAGIC_STRING_PROTOTYPE)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (container != ECMA_STRING_CONTAINER_HEAP_UTF8_STRING
|
||||
|| property_name_p->u.utf8_string.size != (sizeof (prototype_str_p) - 1))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strncmp ((char *) (property_name_p + 1), prototype_str_p, (sizeof (prototype_str_p) - 1)) != 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* ECMA-262 v5, 13.2, 16-18 */
|
||||
|
||||
/* 16. */
|
||||
ecma_object_t *proto_object_p = ecma_op_create_object_object_noarg ();
|
||||
|
||||
/* 17. */
|
||||
ecma_string_t *magic_string_constructor_p = ecma_get_magic_string (LIT_MAGIC_STRING_CONSTRUCTOR);
|
||||
|
||||
ecma_property_value_t *constructor_prop_value_p;
|
||||
constructor_prop_value_p = ecma_create_named_data_property (proto_object_p,
|
||||
magic_string_constructor_p,
|
||||
ECMA_PROPERTY_CONFIGURABLE_WRITABLE,
|
||||
NULL);
|
||||
|
||||
constructor_prop_value_p->value = ecma_make_object_value (object_p);
|
||||
|
||||
ecma_deref_ecma_string (magic_string_constructor_p);
|
||||
|
||||
/* 18. */
|
||||
ecma_property_t *prototype_prop_p;
|
||||
ecma_property_value_t *prototype_prop_value_p;
|
||||
prototype_prop_value_p = ecma_create_named_data_property (object_p,
|
||||
property_name_p,
|
||||
ECMA_PROPERTY_FLAG_WRITABLE,
|
||||
&prototype_prop_p);
|
||||
|
||||
prototype_prop_value_p->value = ecma_make_object_value (proto_object_p);
|
||||
|
||||
ecma_deref_object (proto_object_p);
|
||||
|
||||
return prototype_prop_p;
|
||||
} /* ecma_op_function_try_lazy_instantiate_property */
|
||||
|
||||
/**
|
||||
* External function object creation operation.
|
||||
*
|
||||
* Note:
|
||||
* external function object is implementation-defined object type
|
||||
* that represent functions implemented in native code, using Embedding API
|
||||
*
|
||||
* @return pointer to newly created external function object
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_op_create_external_function_object (ecma_external_pointer_t code_p) /**< pointer to external native handler */
|
||||
{
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
|
||||
|
||||
ecma_object_t *function_obj_p;
|
||||
function_obj_p = ecma_create_object (prototype_obj_p, true, true, ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
|
||||
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
|
||||
/*
|
||||
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION type.
|
||||
*
|
||||
* See also: ecma_object_get_class_name
|
||||
*/
|
||||
|
||||
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) function_obj_p;
|
||||
ext_func_obj_p->u.external_function = code_p;
|
||||
|
||||
ecma_string_t *magic_string_prototype_p = ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE);
|
||||
ecma_builtin_helper_def_prop (function_obj_p,
|
||||
magic_string_prototype_p,
|
||||
ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
|
||||
true, /* Writable */
|
||||
false, /* Enumerable */
|
||||
false, /* Configurable */
|
||||
false); /* Failure handling */
|
||||
|
||||
ecma_deref_ecma_string (magic_string_prototype_p);
|
||||
|
||||
return function_obj_p;
|
||||
} /* ecma_op_create_external_function_object */
|
||||
|
||||
/**
|
||||
* [[Call]] implementation for Function objects,
|
||||
* created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION)
|
||||
* or 15.3.4.5 (ECMA_OBJECT_TYPE_BOUND_FUNCTION),
|
||||
* and for built-in Function objects
|
||||
* from section 15 (ECMA_OBJECT_TYPE_FUNCTION).
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object */
|
||||
ecma_value_t value) /**< argument 'V' */
|
||||
{
|
||||
JERRY_ASSERT (func_obj_p != NULL
|
||||
&& !ecma_is_lexical_environment (func_obj_p));
|
||||
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION)
|
||||
{
|
||||
if (ecma_get_object_is_builtin (func_obj_p)
|
||||
&& ecma_builtin_function_is_routine (func_obj_p))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
|
||||
if (!ecma_is_value_object (value))
|
||||
{
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
}
|
||||
|
||||
ecma_object_t *v_obj_p = ecma_get_object_from_value (value);
|
||||
|
||||
ecma_string_t *prototype_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE);
|
||||
|
||||
ECMA_TRY_CATCH (prototype_obj_value,
|
||||
ecma_op_object_get (func_obj_p, prototype_magic_string_p),
|
||||
ret_value);
|
||||
|
||||
if (!ecma_is_value_object (prototype_obj_value))
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_object_t *prototype_obj_p = ecma_get_object_from_value (prototype_obj_value);
|
||||
JERRY_ASSERT (prototype_obj_p != NULL);
|
||||
|
||||
do
|
||||
{
|
||||
v_obj_p = ecma_get_object_prototype (v_obj_p);
|
||||
|
||||
if (v_obj_p == NULL)
|
||||
{
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
|
||||
break;
|
||||
}
|
||||
else if (v_obj_p == prototype_obj_p)
|
||||
{
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (prototype_obj_value);
|
||||
|
||||
ecma_deref_ecma_string (prototype_magic_string_p);
|
||||
}
|
||||
else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
|
||||
|
||||
/* 1. */
|
||||
ecma_value_t *target_function_prop_p;
|
||||
target_function_prop_p = ecma_get_internal_property (func_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION);
|
||||
|
||||
ecma_object_t *target_func_obj_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *target_function_prop_p);
|
||||
|
||||
/* 3. */
|
||||
ret_value = ecma_op_object_has_instance (target_func_obj_p, value);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_function_has_instance */
|
||||
|
||||
/**
|
||||
* [[Call]] implementation for Function objects,
|
||||
* created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION)
|
||||
* or 15.3.4.5 (ECMA_OBJECT_TYPE_BOUND_FUNCTION),
|
||||
* and for built-in Function objects
|
||||
* from section 15 (ECMA_OBJECT_TYPE_FUNCTION).
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
|
||||
ecma_value_t this_arg_value, /**< 'this' argument's value */
|
||||
const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
ecma_length_t arguments_list_len) /**< length of arguments list */
|
||||
{
|
||||
JERRY_ASSERT (func_obj_p != NULL
|
||||
&& !ecma_is_lexical_environment (func_obj_p));
|
||||
JERRY_ASSERT (ecma_op_is_callable (ecma_make_object_value (func_obj_p)));
|
||||
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION)
|
||||
{
|
||||
if (unlikely (ecma_get_object_is_builtin (func_obj_p)))
|
||||
{
|
||||
ret_value = ecma_builtin_dispatch_call (func_obj_p,
|
||||
this_arg_value,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Entering Function Code (ECMA-262 v5, 10.4.3) */
|
||||
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_obj_p;
|
||||
|
||||
ecma_object_t *scope_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
|
||||
ext_func_p->u.function.scope_cp);
|
||||
|
||||
// 8.
|
||||
ecma_value_t this_binding;
|
||||
bool is_strict;
|
||||
bool is_no_lex_env;
|
||||
|
||||
const ecma_compiled_code_t *bytecode_data_p;
|
||||
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
|
||||
ext_func_p->u.function.bytecode_cp);
|
||||
|
||||
is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) ? true : false;
|
||||
is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) ? true : false;
|
||||
|
||||
// 1.
|
||||
if (is_strict)
|
||||
{
|
||||
this_binding = ecma_copy_value (this_arg_value);
|
||||
}
|
||||
else if (ecma_is_value_undefined (this_arg_value)
|
||||
|| ecma_is_value_null (this_arg_value))
|
||||
{
|
||||
// 2.
|
||||
this_binding = ecma_make_object_value (ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 3., 4.
|
||||
this_binding = ecma_op_to_object (this_arg_value);
|
||||
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (this_binding));
|
||||
}
|
||||
|
||||
// 5.
|
||||
ecma_object_t *local_env_p;
|
||||
if (is_no_lex_env)
|
||||
{
|
||||
local_env_p = scope_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
local_env_p = ecma_create_decl_lex_env (scope_p);
|
||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_ARGUMENTS_NEEDED)
|
||||
{
|
||||
ecma_op_create_arguments_object (func_obj_p,
|
||||
local_env_p,
|
||||
arguments_list_p,
|
||||
arguments_list_len,
|
||||
bytecode_data_p);
|
||||
}
|
||||
}
|
||||
|
||||
ret_value = vm_run (bytecode_data_p,
|
||||
this_binding,
|
||||
local_env_p,
|
||||
false,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
|
||||
if (!is_no_lex_env)
|
||||
{
|
||||
ecma_deref_object (local_env_p);
|
||||
}
|
||||
|
||||
ecma_free_value (this_binding);
|
||||
}
|
||||
}
|
||||
else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
|
||||
{
|
||||
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
|
||||
|
||||
ret_value = jerry_dispatch_external_function (func_obj_p,
|
||||
ext_func_obj_p->u.external_function,
|
||||
this_arg_value,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
|
||||
JERRY_CONTEXT (is_direct_eval_form_call) = false;
|
||||
|
||||
/* 2-3. */
|
||||
ecma_value_t *target_function_prop_p;
|
||||
target_function_prop_p = ecma_get_internal_property (func_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION);
|
||||
|
||||
ecma_object_t *target_func_obj_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *target_function_prop_p);
|
||||
|
||||
/* 4. */
|
||||
ecma_value_t *bound_args_prop_p = ecma_find_internal_property (func_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS);
|
||||
ecma_value_t bound_this_value = *ecma_get_internal_property (func_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_THIS);
|
||||
|
||||
if (bound_args_prop_p != NULL)
|
||||
{
|
||||
ecma_collection_header_t *bound_arg_list_p;
|
||||
bound_arg_list_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_header_t, *bound_args_prop_p);
|
||||
|
||||
JERRY_ASSERT (bound_arg_list_p->unit_number > 0);
|
||||
|
||||
ecma_length_t merged_args_list_len = bound_arg_list_p->unit_number + arguments_list_len;
|
||||
|
||||
JMEM_DEFINE_LOCAL_ARRAY (merged_args_list_p, merged_args_list_len, ecma_value_t);
|
||||
|
||||
ecma_function_bind_merge_arg_lists (merged_args_list_p,
|
||||
bound_arg_list_p,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
|
||||
/* 5. */
|
||||
ret_value = ecma_op_function_call (target_func_obj_p,
|
||||
bound_this_value,
|
||||
merged_args_list_p,
|
||||
merged_args_list_len);
|
||||
|
||||
JMEM_FINALIZE_LOCAL_ARRAY (merged_args_list_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 5. */
|
||||
ret_value = ecma_op_function_call (target_func_obj_p,
|
||||
bound_this_value,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
}
|
||||
}
|
||||
|
||||
JERRY_ASSERT (!ecma_is_value_empty (ret_value));
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_function_call */
|
||||
|
||||
/**
|
||||
* [[Construct]] implementation for Function objects (13.2.2),
|
||||
* created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION) and
|
||||
* externally defined (host) functions (ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION).
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_op_function_construct_simple_or_external (ecma_object_t *func_obj_p, /**< Function object */
|
||||
const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
ecma_length_t arguments_list_len) /**< length of arguments list */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION
|
||||
|| ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
|
||||
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ecma_string_t *prototype_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE);
|
||||
|
||||
// 5.
|
||||
ECMA_TRY_CATCH (func_obj_prototype_prop_value,
|
||||
ecma_op_object_get (func_obj_p,
|
||||
prototype_magic_string_p),
|
||||
ret_value);
|
||||
|
||||
// 1., 2., 4.
|
||||
ecma_object_t *obj_p;
|
||||
if (ecma_is_value_object (func_obj_prototype_prop_value))
|
||||
{
|
||||
// 6.
|
||||
obj_p = ecma_create_object (ecma_get_object_from_value (func_obj_prototype_prop_value),
|
||||
false,
|
||||
true,
|
||||
ECMA_OBJECT_TYPE_GENERAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 7.
|
||||
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
|
||||
obj_p = ecma_create_object (prototype_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
|
||||
ecma_deref_object (prototype_p);
|
||||
}
|
||||
|
||||
// 3.
|
||||
/*
|
||||
* [[Class]] property of ECMA_OBJECT_TYPE_GENERAL type objects
|
||||
* without ECMA_INTERNAL_PROPERTY_CLASS internal property
|
||||
* is "Object".
|
||||
*
|
||||
* See also: ecma_object_get_class_name.
|
||||
*/
|
||||
|
||||
// 8.
|
||||
ECMA_TRY_CATCH (call_completion,
|
||||
ecma_op_function_call (func_obj_p,
|
||||
ecma_make_object_value (obj_p),
|
||||
arguments_list_p,
|
||||
arguments_list_len),
|
||||
ret_value);
|
||||
|
||||
// 9.
|
||||
if (ecma_is_value_object (call_completion))
|
||||
{
|
||||
ret_value = ecma_copy_value (call_completion);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 10.
|
||||
ecma_ref_object (obj_p);
|
||||
ret_value = ecma_make_object_value (obj_p);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (call_completion);
|
||||
|
||||
ecma_deref_object (obj_p);
|
||||
|
||||
ECMA_FINALIZE (func_obj_prototype_prop_value);
|
||||
|
||||
ecma_deref_ecma_string (prototype_magic_string_p);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_function_construct_simple_or_external */
|
||||
|
||||
/**
|
||||
* [[Construct]] implementation:
|
||||
* 13.2.2 - for Function objects, created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION),
|
||||
* and externally defined host functions (ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
|
||||
* 15.3.4.5.1 - for Function objects, created through 15.3.4.5 (ECMA_OBJECT_TYPE_BOUND_FUNCTION).
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
|
||||
const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
ecma_length_t arguments_list_len) /**< length of arguments list */
|
||||
{
|
||||
JERRY_ASSERT (func_obj_p != NULL
|
||||
&& !ecma_is_lexical_environment (func_obj_p));
|
||||
JERRY_ASSERT (ecma_is_constructor (ecma_make_object_value (func_obj_p)));
|
||||
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION)
|
||||
{
|
||||
if (unlikely (ecma_get_object_is_builtin (func_obj_p)
|
||||
&& !ecma_builtin_function_is_routine (func_obj_p)))
|
||||
{
|
||||
ret_value = ecma_builtin_dispatch_construct (func_obj_p,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = ecma_op_function_construct_simple_or_external (func_obj_p,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
}
|
||||
}
|
||||
else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
|
||||
{
|
||||
ret_value = ecma_op_function_construct_simple_or_external (func_obj_p,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
|
||||
|
||||
/* 1. */
|
||||
ecma_value_t *target_function_prop_p;
|
||||
target_function_prop_p = ecma_get_internal_property (func_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION);
|
||||
|
||||
ecma_object_t *target_func_obj_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *target_function_prop_p);
|
||||
|
||||
/* 2. */
|
||||
if (!ecma_is_constructor (ecma_make_object_value (target_func_obj_p)))
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 4. */
|
||||
ecma_value_t *bound_args_prop_p;
|
||||
bound_args_prop_p = ecma_find_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS);
|
||||
|
||||
if (bound_args_prop_p != NULL)
|
||||
{
|
||||
ecma_collection_header_t *bound_arg_list_p;
|
||||
bound_arg_list_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_header_t, *bound_args_prop_p);
|
||||
|
||||
JERRY_ASSERT (bound_arg_list_p->unit_number > 0);
|
||||
|
||||
ecma_length_t merged_args_list_len = bound_arg_list_p->unit_number + arguments_list_len;
|
||||
|
||||
JMEM_DEFINE_LOCAL_ARRAY (merged_args_list_p, merged_args_list_len, ecma_value_t);
|
||||
|
||||
ecma_function_bind_merge_arg_lists (merged_args_list_p,
|
||||
bound_arg_list_p,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
|
||||
/* 5. */
|
||||
ret_value = ecma_op_function_construct (target_func_obj_p,
|
||||
merged_args_list_p,
|
||||
merged_args_list_len);
|
||||
|
||||
JMEM_FINALIZE_LOCAL_ARRAY (merged_args_list_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 5. */
|
||||
ret_value = ecma_op_function_construct (target_func_obj_p,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_function_construct */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
61
third_party/jerryscript/jerry-core/ecma/operations/ecma-function-object.h
vendored
Normal file
61
third_party/jerryscript/jerry-core/ecma/operations/ecma-function-object.h
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_FUNCTION_OBJECT_H
|
||||
#define ECMA_FUNCTION_OBJECT_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
#include "vm.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmafunctionobject ECMA Function object related routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern bool ecma_op_is_callable (ecma_value_t);
|
||||
extern bool ecma_is_constructor (ecma_value_t);
|
||||
|
||||
extern ecma_object_t *
|
||||
ecma_op_create_function_object (ecma_object_t *, bool, const ecma_compiled_code_t *);
|
||||
|
||||
extern void
|
||||
ecma_op_function_list_lazy_property_names (bool,
|
||||
ecma_collection_header_t *,
|
||||
ecma_collection_header_t *);
|
||||
|
||||
extern ecma_property_t *
|
||||
ecma_op_function_try_lazy_instantiate_property (ecma_object_t *, ecma_string_t *);
|
||||
|
||||
extern ecma_object_t *
|
||||
ecma_op_create_external_function_object (ecma_external_pointer_t);
|
||||
|
||||
extern ecma_value_t
|
||||
ecma_op_function_call (ecma_object_t *, ecma_value_t,
|
||||
const ecma_value_t *, ecma_length_t);
|
||||
|
||||
extern ecma_value_t
|
||||
ecma_op_function_construct (ecma_object_t *, const ecma_value_t *, ecma_length_t);
|
||||
|
||||
extern ecma_value_t
|
||||
ecma_op_function_has_instance (ecma_object_t *, ecma_value_t);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_FUNCTION_OBJECT_H */
|
187
third_party/jerryscript/jerry-core/ecma/operations/ecma-get-put-value.c
vendored
Normal file
187
third_party/jerryscript/jerry-core/ecma/operations/ecma-get-put-value.c
vendored
Normal file
|
@ -0,0 +1,187 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of ECMA GetValue and PutValue
|
||||
*/
|
||||
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-lex-env.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-function-object.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup lexicalenvironment Lexical environment
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* GetValue operation part (lexical environment base or unresolvable reference).
|
||||
*
|
||||
* See also: ECMA-262 v5, 8.7.1, sections 3 and 5
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_get_value_lex_env_base (ecma_object_t *ref_base_lex_env_p, /**< reference's base (lexical environment) */
|
||||
ecma_string_t *var_name_string_p, /**< variable name */
|
||||
bool is_strict) /**< flag indicating strict mode */
|
||||
{
|
||||
const bool is_unresolvable_reference = (ref_base_lex_env_p == NULL);
|
||||
|
||||
// 3.
|
||||
if (unlikely (is_unresolvable_reference))
|
||||
{
|
||||
return ecma_raise_reference_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
|
||||
// 5.
|
||||
JERRY_ASSERT (ref_base_lex_env_p != NULL
|
||||
&& ecma_is_lexical_environment (ref_base_lex_env_p));
|
||||
|
||||
// 5.a
|
||||
return ecma_op_get_binding_value (ref_base_lex_env_p,
|
||||
var_name_string_p,
|
||||
is_strict);
|
||||
} /* ecma_op_get_value_lex_env_base */
|
||||
|
||||
/**
|
||||
* GetValue operation part (object base).
|
||||
*
|
||||
* See also: ECMA-262 v5, 8.7.1, section 4
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_get_value_object_base (ecma_value_t base_value, /**< base value */
|
||||
ecma_string_t *property_name_p) /**< property name */
|
||||
{
|
||||
if (ecma_is_value_object (base_value))
|
||||
{
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (base_value);
|
||||
JERRY_ASSERT (obj_p != NULL
|
||||
&& !ecma_is_lexical_environment (obj_p));
|
||||
|
||||
return ecma_op_object_get (obj_p, property_name_p);
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (base_value)
|
||||
|| ecma_is_value_number (base_value)
|
||||
|| ecma_is_value_string (base_value));
|
||||
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ECMA_TRY_CATCH (object_base, ecma_op_to_object (base_value), ret_value);
|
||||
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (object_base);
|
||||
JERRY_ASSERT (object_p != NULL
|
||||
&& !ecma_is_lexical_environment (object_p));
|
||||
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
|
||||
/* Circular reference is possible in JavaScript and testing it is complicated. */
|
||||
int max_depth = ECMA_PROPERTY_SEARCH_DEPTH_LIMIT;
|
||||
|
||||
do
|
||||
{
|
||||
ecma_value_t value = ecma_op_object_find_own (base_value, object_p, property_name_p);
|
||||
|
||||
if (ecma_is_value_found (value))
|
||||
{
|
||||
ret_value = value;
|
||||
break;
|
||||
}
|
||||
|
||||
if (--max_depth == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
object_p = ecma_get_object_prototype (object_p);
|
||||
}
|
||||
while (object_p != NULL);
|
||||
|
||||
ECMA_FINALIZE (object_base);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_get_value_object_base */
|
||||
|
||||
/**
|
||||
* PutValue operation part (lexical environment base or unresolvable reference).
|
||||
*
|
||||
* See also: ECMA-262 v5, 8.7.2, sections 3 and 5
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_put_value_lex_env_base (ecma_object_t *ref_base_lex_env_p, /**< reference's base (lexical environment) */
|
||||
ecma_string_t *var_name_string_p, /**< variable name */
|
||||
bool is_strict, /**< flag indicating strict mode */
|
||||
ecma_value_t value) /**< ECMA-value */
|
||||
{
|
||||
const bool is_unresolvable_reference = (ref_base_lex_env_p == NULL);
|
||||
|
||||
// 3.
|
||||
if (unlikely (is_unresolvable_reference))
|
||||
{
|
||||
// 3.a.
|
||||
if (is_strict)
|
||||
{
|
||||
return ecma_raise_reference_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 3.b.
|
||||
ecma_object_t *global_object_p = ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL);
|
||||
|
||||
ecma_value_t completion = ecma_op_object_put (global_object_p,
|
||||
var_name_string_p,
|
||||
value,
|
||||
false);
|
||||
|
||||
ecma_deref_object (global_object_p);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (completion));
|
||||
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
// 5.
|
||||
JERRY_ASSERT (ref_base_lex_env_p != NULL
|
||||
&& ecma_is_lexical_environment (ref_base_lex_env_p));
|
||||
|
||||
// 5.a
|
||||
return ecma_op_set_mutable_binding (ref_base_lex_env_p,
|
||||
var_name_string_p,
|
||||
value,
|
||||
is_strict);
|
||||
} /* ecma_op_put_value_lex_env_base */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
400
third_party/jerryscript/jerry-core/ecma/operations/ecma-lex-env.c
vendored
Normal file
400
third_party/jerryscript/jerry-core/ecma/operations/ecma-lex-env.c
vendored
Normal file
|
@ -0,0 +1,400 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 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-builtin-helpers.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-lex-env.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "jcontext.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup lexicalenvironment Lexical environment
|
||||
* @{
|
||||
*
|
||||
* \addtogroup globallexicalenvironment Global lexical environment
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialize Global environment
|
||||
*/
|
||||
void
|
||||
ecma_init_global_lex_env (void)
|
||||
{
|
||||
#ifdef CONFIG_ECMA_GLOBAL_ENVIRONMENT_DECLARATIVE
|
||||
JERRY_CONTEXT (ecma_global_lex_env_p) = ecma_create_decl_lex_env (NULL);
|
||||
#else /* !CONFIG_ECMA_GLOBAL_ENVIRONMENT_DECLARATIVE */
|
||||
ecma_object_t *glob_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL);
|
||||
|
||||
JERRY_CONTEXT (ecma_global_lex_env_p) = ecma_create_object_lex_env (NULL, glob_obj_p, false);
|
||||
|
||||
ecma_deref_object (glob_obj_p);
|
||||
#endif /* CONFIG_ECMA_GLOBAL_ENVIRONMENT_DECLARATIVE */
|
||||
} /* ecma_init_global_lex_env */
|
||||
|
||||
/**
|
||||
* Finalize Global environment
|
||||
*/
|
||||
void
|
||||
ecma_finalize_global_lex_env (void)
|
||||
{
|
||||
ecma_deref_object (JERRY_CONTEXT (ecma_global_lex_env_p));
|
||||
JERRY_CONTEXT (ecma_global_lex_env_p) = NULL;
|
||||
} /* ecma_finalize_global_lex_env */
|
||||
|
||||
/**
|
||||
* Get reference to Global lexical environment
|
||||
* without increasing its reference count.
|
||||
*
|
||||
* @return pointer to the object's instance
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_get_global_environment (void)
|
||||
{
|
||||
return JERRY_CONTEXT (ecma_global_lex_env_p);
|
||||
} /* ecma_get_global_environment */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* HasBinding operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 10.2.1
|
||||
*
|
||||
* @return true / false
|
||||
*/
|
||||
bool
|
||||
ecma_op_has_binding (ecma_object_t *lex_env_p, /**< lexical environment */
|
||||
ecma_string_t *name_p) /**< argument N */
|
||||
{
|
||||
JERRY_ASSERT (lex_env_p != NULL
|
||||
&& ecma_is_lexical_environment (lex_env_p));
|
||||
|
||||
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
|
||||
{
|
||||
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
|
||||
|
||||
return (property_p != NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
|
||||
|| ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
|
||||
|
||||
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
|
||||
|
||||
return ecma_op_object_has_property (binding_obj_p, name_p);
|
||||
}
|
||||
} /* ecma_op_has_binding */
|
||||
|
||||
/**
|
||||
* CreateMutableBinding operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 10.2.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_create_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environment */
|
||||
ecma_string_t *name_p, /**< argument N */
|
||||
bool is_deletable) /**< argument D */
|
||||
{
|
||||
JERRY_ASSERT (lex_env_p != NULL
|
||||
&& ecma_is_lexical_environment (lex_env_p));
|
||||
JERRY_ASSERT (name_p != NULL);
|
||||
|
||||
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
|
||||
{
|
||||
uint8_t prop_attributes = ECMA_PROPERTY_FLAG_WRITABLE;
|
||||
|
||||
if (is_deletable)
|
||||
{
|
||||
prop_attributes = (uint8_t) (prop_attributes | ECMA_PROPERTY_FLAG_CONFIGURABLE);
|
||||
}
|
||||
|
||||
ecma_create_named_data_property (lex_env_p,
|
||||
name_p,
|
||||
prop_attributes,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
|
||||
|| ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
|
||||
|
||||
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
|
||||
|
||||
ecma_value_t completion;
|
||||
completion = ecma_builtin_helper_def_prop (binding_obj_p,
|
||||
name_p,
|
||||
ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
|
||||
true, /* Writable */
|
||||
true, /* Enumerable */
|
||||
is_deletable, /* Configurable */
|
||||
true); /* Failure handling */
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (completion))
|
||||
{
|
||||
return completion;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_boolean (completion));
|
||||
}
|
||||
}
|
||||
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
} /* ecma_op_create_mutable_binding */
|
||||
|
||||
/**
|
||||
* SetMutableBinding operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 10.2.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_set_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environment */
|
||||
ecma_string_t *name_p, /**< argument N */
|
||||
ecma_value_t value, /**< argument V */
|
||||
bool is_strict) /**< argument S */
|
||||
{
|
||||
JERRY_ASSERT (lex_env_p != NULL
|
||||
&& ecma_is_lexical_environment (lex_env_p));
|
||||
JERRY_ASSERT (name_p != NULL);
|
||||
|
||||
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
|
||||
{
|
||||
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
|
||||
|
||||
JERRY_ASSERT (property_p != NULL
|
||||
&& ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
|
||||
|
||||
if (ecma_is_property_writable (*property_p))
|
||||
{
|
||||
ecma_named_data_property_assign_value (lex_env_p, ECMA_PROPERTY_VALUE_PTR (property_p), value);
|
||||
}
|
||||
else if (is_strict)
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
|
||||
|| ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
|
||||
|
||||
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
|
||||
|
||||
ecma_value_t completion = ecma_op_object_put (binding_obj_p,
|
||||
name_p,
|
||||
value,
|
||||
is_strict);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (completion))
|
||||
{
|
||||
return completion;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_boolean (completion));
|
||||
}
|
||||
}
|
||||
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
} /* ecma_op_set_mutable_binding */
|
||||
|
||||
/**
|
||||
* GetBindingValue operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 10.2.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_get_binding_value (ecma_object_t *lex_env_p, /**< lexical environment */
|
||||
ecma_string_t *name_p, /**< argument N */
|
||||
bool is_strict) /**< argument S */
|
||||
{
|
||||
JERRY_ASSERT (lex_env_p != NULL
|
||||
&& ecma_is_lexical_environment (lex_env_p));
|
||||
JERRY_ASSERT (name_p != NULL);
|
||||
|
||||
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
|
||||
{
|
||||
ecma_property_value_t *prop_value_p = ecma_get_named_data_property (lex_env_p, name_p);
|
||||
|
||||
return ecma_copy_value (prop_value_p->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
|
||||
|| ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
|
||||
|
||||
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
|
||||
|
||||
ecma_value_t result = ecma_op_object_find (binding_obj_p, name_p);
|
||||
|
||||
if (!ecma_is_value_found (result))
|
||||
{
|
||||
if (is_strict)
|
||||
{
|
||||
result = ecma_raise_reference_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
} /* ecma_op_get_binding_value */
|
||||
|
||||
/**
|
||||
* DeleteBinding operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 10.2.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Return 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
|
||||
ecma_op_delete_binding (ecma_object_t *lex_env_p, /**< lexical environment */
|
||||
ecma_string_t *name_p) /**< argument N */
|
||||
{
|
||||
JERRY_ASSERT (lex_env_p != NULL
|
||||
&& ecma_is_lexical_environment (lex_env_p));
|
||||
JERRY_ASSERT (name_p != NULL);
|
||||
|
||||
|
||||
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
|
||||
{
|
||||
ecma_property_t *prop_p = ecma_find_named_property (lex_env_p, name_p);
|
||||
ecma_simple_value_t ret_val;
|
||||
|
||||
if (prop_p == NULL)
|
||||
{
|
||||
ret_val = ECMA_SIMPLE_VALUE_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
|
||||
|
||||
if (!ecma_is_property_configurable (*prop_p))
|
||||
{
|
||||
ret_val = ECMA_SIMPLE_VALUE_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_delete_property (lex_env_p, ECMA_PROPERTY_VALUE_PTR (prop_p));
|
||||
|
||||
ret_val = ECMA_SIMPLE_VALUE_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return ecma_make_simple_value (ret_val);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
|
||||
|| ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
|
||||
|
||||
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
|
||||
|
||||
return ecma_op_object_delete (binding_obj_p, name_p, false);
|
||||
}
|
||||
} /* ecma_op_delete_binding */
|
||||
|
||||
/**
|
||||
* ImplicitThisValue operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 10.2.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_implicit_this_value (ecma_object_t *lex_env_p) /**< lexical environment */
|
||||
{
|
||||
JERRY_ASSERT (lex_env_p != NULL
|
||||
&& ecma_is_lexical_environment (lex_env_p));
|
||||
|
||||
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
|
||||
{
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
|
||||
|| ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
|
||||
|
||||
if (ecma_get_lex_env_provide_this (lex_env_p))
|
||||
{
|
||||
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
|
||||
ecma_ref_object (binding_obj_p);
|
||||
|
||||
return ecma_make_object_value (binding_obj_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
}
|
||||
}
|
||||
} /* ecma_op_implicit_this_value */
|
||||
|
||||
/**
|
||||
* CreateImmutableBinding operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 10.2.1
|
||||
*/
|
||||
void
|
||||
ecma_op_create_immutable_binding (ecma_object_t *lex_env_p, /**< lexical environment */
|
||||
ecma_string_t *name_p, /**< argument N */
|
||||
ecma_value_t value) /**< argument V */
|
||||
{
|
||||
JERRY_ASSERT (lex_env_p != NULL
|
||||
&& ecma_is_lexical_environment (lex_env_p));
|
||||
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE);
|
||||
|
||||
/*
|
||||
* Warning:
|
||||
* Whether immutable bindings are deletable seems not to be defined by ECMA v5.
|
||||
*/
|
||||
ecma_property_value_t *prop_value_p = ecma_create_named_data_property (lex_env_p,
|
||||
name_p,
|
||||
ECMA_PROPERTY_FIXED,
|
||||
NULL);
|
||||
|
||||
prop_value_p->value = ecma_copy_value_if_not_object (value);
|
||||
} /* ecma_op_create_immutable_binding */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
64
third_party/jerryscript/jerry-core/ecma/operations/ecma-lex-env.h
vendored
Normal file
64
third_party/jerryscript/jerry-core/ecma/operations/ecma-lex-env.h
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_LEX_ENV_H
|
||||
#define ECMA_LEX_ENV_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-reference.h"
|
||||
#include "jrt.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup lexicalenvironment Lexical environment
|
||||
* @{
|
||||
*
|
||||
* \addtogroup globallexicalenvironment Global lexical environment
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern void ecma_init_global_lex_env (void);
|
||||
extern void ecma_finalize_global_lex_env (void);
|
||||
extern ecma_object_t *ecma_get_global_environment (void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* ECMA-262 v5, 8.7.1 and 8.7.2 */
|
||||
extern ecma_value_t ecma_op_get_value_lex_env_base (ecma_object_t *, ecma_string_t *, bool);
|
||||
extern ecma_value_t ecma_op_get_value_object_base (ecma_value_t, ecma_string_t *);
|
||||
extern ecma_value_t ecma_op_put_value_lex_env_base (ecma_object_t *, ecma_string_t *, bool, ecma_value_t);
|
||||
|
||||
/* ECMA-262 v5, Table 17. Abstract methods of Environment Records */
|
||||
extern bool ecma_op_has_binding (ecma_object_t *, ecma_string_t *);
|
||||
extern ecma_value_t ecma_op_create_mutable_binding (ecma_object_t *, ecma_string_t *, bool);
|
||||
extern ecma_value_t ecma_op_set_mutable_binding (ecma_object_t *, ecma_string_t *, ecma_value_t, bool);
|
||||
extern ecma_value_t ecma_op_get_binding_value (ecma_object_t *, ecma_string_t *, bool);
|
||||
extern ecma_value_t ecma_op_delete_binding (ecma_object_t *, ecma_string_t *);
|
||||
extern ecma_value_t ecma_op_implicit_this_value (ecma_object_t *);
|
||||
|
||||
/* ECMA-262 v5, Table 18. Additional methods of Declarative Environment Records */
|
||||
extern void ecma_op_create_immutable_binding (ecma_object_t *, ecma_string_t *, ecma_value_t);
|
||||
|
||||
extern ecma_object_t *ecma_op_create_global_environment (ecma_object_t *);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_LEX_ENV_H */
|
59
third_party/jerryscript/jerry-core/ecma/operations/ecma-number-arithmetic.c
vendored
Normal file
59
third_party/jerryscript/jerry-core/ecma/operations/ecma-number-arithmetic.c
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-number-arithmetic.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup numberarithmetic ECMA number arithmetic operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* ECMA-defined number remainder calculation.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 11.5.3
|
||||
*
|
||||
* @return number - calculated remainder.
|
||||
*/
|
||||
ecma_number_t
|
||||
ecma_op_number_remainder (ecma_number_t left_num, /**< left operand */
|
||||
ecma_number_t right_num) /**< right operand */
|
||||
{
|
||||
if (ecma_number_is_nan (left_num)
|
||||
|| ecma_number_is_nan (right_num)
|
||||
|| ecma_number_is_infinity (left_num)
|
||||
|| ecma_number_is_zero (right_num))
|
||||
{
|
||||
return ecma_number_make_nan ();
|
||||
}
|
||||
else if (ecma_number_is_infinity (right_num)
|
||||
|| (ecma_number_is_zero (left_num)
|
||||
&& !ecma_number_is_zero (right_num)))
|
||||
{
|
||||
return left_num;
|
||||
}
|
||||
|
||||
return ecma_number_calc_remainder (left_num, right_num);
|
||||
} /* ecma_op_number_remainder */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
35
third_party/jerryscript/jerry-core/ecma/operations/ecma-number-arithmetic.h
vendored
Normal file
35
third_party/jerryscript/jerry-core/ecma/operations/ecma-number-arithmetic.h
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_NUMBER_ARITHMETIC_H
|
||||
#define ECMA_NUMBER_ARITHMETIC_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup numberarithmetic ECMA number arithmetic operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern ecma_number_t ecma_op_number_remainder (ecma_number_t, ecma_number_t);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_NUMBER_ARITHMETIC_H */
|
78
third_party/jerryscript/jerry-core/ecma/operations/ecma-number-object.c
vendored
Normal file
78
third_party/jerryscript/jerry-core/ecma/operations/ecma-number-object.c
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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-exceptions.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-number-object.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmanumberobject ECMA Number object related routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Number object creation operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.7.2.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_create_number_object (ecma_value_t arg) /**< argument passed to the Number constructor */
|
||||
{
|
||||
ecma_value_t conv_to_num_completion = ecma_op_to_number (arg);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (conv_to_num_completion))
|
||||
{
|
||||
return conv_to_num_completion;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DISABLE_NUMBER_BUILTIN
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_NUMBER_PROTOTYPE);
|
||||
#else /* CONFIG_DISABLE_NUMBER_BUILTIN */
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
#endif /* !CONFIG_DISABLE_NUMBER_BUILTIN */
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p,
|
||||
false,
|
||||
true,
|
||||
ECMA_OBJECT_TYPE_GENERAL);
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
|
||||
ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
*class_prop_p = LIT_MAGIC_STRING_NUMBER_UL;
|
||||
|
||||
ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
|
||||
|
||||
/* Pass reference (no need to free conv_to_num_completion). */
|
||||
*prim_value_p = conv_to_num_completion;
|
||||
|
||||
return ecma_make_object_value (obj_p);
|
||||
} /* ecma_op_create_number_object */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
35
third_party/jerryscript/jerry-core/ecma/operations/ecma-number-object.h
vendored
Normal file
35
third_party/jerryscript/jerry-core/ecma/operations/ecma-number-object.h
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_NUMBER_OBJECT_H
|
||||
#define ECMA_NUMBER_OBJECT_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmanumberobject ECMA Number object related routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern ecma_value_t ecma_op_create_number_object (ecma_value_t);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_NUMBER_OBJECT_H */
|
452
third_party/jerryscript/jerry-core/ecma/operations/ecma-objects-arguments.c
vendored
Normal file
452
third_party/jerryscript/jerry-core/ecma/operations/ecma-objects-arguments.c
vendored
Normal file
|
@ -0,0 +1,452 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 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-builtin-helpers.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-function-object.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-lcache.h"
|
||||
#include "ecma-lex-env.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-arguments.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "jrt.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmafunctionobject ECMA Function object related routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Arguments object creation operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 10.6
|
||||
*/
|
||||
void
|
||||
ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function */
|
||||
ecma_object_t *lex_env_p, /**< lexical environment the Arguments
|
||||
object is created for */
|
||||
const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
ecma_length_t arguments_number, /**< length of arguments list */
|
||||
const ecma_compiled_code_t *bytecode_data_p) /**< byte code */
|
||||
{
|
||||
// 2., 3., 6.
|
||||
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (prototype_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
|
||||
ecma_deref_object (prototype_p);
|
||||
|
||||
// 11.a, 11.b
|
||||
for (ecma_length_t indx = 0;
|
||||
indx < arguments_number;
|
||||
indx++)
|
||||
{
|
||||
ecma_value_t completion;
|
||||
ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 (indx);
|
||||
|
||||
completion = ecma_builtin_helper_def_prop (obj_p,
|
||||
indx_string_p,
|
||||
arguments_list_p[indx],
|
||||
true, /* Writable */
|
||||
true, /* Enumerable */
|
||||
true, /* Configurable */
|
||||
false); /* Failure handling */
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
ecma_deref_ecma_string (indx_string_p);
|
||||
}
|
||||
|
||||
bool is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0;
|
||||
|
||||
// 1.
|
||||
|
||||
// 7.
|
||||
ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string ();
|
||||
ecma_value_t completion = ecma_builtin_helper_def_prop (obj_p,
|
||||
length_magic_string_p,
|
||||
ecma_make_uint32_value (arguments_number),
|
||||
true, /* Writable */
|
||||
false, /* Enumerable */
|
||||
true, /* Configurable */
|
||||
false); /* Failure handling */
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
ecma_deref_ecma_string (length_magic_string_p);
|
||||
|
||||
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
|
||||
|
||||
ecma_length_t formal_params_number;
|
||||
jmem_cpointer_t *literal_p;
|
||||
|
||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p;
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_data_p;
|
||||
|
||||
formal_params_number = args_p->argument_end;
|
||||
literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p;
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_data_p;
|
||||
|
||||
formal_params_number = args_p->argument_end;
|
||||
literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
|
||||
}
|
||||
|
||||
if (!is_strict
|
||||
&& arguments_number > 0
|
||||
&& formal_params_number > 0)
|
||||
{
|
||||
// 8.
|
||||
ecma_object_t *map_p = ecma_op_create_object_object_noarg ();
|
||||
|
||||
// 11.c
|
||||
for (uint32_t indx = 0;
|
||||
indx < formal_params_number;
|
||||
indx++)
|
||||
{
|
||||
// i.
|
||||
if (literal_p[indx] == JMEM_CP_NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, literal_p[indx]);
|
||||
ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 ((uint32_t) indx);
|
||||
|
||||
prop_desc.is_value_defined = true;
|
||||
prop_desc.value = ecma_make_string_value (name_p);
|
||||
|
||||
prop_desc.is_configurable_defined = true;
|
||||
prop_desc.is_configurable = true;
|
||||
|
||||
completion = ecma_op_object_define_own_property (map_p,
|
||||
indx_string_p,
|
||||
&prop_desc,
|
||||
false);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
ecma_deref_ecma_string (indx_string_p);
|
||||
}
|
||||
|
||||
// 12.
|
||||
ecma_set_object_type (obj_p, ECMA_OBJECT_TYPE_ARGUMENTS);
|
||||
|
||||
ecma_value_t *parameters_map_prop_p = ecma_create_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (*parameters_map_prop_p, map_p);
|
||||
|
||||
ecma_value_t *scope_prop_p = ecma_create_internal_property (map_p,
|
||||
ECMA_INTERNAL_PROPERTY_SCOPE);
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (*scope_prop_p, lex_env_p);
|
||||
|
||||
ecma_deref_object (map_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4.
|
||||
ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
*class_prop_p = LIT_MAGIC_STRING_ARGUMENTS_UL;
|
||||
}
|
||||
|
||||
// 13.
|
||||
if (!is_strict)
|
||||
{
|
||||
ecma_string_t *callee_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLEE);
|
||||
|
||||
completion = ecma_builtin_helper_def_prop (obj_p,
|
||||
callee_magic_string_p,
|
||||
ecma_make_object_value (func_obj_p),
|
||||
true, /* Writable */
|
||||
false, /* Enumerable */
|
||||
true, /* Configurable */
|
||||
false); /* Failure handling */
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
ecma_deref_ecma_string (callee_magic_string_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_object_t *thrower_p = ecma_builtin_get (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER);
|
||||
|
||||
// 14.
|
||||
prop_desc = ecma_make_empty_property_descriptor ();
|
||||
{
|
||||
prop_desc.is_get_defined = true;
|
||||
prop_desc.get_p = thrower_p;
|
||||
|
||||
prop_desc.is_set_defined = true;
|
||||
prop_desc.set_p = thrower_p;
|
||||
|
||||
prop_desc.is_enumerable_defined = true;
|
||||
prop_desc.is_enumerable = false;
|
||||
|
||||
prop_desc.is_configurable_defined = true;
|
||||
prop_desc.is_configurable = false;
|
||||
}
|
||||
|
||||
ecma_string_t *callee_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLEE);
|
||||
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
callee_magic_string_p,
|
||||
&prop_desc,
|
||||
false);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
ecma_deref_ecma_string (callee_magic_string_p);
|
||||
|
||||
ecma_string_t *caller_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLER);
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
caller_magic_string_p,
|
||||
&prop_desc,
|
||||
false);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
ecma_deref_ecma_string (caller_magic_string_p);
|
||||
|
||||
ecma_deref_object (thrower_p);
|
||||
}
|
||||
|
||||
ecma_string_t *arguments_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS);
|
||||
|
||||
if (is_strict)
|
||||
{
|
||||
ecma_op_create_immutable_binding (lex_env_p,
|
||||
arguments_string_p,
|
||||
ecma_make_object_value (obj_p));
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_value_t completion = ecma_op_create_mutable_binding (lex_env_p,
|
||||
arguments_string_p,
|
||||
false);
|
||||
JERRY_ASSERT (ecma_is_value_empty (completion));
|
||||
|
||||
completion = ecma_op_set_mutable_binding (lex_env_p,
|
||||
arguments_string_p,
|
||||
ecma_make_object_value (obj_p),
|
||||
false);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_empty (completion));
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (arguments_string_p);
|
||||
ecma_deref_object (obj_p);
|
||||
} /* ecma_op_create_arguments_object */
|
||||
|
||||
/**
|
||||
* Get value of function's argument mapped to index of Arguments object.
|
||||
*
|
||||
* Note:
|
||||
* The procedure emulates execution of function described by MakeArgGetter
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
void
|
||||
ecma_arguments_update_mapped_arg_value (ecma_object_t *object_p, /**< the object */
|
||||
ecma_string_t *property_name_p, /**< property name */
|
||||
ecma_property_t *property_p) /**< property value */
|
||||
{
|
||||
ecma_value_t *map_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
|
||||
ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p);
|
||||
|
||||
ecma_value_t arg_name = ecma_op_object_find (map_p, property_name_p);
|
||||
|
||||
if (!ecma_is_value_found (arg_name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_value_t *scope_prop_p = ecma_get_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE);
|
||||
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *scope_prop_p);
|
||||
|
||||
JERRY_ASSERT (lex_env_p != NULL
|
||||
&& ecma_is_lexical_environment (lex_env_p));
|
||||
|
||||
ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_name);
|
||||
ecma_value_t value = ecma_op_get_binding_value (lex_env_p, arg_name_p, true);
|
||||
ecma_deref_ecma_string (arg_name_p);
|
||||
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (value));
|
||||
|
||||
ecma_named_data_property_assign_value (object_p, ECMA_PROPERTY_VALUE_PTR (property_p), value);
|
||||
ecma_free_value (value);
|
||||
|
||||
/* These properties cannot be cached. This is a temporary
|
||||
* workaround until the property management is fully rewritten. */
|
||||
if (ecma_is_property_lcached (property_p))
|
||||
{
|
||||
ecma_lcache_invalidate (object_p, property_name_p, property_p);
|
||||
}
|
||||
} /* ecma_arguments_update_mapped_arg_value */
|
||||
|
||||
/**
|
||||
* [[DefineOwnProperty]] ecma Arguments object's operation
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
|
||||
* ECMA-262 v5, 10.6
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_arguments_object_define_own_property (ecma_object_t *obj_p, /**< the object */
|
||||
ecma_string_t *property_name_p, /**< property name */
|
||||
const ecma_property_descriptor_t *property_desc_p, /**< property
|
||||
* descriptor */
|
||||
bool is_throw) /**< flag that controls failure handling */
|
||||
{
|
||||
// 1.
|
||||
ecma_value_t *map_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
|
||||
ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p);
|
||||
|
||||
// 3.
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ECMA_TRY_CATCH (defined,
|
||||
ecma_op_general_object_define_own_property (obj_p,
|
||||
property_name_p,
|
||||
property_desc_p,
|
||||
is_throw),
|
||||
ret_value);
|
||||
|
||||
// 5.
|
||||
if (ecma_op_object_has_own_property (map_p, property_name_p))
|
||||
{
|
||||
// a.
|
||||
if (property_desc_p->is_get_defined
|
||||
|| property_desc_p->is_set_defined)
|
||||
{
|
||||
ecma_value_t completion = ecma_op_object_delete (map_p, property_name_p, false);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
// 6.
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// b.
|
||||
|
||||
ecma_value_t completion = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
// i.
|
||||
if (property_desc_p->is_value_defined)
|
||||
{
|
||||
/* emulating execution of function described by MakeArgSetter */
|
||||
ecma_value_t *scope_prop_p = ecma_get_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE);
|
||||
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *scope_prop_p);
|
||||
|
||||
ecma_property_value_t *arg_name_value_p = ecma_get_named_data_property (map_p, property_name_p);
|
||||
|
||||
completion = ecma_op_set_mutable_binding (lex_env_p,
|
||||
ecma_get_string_from_value (arg_name_value_p->value),
|
||||
property_desc_p->value,
|
||||
true);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_empty (completion));
|
||||
}
|
||||
|
||||
// ii.
|
||||
if (property_desc_p->is_writable_defined
|
||||
&& !property_desc_p->is_writable)
|
||||
{
|
||||
completion = ecma_op_object_delete (map_p,
|
||||
property_name_p,
|
||||
false);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
}
|
||||
|
||||
// 6.
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (defined);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_arguments_object_define_own_property */
|
||||
|
||||
/**
|
||||
* [[Delete]] ecma Arguments object's operation
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
|
||||
* ECMA-262 v5, 10.6
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_arguments_object_delete (ecma_object_t *obj_p, /**< the object */
|
||||
ecma_string_t *property_name_p, /**< property name */
|
||||
bool is_throw) /**< flag that controls failure handling */
|
||||
{
|
||||
// 1.
|
||||
ecma_value_t *map_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
|
||||
ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p);
|
||||
|
||||
// 3.
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ECMA_TRY_CATCH (delete_in_args_ret,
|
||||
ecma_op_general_object_delete (obj_p,
|
||||
property_name_p,
|
||||
is_throw),
|
||||
ret_value);
|
||||
|
||||
if (ecma_is_value_true (delete_in_args_ret))
|
||||
{
|
||||
if (ecma_op_object_has_own_property (map_p, property_name_p))
|
||||
{
|
||||
ecma_value_t delete_in_map_completion = ecma_op_object_delete (map_p, property_name_p, false);
|
||||
JERRY_ASSERT (ecma_is_value_true (delete_in_map_completion));
|
||||
}
|
||||
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_boolean (delete_in_args_ret));
|
||||
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (delete_in_args_ret);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_arguments_object_delete */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
34
third_party/jerryscript/jerry-core/ecma/operations/ecma-objects-arguments.h
vendored
Normal file
34
third_party/jerryscript/jerry-core/ecma/operations/ecma-objects-arguments.h
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_OBJECTS_ARGUMENTS_H
|
||||
#define ECMA_OBJECTS_ARGUMENTS_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
|
||||
extern void
|
||||
ecma_op_create_arguments_object (ecma_object_t *, ecma_object_t *, const ecma_value_t *,
|
||||
ecma_length_t, const ecma_compiled_code_t *);
|
||||
|
||||
extern void
|
||||
ecma_arguments_update_mapped_arg_value (ecma_object_t *, ecma_string_t *, ecma_property_t *);
|
||||
extern ecma_value_t
|
||||
ecma_op_arguments_object_delete (ecma_object_t *, ecma_string_t *, bool);
|
||||
extern ecma_value_t
|
||||
ecma_op_arguments_object_define_own_property (ecma_object_t *, ecma_string_t *,
|
||||
const ecma_property_descriptor_t *, bool);
|
||||
|
||||
#endif /* !ECMA_OBJECTS_ARGUMENTS_H */
|
573
third_party/jerryscript/jerry-core/ecma/operations/ecma-objects-general.c
vendored
Normal file
573
third_party/jerryscript/jerry-core/ecma/operations/ecma-objects-general.c
vendored
Normal file
|
@ -0,0 +1,573 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 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-exceptions.h"
|
||||
#include "ecma-function-object.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmaobjectsinternalops ECMA objects' operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reject sequence
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_reject (bool is_throw) /**< Throw flag */
|
||||
{
|
||||
if (is_throw)
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
}
|
||||
} /* ecma_reject */
|
||||
|
||||
/**
|
||||
* 'Object' object creation operation with no arguments.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.2.2.1
|
||||
*
|
||||
* @return pointer to newly created 'Object' object
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_op_create_object_object_noarg (void)
|
||||
{
|
||||
ecma_object_t *object_prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
|
||||
// 3., 4., 6., 7.
|
||||
ecma_object_t *obj_p = ecma_op_create_object_object_noarg_and_set_prototype (object_prototype_p);
|
||||
|
||||
ecma_deref_object (object_prototype_p);
|
||||
|
||||
return obj_p;
|
||||
} /* ecma_op_create_object_object_noarg */
|
||||
|
||||
/**
|
||||
* 'Object' object creation operation with one argument.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.2.2.1
|
||||
*
|
||||
* @return pointer to newly created 'Object' object
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_create_object_object_arg (ecma_value_t value) /**< argument of constructor */
|
||||
{
|
||||
ecma_check_value_type_is_spec_defined (value);
|
||||
|
||||
if (ecma_is_value_object (value)
|
||||
|| ecma_is_value_number (value)
|
||||
|| ecma_is_value_string (value)
|
||||
|| ecma_is_value_boolean (value))
|
||||
{
|
||||
// 1.b, 1.c, 1.d
|
||||
return ecma_op_to_object (value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2.
|
||||
JERRY_ASSERT (ecma_is_value_undefined (value)
|
||||
|| ecma_is_value_null (value));
|
||||
|
||||
ecma_object_t *obj_p = ecma_op_create_object_object_noarg ();
|
||||
|
||||
return ecma_make_object_value (obj_p);
|
||||
}
|
||||
} /* ecma_op_create_object_object_arg */
|
||||
|
||||
/**
|
||||
* Object creation operation with no arguments.
|
||||
* It sets the given prototype to the newly created object.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.2.2.1, 15.2.3.5
|
||||
*
|
||||
* @return pointer to newly created object
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_op_create_object_object_noarg_and_set_prototype (ecma_object_t *object_prototype_p) /**< pointer to prototype of
|
||||
the object
|
||||
(can be NULL) */
|
||||
{
|
||||
ecma_object_t *obj_p = ecma_create_object (object_prototype_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
|
||||
/*
|
||||
* [[Class]] property of ECMA_OBJECT_TYPE_GENERAL type objects
|
||||
* without ECMA_INTERNAL_PROPERTY_CLASS internal property
|
||||
* is "Object".
|
||||
*
|
||||
* See also: ecma_object_get_class_name
|
||||
*/
|
||||
|
||||
return obj_p;
|
||||
} /* ecma_op_create_object_object_noarg_and_set_prototype */
|
||||
|
||||
/**
|
||||
* [[Delete]] ecma general object's operation
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
|
||||
* ECMA-262 v5, 8.12.7
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_general_object_delete (ecma_object_t *obj_p, /**< the object */
|
||||
ecma_string_t *property_name_p, /**< property name */
|
||||
bool is_throw) /**< flag that controls failure handling */
|
||||
{
|
||||
JERRY_ASSERT (obj_p != NULL
|
||||
&& !ecma_is_lexical_environment (obj_p));
|
||||
JERRY_ASSERT (property_name_p != NULL);
|
||||
|
||||
// 1.
|
||||
ecma_property_ref_t property_ref;
|
||||
|
||||
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
|
||||
property_name_p,
|
||||
&property_ref,
|
||||
ECMA_PROPERTY_GET_NO_OPTIONS);
|
||||
|
||||
// 2.
|
||||
if (property == ECMA_PROPERTY_TYPE_NOT_FOUND)
|
||||
{
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
}
|
||||
|
||||
// 3.
|
||||
if (ecma_is_property_configurable (property))
|
||||
{
|
||||
// a.
|
||||
ecma_delete_property (obj_p, property_ref.value_p);
|
||||
|
||||
// b.
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
}
|
||||
else if (is_throw)
|
||||
{
|
||||
// 4.
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 5.
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||
}
|
||||
|
||||
JERRY_UNREACHABLE ();
|
||||
} /* ecma_op_general_object_delete */
|
||||
|
||||
/**
|
||||
* [[DefaultValue]] ecma general object's operation
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
|
||||
* ECMA-262 v5, 8.12.8
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_general_object_default_value (ecma_object_t *obj_p, /**< the object */
|
||||
ecma_preferred_type_hint_t hint) /**< hint on preferred result type */
|
||||
{
|
||||
JERRY_ASSERT (obj_p != NULL
|
||||
&& !ecma_is_lexical_environment (obj_p));
|
||||
|
||||
if (hint == ECMA_PREFERRED_TYPE_NO)
|
||||
{
|
||||
if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_DATE_UL)
|
||||
{
|
||||
hint = ECMA_PREFERRED_TYPE_STRING;
|
||||
}
|
||||
else
|
||||
{
|
||||
hint = ECMA_PREFERRED_TYPE_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 1; i <= 2; i++)
|
||||
{
|
||||
lit_magic_string_id_t function_name_magic_string_id;
|
||||
|
||||
if ((i == 1 && hint == ECMA_PREFERRED_TYPE_STRING)
|
||||
|| (i == 2 && hint == ECMA_PREFERRED_TYPE_NUMBER))
|
||||
{
|
||||
function_name_magic_string_id = LIT_MAGIC_STRING_TO_STRING_UL;
|
||||
}
|
||||
else
|
||||
{
|
||||
function_name_magic_string_id = LIT_MAGIC_STRING_VALUE_OF_UL;
|
||||
}
|
||||
|
||||
ecma_string_t *function_name_p = ecma_get_magic_string (function_name_magic_string_id);
|
||||
|
||||
ecma_value_t function_value_get_completion = ecma_op_object_get (obj_p, function_name_p);
|
||||
|
||||
ecma_deref_ecma_string (function_name_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (function_value_get_completion))
|
||||
{
|
||||
return function_value_get_completion;
|
||||
}
|
||||
|
||||
ecma_value_t call_completion = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
if (ecma_op_is_callable (function_value_get_completion))
|
||||
{
|
||||
ecma_object_t *func_obj_p = ecma_get_object_from_value (function_value_get_completion);
|
||||
|
||||
call_completion = ecma_op_function_call (func_obj_p,
|
||||
ecma_make_object_value (obj_p),
|
||||
NULL,
|
||||
0);
|
||||
}
|
||||
|
||||
ecma_free_value (function_value_get_completion);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (call_completion)
|
||||
|| (!ecma_is_value_empty (call_completion)
|
||||
&& !ecma_is_value_object (call_completion)))
|
||||
{
|
||||
return call_completion;
|
||||
}
|
||||
|
||||
ecma_free_value (call_completion);
|
||||
}
|
||||
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG (""));
|
||||
} /* ecma_op_general_object_default_value */
|
||||
|
||||
/**
|
||||
* Special type for ecma_op_general_object_define_own_property.
|
||||
*/
|
||||
#define ECMA_PROPERTY_TYPE_GENERIC ECMA_PROPERTY_TYPE_DELETED
|
||||
|
||||
/**
|
||||
* [[DefineOwnProperty]] ecma general object's operation
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
|
||||
* ECMA-262 v5, 8.12.9
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the object */
|
||||
ecma_string_t *property_name_p, /**< property name */
|
||||
const ecma_property_descriptor_t *property_desc_p, /**< property
|
||||
* descriptor */
|
||||
bool is_throw) /**< flag that controls failure handling */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL
|
||||
&& !ecma_is_lexical_environment (object_p));
|
||||
JERRY_ASSERT (property_name_p != NULL);
|
||||
|
||||
ecma_property_types_t property_desc_type = ECMA_PROPERTY_TYPE_GENERIC;
|
||||
|
||||
if (property_desc_p->is_value_defined
|
||||
|| property_desc_p->is_writable_defined)
|
||||
{
|
||||
/* A property descriptor cannot be both named data and named accessor. */
|
||||
JERRY_ASSERT (!property_desc_p->is_get_defined
|
||||
&& !property_desc_p->is_set_defined);
|
||||
property_desc_type = ECMA_PROPERTY_TYPE_NAMEDDATA;
|
||||
}
|
||||
else if (property_desc_p->is_get_defined
|
||||
|| property_desc_p->is_set_defined)
|
||||
{
|
||||
property_desc_type = ECMA_PROPERTY_TYPE_NAMEDACCESSOR;
|
||||
}
|
||||
|
||||
/* These three asserts ensures that a new property is created with the appropriate default flags.
|
||||
* E.g. if is_configurable_defined is false, the newly created property must be non-configurable. */
|
||||
JERRY_ASSERT (property_desc_p->is_configurable_defined || !property_desc_p->is_configurable);
|
||||
JERRY_ASSERT (property_desc_p->is_enumerable_defined || !property_desc_p->is_enumerable);
|
||||
JERRY_ASSERT (property_desc_p->is_writable_defined || !property_desc_p->is_writable);
|
||||
|
||||
// 1.
|
||||
ecma_extended_property_ref_t ext_property_ref;
|
||||
ecma_property_t current_prop;
|
||||
|
||||
current_prop = ecma_op_object_get_own_property (object_p,
|
||||
property_name_p,
|
||||
&ext_property_ref.property_ref,
|
||||
ECMA_PROPERTY_GET_VALUE | ECMA_PROPERTY_GET_EXT_REFERENCE);
|
||||
|
||||
if (current_prop == ECMA_PROPERTY_TYPE_NOT_FOUND)
|
||||
{
|
||||
// 3.
|
||||
if (!ecma_get_object_extensible (object_p))
|
||||
{
|
||||
// 2.
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
|
||||
// 4.
|
||||
|
||||
if (property_desc_type != ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
|
||||
{
|
||||
// a.
|
||||
|
||||
JERRY_ASSERT (property_desc_type == ECMA_PROPERTY_TYPE_GENERIC
|
||||
|| property_desc_type == ECMA_PROPERTY_TYPE_NAMEDDATA);
|
||||
|
||||
uint8_t prop_attributes = 0;
|
||||
|
||||
if (property_desc_p->is_configurable)
|
||||
{
|
||||
prop_attributes = (uint8_t) (prop_attributes | ECMA_PROPERTY_FLAG_CONFIGURABLE);
|
||||
}
|
||||
if (property_desc_p->is_enumerable)
|
||||
{
|
||||
prop_attributes = (uint8_t) (prop_attributes | ECMA_PROPERTY_FLAG_ENUMERABLE);
|
||||
}
|
||||
if (property_desc_p->is_writable)
|
||||
{
|
||||
prop_attributes = (uint8_t) (prop_attributes | ECMA_PROPERTY_FLAG_WRITABLE);
|
||||
}
|
||||
|
||||
ecma_property_value_t *new_prop_value_p = ecma_create_named_data_property (object_p,
|
||||
property_name_p,
|
||||
prop_attributes,
|
||||
NULL);
|
||||
|
||||
JERRY_ASSERT (property_desc_p->is_value_defined
|
||||
|| ecma_is_value_undefined (property_desc_p->value));
|
||||
|
||||
new_prop_value_p->value = ecma_copy_value_if_not_object (property_desc_p->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// b.
|
||||
|
||||
uint8_t prop_attributes = 0;
|
||||
|
||||
if (property_desc_p->is_configurable)
|
||||
{
|
||||
prop_attributes = (uint8_t) (prop_attributes | ECMA_PROPERTY_FLAG_CONFIGURABLE);
|
||||
}
|
||||
if (property_desc_p->is_enumerable)
|
||||
{
|
||||
prop_attributes = (uint8_t) (prop_attributes | ECMA_PROPERTY_FLAG_ENUMERABLE);
|
||||
}
|
||||
|
||||
ecma_create_named_accessor_property (object_p,
|
||||
property_name_p,
|
||||
property_desc_p->get_p,
|
||||
property_desc_p->set_p,
|
||||
prop_attributes);
|
||||
}
|
||||
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
}
|
||||
|
||||
// 6.
|
||||
ecma_property_types_t current_property_type = ECMA_PROPERTY_GET_TYPE (current_prop);
|
||||
const bool is_current_configurable = ecma_is_property_configurable (current_prop);
|
||||
|
||||
JERRY_ASSERT (current_property_type == ECMA_PROPERTY_TYPE_NAMEDDATA
|
||||
|| current_property_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR
|
||||
|| current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL);
|
||||
|
||||
// 7. a., b.
|
||||
if (!is_current_configurable
|
||||
&& (property_desc_p->is_configurable
|
||||
|| (property_desc_p->is_enumerable_defined
|
||||
&& (property_desc_p->is_enumerable != ecma_is_property_enumerable (current_prop)))))
|
||||
{
|
||||
if (current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL)
|
||||
{
|
||||
ecma_free_value (ext_property_ref.property_ref.virtual_value);
|
||||
}
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
|
||||
if (current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL)
|
||||
{
|
||||
JERRY_ASSERT (!is_current_configurable && !ecma_is_property_writable (current_prop));
|
||||
|
||||
ecma_value_t result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
|
||||
if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR
|
||||
|| property_desc_p->is_writable
|
||||
|| (property_desc_p->is_value_defined
|
||||
&& !ecma_op_same_value (property_desc_p->value,
|
||||
ext_property_ref.property_ref.virtual_value)))
|
||||
{
|
||||
result = ecma_reject (is_throw);
|
||||
}
|
||||
|
||||
ecma_free_value (ext_property_ref.property_ref.virtual_value);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 8.
|
||||
if (property_desc_type == ECMA_PROPERTY_TYPE_GENERIC)
|
||||
{
|
||||
/* No action required. */
|
||||
}
|
||||
else if (likely (property_desc_type == current_property_type))
|
||||
{
|
||||
/* If property is configurable, there is no need for checks. */
|
||||
if (unlikely (!is_current_configurable))
|
||||
{
|
||||
if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDDATA)
|
||||
{
|
||||
// 10. a. i. & ii.
|
||||
if (!ecma_is_property_writable (current_prop)
|
||||
&& (property_desc_p->is_writable
|
||||
|| (property_desc_p->is_value_defined
|
||||
&& !ecma_op_same_value (property_desc_p->value,
|
||||
ext_property_ref.property_ref.value_p->value))))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 11.
|
||||
|
||||
// a.
|
||||
ecma_property_value_t *value_p = ext_property_ref.property_ref.value_p;
|
||||
|
||||
if ((property_desc_p->is_get_defined
|
||||
&& property_desc_p->get_p != ecma_get_named_accessor_property_getter (value_p))
|
||||
|| (property_desc_p->is_set_defined
|
||||
&& property_desc_p->set_p != ecma_get_named_accessor_property_setter (value_p)))
|
||||
{
|
||||
// i., ii.
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 9.
|
||||
if (!is_current_configurable)
|
||||
{
|
||||
// a.
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
|
||||
ecma_property_value_t *value_p = ext_property_ref.property_ref.value_p;
|
||||
|
||||
if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
|
||||
{
|
||||
JERRY_ASSERT (current_property_type == ECMA_PROPERTY_TYPE_NAMEDDATA);
|
||||
ecma_free_value_if_not_object (value_p->value);
|
||||
|
||||
#ifdef JERRY_CPOINTER_32_BIT
|
||||
ecma_getter_setter_pointers_t *getter_setter_pair_p;
|
||||
getter_setter_pair_p = jmem_pools_alloc (sizeof (ecma_getter_setter_pointers_t));
|
||||
getter_setter_pair_p->getter_p = JMEM_CP_NULL;
|
||||
getter_setter_pair_p->setter_p = JMEM_CP_NULL;
|
||||
ECMA_SET_POINTER (value_p->getter_setter_pair_cp, getter_setter_pair_p);
|
||||
#else /* !JERRY_CPOINTER_32_BIT */
|
||||
value_p->getter_setter_pair.getter_p = JMEM_CP_NULL;
|
||||
value_p->getter_setter_pair.setter_p = JMEM_CP_NULL;
|
||||
#endif /* JERRY_CPOINTER_32_BIT */
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (current_property_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
|
||||
#ifdef JERRY_CPOINTER_32_BIT
|
||||
ecma_getter_setter_pointers_t *getter_setter_pair_p;
|
||||
getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t,
|
||||
value_p->getter_setter_pair_cp);
|
||||
jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t));
|
||||
#endif /* JERRY_CPOINTER_32_BIT */
|
||||
value_p->value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
}
|
||||
|
||||
/* Update flags */
|
||||
ecma_property_t prop_flags = *(ext_property_ref.property_p);
|
||||
prop_flags = (ecma_property_t) (prop_flags & ~(ECMA_PROPERTY_TYPE_MASK | ECMA_PROPERTY_FLAG_WRITABLE));
|
||||
prop_flags = (ecma_property_t) (prop_flags | property_desc_type);
|
||||
*(ext_property_ref.property_p) = prop_flags;
|
||||
}
|
||||
|
||||
// 12.
|
||||
if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDDATA)
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*ext_property_ref.property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
|
||||
|
||||
if (property_desc_p->is_value_defined)
|
||||
{
|
||||
ecma_named_data_property_assign_value (object_p,
|
||||
ext_property_ref.property_ref.value_p,
|
||||
property_desc_p->value);
|
||||
}
|
||||
|
||||
if (property_desc_p->is_writable_defined)
|
||||
{
|
||||
ecma_set_property_writable_attr (ext_property_ref.property_p, property_desc_p->is_writable);
|
||||
}
|
||||
}
|
||||
else if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*ext_property_ref.property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
|
||||
|
||||
if (property_desc_p->is_get_defined)
|
||||
{
|
||||
ecma_set_named_accessor_property_getter (object_p,
|
||||
ext_property_ref.property_ref.value_p,
|
||||
property_desc_p->get_p);
|
||||
}
|
||||
|
||||
if (property_desc_p->is_set_defined)
|
||||
{
|
||||
ecma_set_named_accessor_property_setter (object_p,
|
||||
ext_property_ref.property_ref.value_p,
|
||||
property_desc_p->set_p);
|
||||
}
|
||||
}
|
||||
|
||||
if (property_desc_p->is_enumerable_defined)
|
||||
{
|
||||
ecma_set_property_enumerable_attr (ext_property_ref.property_p, property_desc_p->is_enumerable);
|
||||
}
|
||||
|
||||
if (property_desc_p->is_configurable_defined)
|
||||
{
|
||||
ecma_set_property_configurable_attr (ext_property_ref.property_p, property_desc_p->is_configurable);
|
||||
}
|
||||
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||
} /* ecma_op_general_object_define_own_property */
|
||||
|
||||
#undef ECMA_PROPERTY_TYPE_GENERIC
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
44
third_party/jerryscript/jerry-core/ecma/operations/ecma-objects-general.h
vendored
Normal file
44
third_party/jerryscript/jerry-core/ecma/operations/ecma-objects-general.h
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_OBJECTS_GENERAL_H
|
||||
#define ECMA_OBJECTS_GENERAL_H
|
||||
|
||||
#include "ecma-conversion.h"
|
||||
#include "ecma-globals.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmaobjectsinternalops ECMA objects' operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern ecma_value_t ecma_reject (bool);
|
||||
extern ecma_object_t *ecma_op_create_object_object_noarg (void);
|
||||
extern ecma_value_t ecma_op_create_object_object_arg (ecma_value_t);
|
||||
extern ecma_object_t *ecma_op_create_object_object_noarg_and_set_prototype (ecma_object_t *);
|
||||
|
||||
extern ecma_value_t ecma_op_general_object_delete (ecma_object_t *, ecma_string_t *, bool);
|
||||
extern ecma_value_t ecma_op_general_object_default_value (ecma_object_t *, ecma_preferred_type_hint_t);
|
||||
extern ecma_value_t ecma_op_general_object_define_own_property (ecma_object_t *, ecma_string_t *,
|
||||
const ecma_property_descriptor_t *, bool);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_OBJECTS_GENERAL_H */
|
1509
third_party/jerryscript/jerry-core/ecma/operations/ecma-objects.c
vendored
Normal file
1509
third_party/jerryscript/jerry-core/ecma/operations/ecma-objects.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
57
third_party/jerryscript/jerry-core/ecma/operations/ecma-objects.h
vendored
Normal file
57
third_party/jerryscript/jerry-core/ecma/operations/ecma-objects.h
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_OBJECTS_H
|
||||
#define ECMA_OBJECTS_H
|
||||
|
||||
#include "ecma-conversion.h"
|
||||
#include "ecma-globals.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmaobjectsinternalops ECMA objects' operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern ecma_property_t ecma_op_object_get_own_property (ecma_object_t *, ecma_string_t *,
|
||||
ecma_property_ref_t *, uint32_t);
|
||||
extern ecma_property_t ecma_op_object_get_property (ecma_object_t *, ecma_string_t *,
|
||||
ecma_property_ref_t *, uint32_t);
|
||||
extern bool ecma_op_object_has_own_property (ecma_object_t *, ecma_string_t *);
|
||||
extern bool ecma_op_object_has_property (ecma_object_t *, ecma_string_t *);
|
||||
extern ecma_value_t ecma_op_object_find_own (ecma_value_t, ecma_object_t *, ecma_string_t *);
|
||||
extern ecma_value_t ecma_op_object_find (ecma_object_t *, ecma_string_t *);
|
||||
extern ecma_value_t ecma_op_object_get_own_data_prop (ecma_object_t *, ecma_string_t *);
|
||||
extern ecma_value_t ecma_op_object_get (ecma_object_t *, ecma_string_t *);
|
||||
extern ecma_value_t ecma_op_object_put (ecma_object_t *, ecma_string_t *, ecma_value_t, bool);
|
||||
extern ecma_value_t ecma_op_object_delete (ecma_object_t *, ecma_string_t *, bool);
|
||||
extern ecma_value_t ecma_op_object_default_value (ecma_object_t *, ecma_preferred_type_hint_t);
|
||||
extern ecma_value_t ecma_op_object_define_own_property (ecma_object_t *, ecma_string_t *,
|
||||
const ecma_property_descriptor_t *, bool);
|
||||
extern bool ecma_op_object_get_own_property_descriptor (ecma_object_t *, ecma_string_t *,
|
||||
ecma_property_descriptor_t *);
|
||||
extern ecma_value_t ecma_op_object_has_instance (ecma_object_t *, ecma_value_t);
|
||||
extern bool ecma_op_object_is_prototype_of (ecma_object_t *, ecma_object_t *);
|
||||
extern ecma_collection_header_t * ecma_op_object_get_property_names (ecma_object_t *, bool, bool, bool);
|
||||
|
||||
extern lit_magic_string_id_t ecma_object_get_class_name (ecma_object_t *);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_OBJECTS_H */
|
108
third_party/jerryscript/jerry-core/ecma/operations/ecma-reference.c
vendored
Normal file
108
third_party/jerryscript/jerry-core/ecma/operations/ecma-reference.c
vendored
Normal file
|
@ -0,0 +1,108 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 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-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-reference.h"
|
||||
#include "jrt.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup references ECMA-Reference
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolve syntactic reference.
|
||||
*
|
||||
* @return if reference was resolved successfully,
|
||||
* pointer to lexical environment - reference's base,
|
||||
* else - NULL.
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_op_resolve_reference_base (ecma_object_t *lex_env_p, /**< starting lexical environment */
|
||||
ecma_string_t *name_p) /**< identifier's name */
|
||||
{
|
||||
JERRY_ASSERT (lex_env_p != NULL);
|
||||
|
||||
ecma_object_t *lex_env_iter_p = lex_env_p;
|
||||
|
||||
while (lex_env_iter_p != NULL)
|
||||
{
|
||||
if (ecma_op_has_binding (lex_env_iter_p, name_p))
|
||||
{
|
||||
return lex_env_iter_p;
|
||||
}
|
||||
|
||||
lex_env_iter_p = ecma_get_lex_env_outer_reference (lex_env_iter_p);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
} /* ecma_op_resolve_reference_base */
|
||||
|
||||
/**
|
||||
* Resolve value corresponding to reference.
|
||||
*
|
||||
* @return value of the reference
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical environment */
|
||||
ecma_string_t *name_p) /**< identifier's name */
|
||||
{
|
||||
JERRY_ASSERT (lex_env_p != NULL);
|
||||
|
||||
while (lex_env_p != NULL)
|
||||
{
|
||||
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
|
||||
{
|
||||
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
|
||||
|
||||
if (property_p != NULL)
|
||||
{
|
||||
return ecma_fast_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
|
||||
|| ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
|
||||
|
||||
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
|
||||
|
||||
ecma_value_t prop_value = ecma_op_object_find (binding_obj_p, name_p);
|
||||
|
||||
if (ecma_is_value_found (prop_value))
|
||||
{
|
||||
return prop_value;
|
||||
}
|
||||
}
|
||||
|
||||
lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
|
||||
}
|
||||
|
||||
return ecma_raise_reference_error (ECMA_ERR_MSG (""));
|
||||
} /* ecma_op_resolve_reference_value */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
37
third_party/jerryscript/jerry-core/ecma/operations/ecma-reference.h
vendored
Normal file
37
third_party/jerryscript/jerry-core/ecma/operations/ecma-reference.h
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_REFERENCE_H
|
||||
#define ECMA_REFERENCE_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
#include "jrt.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup references ECMA-Reference
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern ecma_object_t *ecma_op_resolve_reference_base (ecma_object_t *, ecma_string_t *);
|
||||
extern ecma_value_t ecma_op_resolve_reference_value (ecma_object_t *, ecma_string_t *);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_REFERENCE_H */
|
1463
third_party/jerryscript/jerry-core/ecma/operations/ecma-regexp-object.c
vendored
Normal file
1463
third_party/jerryscript/jerry-core/ecma/operations/ecma-regexp-object.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
70
third_party/jerryscript/jerry-core/ecma/operations/ecma-regexp-object.h
vendored
Normal file
70
third_party/jerryscript/jerry-core/ecma/operations/ecma-regexp-object.h
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* 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 ECMA_REGEXP_OBJECT_H
|
||||
#define ECMA_REGEXP_OBJECT_H
|
||||
|
||||
#ifndef CONFIG_DISABLE_REGEXP_BUILTIN
|
||||
|
||||
#include "ecma-globals.h"
|
||||
#include "re-compiler.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmaregexpobject ECMA RegExp object related routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* RegExp flags
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
RE_FLAG_GLOBAL = (1u << 1), /**< ECMA-262 v5, 15.10.7.2 */
|
||||
RE_FLAG_IGNORE_CASE = (1u << 2), /**< ECMA-262 v5, 15.10.7.3 */
|
||||
RE_FLAG_MULTILINE = (1u << 3) /**< ECMA-262 v5, 15.10.7.4 */
|
||||
} re_flags_t;
|
||||
|
||||
/**
|
||||
* RegExp executor context
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const lit_utf8_byte_t **saved_p; /**< saved result string pointers, ECMA 262 v5, 15.10.2.1, State */
|
||||
const lit_utf8_byte_t *input_start_p; /**< start of input pattern string */
|
||||
const lit_utf8_byte_t *input_end_p; /**< end of input pattern string */
|
||||
uint32_t num_of_captures; /**< number of capture groups */
|
||||
uint32_t num_of_non_captures; /**< number of non-capture groups */
|
||||
uint32_t *num_of_iterations_p; /**< number of iterations */
|
||||
uint16_t flags; /**< RegExp flags */
|
||||
} re_matcher_ctx_t;
|
||||
|
||||
ecma_value_t ecma_op_create_regexp_object_from_bytecode (re_compiled_code_t *);
|
||||
ecma_value_t ecma_op_create_regexp_object (ecma_string_t *, ecma_string_t *);
|
||||
ecma_value_t ecma_regexp_exec_helper (ecma_value_t, ecma_value_t, bool);
|
||||
ecma_char_t re_canonicalize (ecma_char_t, bool);
|
||||
void re_set_result_array_properties (ecma_object_t *, ecma_string_t *, uint32_t, int32_t);
|
||||
ecma_value_t re_parse_regexp_flags (ecma_string_t *, uint16_t *);
|
||||
void re_initialize_props (ecma_object_t *, ecma_string_t *, uint16_t);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
|
||||
#endif /* !ECMA_REGEXP_OBJECT_H */
|
162
third_party/jerryscript/jerry-core/ecma/operations/ecma-string-object.c
vendored
Normal file
162
third_party/jerryscript/jerry-core/ecma/operations/ecma-string-object.c
vendored
Normal file
|
@ -0,0 +1,162 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 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-exceptions.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-string-object.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmastringobject ECMA String object related routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* String object creation operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.5.2.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_create_string_object (const ecma_value_t *arguments_list_p, /**< list of arguments that
|
||||
are passed to String constructor */
|
||||
ecma_length_t arguments_list_len) /**< length of the arguments' list */
|
||||
{
|
||||
JERRY_ASSERT (arguments_list_len == 0
|
||||
|| arguments_list_p != NULL);
|
||||
|
||||
ecma_string_t *prim_prop_str_value_p;
|
||||
|
||||
ecma_number_t length_value;
|
||||
|
||||
if (arguments_list_len == 0)
|
||||
{
|
||||
prim_prop_str_value_p = ecma_new_ecma_string_from_magic_string_id (LIT_MAGIC_STRING__EMPTY);
|
||||
length_value = ECMA_NUMBER_ZERO;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_value_t to_str_arg_value = ecma_op_to_string (arguments_list_p[0]);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (to_str_arg_value))
|
||||
{
|
||||
return to_str_arg_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (to_str_arg_value));
|
||||
JERRY_ASSERT (ecma_is_value_string (to_str_arg_value));
|
||||
|
||||
prim_prop_str_value_p = ecma_get_string_from_value (to_str_arg_value);
|
||||
|
||||
ecma_length_t string_len = ecma_string_get_length (prim_prop_str_value_p);
|
||||
length_value = ((ecma_number_t) (uint32_t) string_len);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DISABLE_STRING_BUILTIN
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_STRING_PROTOTYPE);
|
||||
#else /* CONFIG_DISABLE_STRING_BUILTIN */
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
#endif /* !CONFIG_DISABLE_STRING_BUILTIN */
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p,
|
||||
false,
|
||||
true,
|
||||
ECMA_OBJECT_TYPE_STRING);
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
|
||||
/*
|
||||
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_STRING type.
|
||||
*
|
||||
* See also: ecma_object_get_class_name
|
||||
*/
|
||||
|
||||
ecma_value_t *prim_value_prop_p = ecma_create_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
|
||||
*prim_value_prop_p = ecma_make_string_value (prim_prop_str_value_p);
|
||||
|
||||
// 15.5.5.1
|
||||
ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string ();
|
||||
ecma_property_value_t *length_prop_value_p = ecma_create_named_data_property (obj_p,
|
||||
length_magic_string_p,
|
||||
ECMA_PROPERTY_FIXED,
|
||||
NULL);
|
||||
ecma_deref_ecma_string (length_magic_string_p);
|
||||
|
||||
length_prop_value_p->value = ecma_make_number_value (length_value);
|
||||
|
||||
return ecma_make_object_value (obj_p);
|
||||
} /* ecma_op_create_string_object */
|
||||
|
||||
/**
|
||||
* List names of a String object's lazy instantiated properties
|
||||
*
|
||||
* @return string values collection
|
||||
*/
|
||||
void
|
||||
ecma_op_string_list_lazy_property_names (ecma_object_t *obj_p, /**< a String object */
|
||||
bool separate_enumerable, /**< true - list enumerable properties
|
||||
* into main collection,
|
||||
* and non-enumerable to collection of
|
||||
* 'skipped non-enumerable' properties,
|
||||
* false - list all properties into main
|
||||
* collection.
|
||||
*/
|
||||
ecma_collection_header_t *main_collection_p, /**< 'main'
|
||||
* collection */
|
||||
ecma_collection_header_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection
|
||||
*/
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_STRING);
|
||||
|
||||
ecma_collection_header_t *for_enumerable_p = main_collection_p;
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? main_collection_p : non_enum_collection_p;
|
||||
JERRY_UNUSED (for_non_enumerable_p);
|
||||
|
||||
ecma_value_t *prim_value_p = ecma_get_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
|
||||
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (*prim_value_p);
|
||||
|
||||
ecma_length_t length = ecma_string_get_length (prim_value_str_p);
|
||||
|
||||
for (ecma_length_t i = 0; i < length; i++)
|
||||
{
|
||||
ecma_string_t *name_p = ecma_new_ecma_string_from_uint32 (i);
|
||||
|
||||
/* the properties are enumerable (ECMA-262 v5, 15.5.5.2.9) */
|
||||
ecma_append_to_values_collection (for_enumerable_p, ecma_make_string_value (name_p), true);
|
||||
|
||||
ecma_deref_ecma_string (name_p);
|
||||
}
|
||||
} /* ecma_op_string_list_lazy_property_names */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
43
third_party/jerryscript/jerry-core/ecma/operations/ecma-string-object.h
vendored
Normal file
43
third_party/jerryscript/jerry-core/ecma/operations/ecma-string-object.h
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_STRING_OBJECT_H
|
||||
#define ECMA_STRING_OBJECT_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmastringobject ECMA String object related routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern ecma_value_t
|
||||
ecma_op_create_string_object (const ecma_value_t *, ecma_length_t);
|
||||
|
||||
extern void
|
||||
ecma_op_string_list_lazy_property_names (ecma_object_t *,
|
||||
bool,
|
||||
ecma_collection_header_t *,
|
||||
ecma_collection_header_t *);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_STRING_OBJECT_H */
|
101
third_party/jerryscript/jerry-core/ecma/operations/ecma-try-catch-macro.h
vendored
Normal file
101
third_party/jerryscript/jerry-core/ecma/operations/ecma-try-catch-macro.h
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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 ECMA_TRY_CATCH_MACRO_H
|
||||
#define ECMA_TRY_CATCH_MACRO_H
|
||||
|
||||
#include "ecma-helpers.h"
|
||||
|
||||
/**
|
||||
* The macro defines try-block that initializes variable 'var' with 'op'
|
||||
* and checks for exceptions that might be thrown during initialization.
|
||||
*
|
||||
* If no exception was thrown, then code after the try-block is executed.
|
||||
* Otherwise, throw-completion value is just copied to return_value.
|
||||
*
|
||||
* Note:
|
||||
* Each ECMA_TRY_CATCH should have it's own corresponding ECMA_FINALIZE
|
||||
* statement with same argument as corresponding ECMA_TRY_CATCH's first argument.
|
||||
*/
|
||||
#define ECMA_TRY_CATCH(var, op, return_value) \
|
||||
JERRY_ASSERT (return_value == ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY)); \
|
||||
ecma_value_t var ## _completion = op; \
|
||||
if (ECMA_IS_VALUE_ERROR (var ## _completion)) \
|
||||
{ \
|
||||
return_value = var ## _completion; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ecma_value_t var = var ## _completion; \
|
||||
JERRY_UNUSED (var);
|
||||
|
||||
/**
|
||||
* The macro marks end of code block that is defined by corresponding
|
||||
* ECMA_TRY_CATCH and frees variable, initialized by the ECMA_TRY_CATCH.
|
||||
*
|
||||
* Note:
|
||||
* Each ECMA_TRY_CATCH should be followed by ECMA_FINALIZE with same argument
|
||||
* as corresponding ECMA_TRY_CATCH's first argument.
|
||||
*/
|
||||
#define ECMA_FINALIZE(var) \
|
||||
ecma_free_value (var ## _completion); \
|
||||
}
|
||||
|
||||
/**
|
||||
* The macro defines try-block that tries to perform ToNumber operation on given value
|
||||
* and checks for exceptions that might be thrown during the operation.
|
||||
*
|
||||
* If no exception was thrown, then code after the try-block is executed.
|
||||
* Otherwise, throw-completion value is just copied to return_value.
|
||||
*
|
||||
* Note:
|
||||
* Each ECMA_OP_TO_NUMBER_TRY_CATCH should have it's own corresponding ECMA_OP_TO_NUMBER_FINALIZE
|
||||
* statement with same argument as corresponding ECMA_OP_TO_NUMBER_TRY_CATCH's first argument.
|
||||
*/
|
||||
#define ECMA_OP_TO_NUMBER_TRY_CATCH(num_var, value, return_value) \
|
||||
JERRY_ASSERT (return_value == ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY)); \
|
||||
ecma_number_t num_var = ecma_number_make_nan (); \
|
||||
if (ecma_is_value_number (value)) \
|
||||
{ \
|
||||
num_var = ecma_get_number_from_value (value); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ECMA_TRY_CATCH (to_number_value, \
|
||||
ecma_op_to_number (value), \
|
||||
return_value); \
|
||||
\
|
||||
num_var = ecma_get_number_from_value (to_number_value); \
|
||||
\
|
||||
ECMA_FINALIZE (to_number_value); \
|
||||
} \
|
||||
\
|
||||
if (ecma_is_value_empty (return_value)) \
|
||||
{
|
||||
|
||||
/**
|
||||
* The macro marks end of code block that is defined by corresponding ECMA_OP_TO_NUMBER_TRY_CATCH.
|
||||
*
|
||||
* Note:
|
||||
* Each ECMA_OP_TO_NUMBER_TRY_CATCH should be followed by ECMA_OP_TO_NUMBER_FINALIZE
|
||||
* with same argument as corresponding ECMA_OP_TO_NUMBER_TRY_CATCH's first argument.
|
||||
*/
|
||||
#define ECMA_OP_TO_NUMBER_FINALIZE(num_var) } \
|
||||
else \
|
||||
{ \
|
||||
JERRY_ASSERT (ecma_number_is_nan (num_var)); \
|
||||
}
|
||||
|
||||
#endif /* !ECMA_TRY_CATCH_MACRO_H */
|
Loading…
Add table
Add a link
Reference in a new issue