Import of the watch repository from Pebble

This commit is contained in:
Matthieu Jeanson 2024-12-12 16:43:03 -08:00 committed by Katharine Berry
commit 3b92768480
10334 changed files with 2564465 additions and 0 deletions

View file

@ -0,0 +1,146 @@
/* 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.
*/
#ifndef CONFIG_H
#define CONFIG_H
/**
* Limit of data (system heap, engine's data except engine's own heap)
*/
#define CONFIG_MEM_DATA_LIMIT_MINUS_HEAP_SIZE (1024)
/**
* Limit of stack size
*/
#define CONFIG_MEM_STACK_LIMIT (4096)
/**
* Size of pool chunk
*
* Should not be less than size of any of ECMA Object Model's data types.
*/
#define CONFIG_MEM_POOL_CHUNK_SIZE (8)
/**
* Size of heap
*/
#ifndef CONFIG_MEM_HEAP_AREA_SIZE
# define CONFIG_MEM_HEAP_AREA_SIZE (512 * 1024)
#endif /* !CONFIG_MEM_HEAP_AREA_SIZE */
/**
* Max heap usage limit
*/
#define CONFIG_MEM_HEAP_MAX_LIMIT 8192
/**
* Desired limit of heap usage
*/
#define CONFIG_MEM_HEAP_DESIRED_LIMIT (JERRY_MIN (CONFIG_MEM_HEAP_AREA_SIZE / 32, CONFIG_MEM_HEAP_MAX_LIMIT))
/**
* Number of lower bits in key of literal hash table.
*/
#define CONFIG_LITERAL_HASH_TABLE_KEY_BITS (7)
/**
* Width of fields used for holding counter of references to ecma-strings and ecma-objects
*
* The option affects maximum number of simultaneously existing:
* - references to one string;
* - stack references to one object
* The number is ((2 ^ CONFIG_ECMA_REFERENCE_COUNTER_WIDTH) - 1).
*
* Also the option affects size of ECMA Object Model's data types.
* In any case size of any of the types should not exceed CONFIG_MEM_POOL_CHUNK_SIZE.
*/
#define CONFIG_ECMA_REFERENCE_COUNTER_WIDTH (12)
#define CONFIG_ECMA_REFERENCE_COUNTER_LIMIT ((1u << CONFIG_ECMA_REFERENCE_COUNTER_WIDTH) - 1u)
/**
* Use 32-bit/64-bit float for ecma-numbers
*/
#define CONFIG_ECMA_NUMBER_FLOAT32 (1u) /* 32-bit float */
#define CONFIG_ECMA_NUMBER_FLOAT64 (2u) /* 64-bit float */
#ifndef CONFIG_ECMA_NUMBER_TYPE
# define CONFIG_ECMA_NUMBER_TYPE CONFIG_ECMA_NUMBER_FLOAT64
#else /* CONFIG_ECMA_NUMBER_TYPE */
# if (CONFIG_ECMA_NUMBER_TYPE != CONFIG_ECMA_NUMBER_FLOAT32 \
&& CONFIG_ECMA_NUMBER_TYPE != CONFIG_ECMA_NUMBER_FLOAT64)
# error "ECMA-number storage is configured incorrectly"
# endif /* CONFIG_ECMA_NUMBER_TYPE != CONFIG_ECMA_NUMBER_FLOAT32
&& CONFIG_ECMA_NUMBER_TYPE != CONFIG_ECMA_NUMBER_FLOAT64 */
#endif /* !CONFIG_ECMA_NUMBER_TYPE */
/**
* Representation for ecma-characters
*/
#define CONFIG_ECMA_CHAR_ASCII (1) /* ASCII */
#define CONFIG_ECMA_CHAR_UTF16 (2) /* UTF-16 */
#ifndef CONFIG_ECMA_CHAR_ENCODING
# define CONFIG_ECMA_CHAR_ENCODING CONFIG_ECMA_CHAR_ASCII
#else /* CONFIG_ECMA_CHAR_ENCODING */
# if (CONFIG_ECMA_CHAR_ENCODING != CONFIG_ECMA_CHAR_ASCII \
&& CONFIG_ECMA_CHAR_ENCODING != CONFIG_ECMA_CHAR_UTF16)
# error "ECMA-char encoding is configured incorrectly"
# endif /* CONFIG_ECMA_CHAR_ENCODING != CONFIG_ECMA_CHAR_ASCII
&& CONFIG_ECMA_CHAR_ENCODING != CONFIG_ECMA_CHAR_UTF16 */
#endif /* !CONFIG_ECMA_CHAR_ENCODING */
/**
* Disable ECMA lookup cache
*/
// #define CONFIG_ECMA_LCACHE_DISABLE
/**
* Disable ECMA property hashmap
*/
// #define CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
/**
* Share of newly allocated since last GC objects among all currently allocated objects,
* after achieving which, GC is started upon low severity try-give-memory-back requests.
*
* Share is calculated as the following:
* 1.0 / CONFIG_ECMA_GC_NEW_OBJECTS_SHARE_TO_START_GC
*/
#define CONFIG_ECMA_GC_NEW_OBJECTS_SHARE_TO_START_GC (16)
/**
* Link Global Environment to an empty declarative lexical environment
* instead of lexical environment bound to Global Object.
*/
// #define CONFIG_ECMA_GLOBAL_ENVIRONMENT_DECLARATIVE
/**
* Number of ecma values inlined into VM stack frame
*/
#define CONFIG_VM_STACK_FRAME_INLINED_VALUES_NUMBER (16)
/**
* Run GC after execution of each byte-code instruction
*/
// #define CONFIG_VM_RUN_GC_AFTER_EACH_OPCODE
/**
* Flag, indicating whether to enable parser-time byte-code optimizations
*/
#define CONFIG_PARSER_ENABLE_PARSE_TIME_BYTE_CODE_OPTIMIZER
#endif /* !CONFIG_H */

View file

@ -0,0 +1,132 @@
/* 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-globals.h"
#include "ecma-gc.h"
#include "ecma-lcache.h"
#include "jrt.h"
#include "jmem-poolman.h"
JERRY_STATIC_ASSERT (sizeof (ecma_property_value_t) == sizeof (ecma_value_t),
size_of_ecma_property_value_t_must_be_equal_to_size_of_ecma_value_t);
JERRY_STATIC_ASSERT (((sizeof (ecma_property_value_t) - 1) & sizeof (ecma_property_value_t)) == 0,
size_of_ecma_property_value_t_must_be_power_of_2);
JERRY_STATIC_ASSERT (sizeof (ecma_string_t) == sizeof (uint64_t),
size_of_ecma_string_t_must_be_less_than_or_equal_to_8_bytes);
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmaalloc Routines for allocation/freeing memory for ECMA data types
* @{
*/
/**
* Implementation of routines for allocation/freeing memory for ECMA data types.
*
* All allocation routines from this module have the same structure:
* 1. Try to allocate memory.
* 2. If allocation was successful, return pointer to the allocated block.
* 3. Run garbage collection.
* 4. Try to allocate memory.
* 5. If allocation was successful, return pointer to the allocated block;
* else - shutdown engine.
*/
/**
* Template of an allocation routine.
*/
#define ALLOC(ecma_type) ecma_ ## ecma_type ## _t * \
ecma_alloc_ ## ecma_type (void) \
{ \
ecma_ ## ecma_type ## _t *ecma_type ## _p; \
ecma_type ## _p = (ecma_ ## ecma_type ## _t *) jmem_pools_alloc (sizeof (ecma_ ## ecma_type ## _t)); \
\
JERRY_ASSERT (ecma_type ## _p != NULL); \
\
return ecma_type ## _p; \
}
/**
* Deallocation routine template
*/
#define DEALLOC(ecma_type) void \
ecma_dealloc_ ## ecma_type (ecma_ ## ecma_type ## _t *ecma_type ## _p) \
{ \
jmem_pools_free ((uint8_t *) ecma_type ## _p, sizeof (ecma_ ## ecma_type ## _t)); \
}
/**
* Declaration of alloc/free routine for specified ecma-type.
*/
#define DECLARE_ROUTINES_FOR(ecma_type) \
ALLOC (ecma_type) \
DEALLOC (ecma_type)
DECLARE_ROUTINES_FOR (object)
DECLARE_ROUTINES_FOR (number)
DECLARE_ROUTINES_FOR (collection_header)
DECLARE_ROUTINES_FOR (collection_chunk)
DECLARE_ROUTINES_FOR (string)
DECLARE_ROUTINES_FOR (getter_setter_pointers)
DECLARE_ROUTINES_FOR (external_pointer)
/**
* Allocate memory for extended object
*
* @return pointer to allocated memory
*/
inline ecma_extended_object_t * __attr_always_inline___
ecma_alloc_extended_object (void)
{
return jmem_heap_alloc_block (sizeof (ecma_extended_object_t));
} /* ecma_alloc_extended_object */
/**
* Dealloc memory of an extended object
*/
inline void __attr_always_inline___
ecma_dealloc_extended_object (ecma_extended_object_t *ext_object_p) /**< property pair to be freed */
{
jmem_heap_free_block (ext_object_p, sizeof (ecma_extended_object_t));
} /* ecma_dealloc_extended_object */
/**
* Allocate memory for ecma-property pair
*
* @return pointer to allocated memory
*/
inline ecma_property_pair_t * __attr_always_inline___
ecma_alloc_property_pair (void)
{
return jmem_heap_alloc_block (sizeof (ecma_property_pair_t));
} /* ecma_alloc_property_pair */
/**
* Dealloc memory of an ecma-property
*/
inline void __attr_always_inline___
ecma_dealloc_property_pair (ecma_property_pair_t *property_pair_p) /**< property pair to be freed */
{
jmem_heap_free_block (property_pair_p, sizeof (ecma_property_pair_t));
} /* ecma_dealloc_property_pair */
/**
* @}
* @}
*/

View file

@ -0,0 +1,141 @@
/* 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_ALLOC_H
#define ECMA_ALLOC_H
#include "ecma-globals.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmaalloc Routines for allocation/freeing memory for ECMA data types
* @{
*/
/**
* Allocate memory for ecma-object
*
* @return pointer to allocated memory
*/
extern ecma_object_t *ecma_alloc_object (void);
/**
* Dealloc memory from an ecma-object
*/
extern void ecma_dealloc_object (ecma_object_t *);
/**
* Allocate memory for ecma-number
*
* @return pointer to allocated memory
*/
extern ecma_number_t *ecma_alloc_number (void);
/**
* Dealloc memory from an ecma-number
*/
extern void ecma_dealloc_number (ecma_number_t *);
/**
* Allocate memory for header of a collection
*
* @return pointer to allocated memory
*/
extern ecma_collection_header_t *ecma_alloc_collection_header (void);
/**
* Dealloc memory from the collection's header
*/
extern void ecma_dealloc_collection_header (ecma_collection_header_t *);
/**
* Allocate memory for non-first chunk of a collection
*
* @return pointer to allocated memory
*/
extern ecma_collection_chunk_t *ecma_alloc_collection_chunk (void);
/**
* Dealloc memory from non-first chunk of a collection
*/
extern void ecma_dealloc_collection_chunk (ecma_collection_chunk_t *);
/**
* Allocate memory for ecma-string descriptor
*
* @return pointer to allocated memory
*/
extern ecma_string_t *ecma_alloc_string (void);
/**
* Dealloc memory from ecma-string descriptor
*/
extern void ecma_dealloc_string (ecma_string_t *);
/**
* Allocate memory for getter-setter pointer pair
*
* @return pointer to allocated memory
*/
extern ecma_getter_setter_pointers_t *ecma_alloc_getter_setter_pointers (void);
/**
* Dealloc memory from getter-setter pointer pair
*/
extern void ecma_dealloc_getter_setter_pointers (ecma_getter_setter_pointers_t *);
/**
* Allocate memory for external pointer
*
* @return pointer to allocated memory
*/
extern ecma_external_pointer_t *ecma_alloc_external_pointer (void);
/**
* Dealloc memory from external pointer
*/
extern void ecma_dealloc_external_pointer (ecma_external_pointer_t *);
/*
* Allocate memory for extended object
*
* @return pointer to allocated memory
*/
extern ecma_extended_object_t *ecma_alloc_extended_object (void);
/**
* Dealloc memory of an extended object
*/
extern void ecma_dealloc_extended_object (ecma_extended_object_t *);
/**
* Allocate memory for ecma-property pair
*
* @return pointer to allocated memory
*/
extern ecma_property_pair_t *ecma_alloc_property_pair (void);
/**
* Dealloc memory from an ecma-property pair
*/
extern void ecma_dealloc_property_pair (ecma_property_pair_t *);
/**
* @}
* @}
*/
#endif /* !ECMA_ALLOC_H */

View file

@ -0,0 +1,615 @@
/* 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.
*/
/**
* Garbage collector implementation
*/
#include "ecma-alloc.h"
#include "ecma-globals.h"
#include "ecma-gc.h"
#include "ecma-helpers.h"
#include "ecma-lcache.h"
#include "ecma-property-hashmap.h"
#include "jcontext.h"
#include "jrt.h"
#include "jrt-libc-includes.h"
#include "jrt-bit-fields.h"
#include "re-compiler.h"
#include "vm-defines.h"
#include "vm-stack.h"
#define JERRY_INTERNAL
#include "jerry-internal.h"
/* TODO: Extract GC to a separate component */
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmagc Garbage collector
* @{
*/
/**
* Current state of an object's visited flag that
* indicates whether the object is in visited state:
*
* visited_field | visited_flip_flag | real_value
* false | false | false
* false | true | true
* true | false | true
* true | true | false
*/
static void ecma_gc_mark (ecma_object_t *object_p);
static void ecma_gc_sweep (ecma_object_t *object_p);
/**
* Get next object in list of objects with same generation.
*/
static inline ecma_object_t *
ecma_gc_get_object_next (ecma_object_t *object_p) /**< object */
{
JERRY_ASSERT (object_p != NULL);
return ECMA_GET_POINTER (ecma_object_t, object_p->gc_next_cp);
} /* ecma_gc_get_object_next */
/**
* Set next object in list of objects with same generation.
*/
static inline void
ecma_gc_set_object_next (ecma_object_t *object_p, /**< object */
ecma_object_t *next_object_p) /**< next object */
{
JERRY_ASSERT (object_p != NULL);
ECMA_SET_POINTER (object_p->gc_next_cp, next_object_p);
} /* ecma_gc_set_object_next */
/**
* Get visited flag of the object.
*/
static inline bool
ecma_gc_is_object_visited (ecma_object_t *object_p) /**< object */
{
JERRY_ASSERT (object_p != NULL);
bool flag_value = (object_p->type_flags_refs & ECMA_OBJECT_FLAG_GC_VISITED) != 0;
return flag_value != JERRY_CONTEXT (ecma_gc_visited_flip_flag);
} /* ecma_gc_is_object_visited */
/**
* Set visited flag of the object.
*/
static inline void
ecma_gc_set_object_visited (ecma_object_t *object_p, /**< object */
bool is_visited) /**< flag value */
{
JERRY_ASSERT (object_p != NULL);
if (is_visited != JERRY_CONTEXT (ecma_gc_visited_flip_flag))
{
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs | ECMA_OBJECT_FLAG_GC_VISITED);
}
else
{
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs & ~ECMA_OBJECT_FLAG_GC_VISITED);
}
} /* ecma_gc_set_object_visited */
/**
* Initialize GC information for the object
*/
inline void
ecma_init_gc_info (ecma_object_t *object_p) /**< object */
{
JERRY_CONTEXT (ecma_gc_objects_number)++;
JERRY_CONTEXT (ecma_gc_new_objects)++;
JERRY_ASSERT (JERRY_CONTEXT (ecma_gc_new_objects) <= JERRY_CONTEXT (ecma_gc_objects_number));
JERRY_ASSERT (object_p->type_flags_refs < ECMA_OBJECT_REF_ONE);
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs | ECMA_OBJECT_REF_ONE);
ecma_gc_set_object_next (object_p, JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_WHITE_GRAY]);
JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_WHITE_GRAY] = object_p;
/* Should be set to false at the beginning of garbage collection */
ecma_gc_set_object_visited (object_p, false);
} /* ecma_init_gc_info */
/**
* Increase reference counter of an object
*/
void
ecma_ref_object (ecma_object_t *object_p) /**< object */
{
if (likely (object_p->type_flags_refs < ECMA_OBJECT_MAX_REF))
{
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs + ECMA_OBJECT_REF_ONE);
}
else
{
jerry_fatal (ERR_REF_COUNT_LIMIT);
}
} /* ecma_ref_object */
/**
* Decrease reference counter of an object
*/
void
ecma_deref_object (ecma_object_t *object_p) /**< object */
{
JERRY_ASSERT (object_p->type_flags_refs >= ECMA_OBJECT_REF_ONE);
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs - ECMA_OBJECT_REF_ONE);
} /* ecma_deref_object */
/**
* Mark referenced object from property
*/
static void
ecma_gc_mark_property (ecma_property_t *property_p) /**< property */
{
switch (ECMA_PROPERTY_GET_TYPE (*property_p))
{
case ECMA_PROPERTY_TYPE_NAMEDDATA:
{
ecma_value_t value = ECMA_PROPERTY_VALUE_PTR (property_p)->value;
if (ecma_is_value_object (value))
{
ecma_object_t *value_obj_p = ecma_get_object_from_value (value);
ecma_gc_set_object_visited (value_obj_p, true);
}
break;
}
case ECMA_PROPERTY_TYPE_NAMEDACCESSOR:
{
ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
ecma_object_t *getter_obj_p = ecma_get_named_accessor_property_getter (prop_value_p);
ecma_object_t *setter_obj_p = ecma_get_named_accessor_property_setter (prop_value_p);
if (getter_obj_p != NULL)
{
ecma_gc_set_object_visited (getter_obj_p, true);
}
if (setter_obj_p != NULL)
{
ecma_gc_set_object_visited (setter_obj_p, true);
}
break;
}
case ECMA_PROPERTY_TYPE_INTERNAL:
{
uint32_t property_value = ECMA_PROPERTY_VALUE_PTR (property_p)->value;
switch (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (property_p))
{
case ECMA_INTERNAL_PROPERTY_ECMA_VALUE: /* an ecma_value_t except object */
case ECMA_INTERNAL_PROPERTY_DATE_FLOAT: /* pointer to a ecma_number_t */
case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */
case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE: /* pointer to a regexp bytecode array */
case ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE: /* an external pointer */
case ECMA_INTERNAL_PROPERTY_FREE_CALLBACK: /* an object's native free callback */
case ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63: /* an integer (bit-mask) */
{
break;
}
case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_THIS: /* an ecma value */
{
if (ecma_is_value_object (property_value))
{
ecma_object_t *obj_p = ecma_get_object_from_value (property_value);
ecma_gc_set_object_visited (obj_p, true);
}
break;
}
case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS: /* a collection of ecma values */
{
ecma_collection_header_t *bound_arg_list_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_header_t,
property_value);
ecma_collection_iterator_t bound_args_iterator;
ecma_collection_iterator_init (&bound_args_iterator, bound_arg_list_p);
for (ecma_length_t i = 0; i < bound_arg_list_p->unit_number; i++)
{
bool is_moved = ecma_collection_iterator_next (&bound_args_iterator);
JERRY_ASSERT (is_moved);
if (ecma_is_value_object (*bound_args_iterator.current_value_p))
{
ecma_object_t *obj_p = ecma_get_object_from_value (*bound_args_iterator.current_value_p);
ecma_gc_set_object_visited (obj_p, true);
}
}
break;
}
case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION: /* an object */
case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */
case ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP: /* an object */
{
ecma_object_t *obj_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, property_value);
ecma_gc_set_object_visited (obj_p, true);
break;
}
case ECMA_INTERNAL_PROPERTY__COUNT: /* not a real internal property type,
* but number of the real internal property types */
{
JERRY_UNREACHABLE ();
break;
}
}
break;
}
default:
{
JERRY_UNREACHABLE ();
break;
}
}
} /* ecma_gc_mark_property */
/**
* Mark objects as visited starting from specified object as root
*/
void
ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
{
JERRY_ASSERT (object_p != NULL);
JERRY_ASSERT (ecma_gc_is_object_visited (object_p));
bool traverse_properties = true;
if (ecma_is_lexical_environment (object_p))
{
ecma_object_t *lex_env_p = ecma_get_lex_env_outer_reference (object_p);
if (lex_env_p != NULL)
{
ecma_gc_set_object_visited (lex_env_p, true);
}
if (ecma_get_lex_env_type (object_p) != ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
{
ecma_object_t *binding_object_p = ecma_get_lex_env_binding_object (object_p);
ecma_gc_set_object_visited (binding_object_p, true);
traverse_properties = false;
}
}
else
{
ecma_object_t *proto_p = ecma_get_object_prototype (object_p);
if (proto_p != NULL)
{
ecma_gc_set_object_visited (proto_p, true);
}
if (!ecma_get_object_is_builtin (object_p)
&& ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
{
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
ecma_object_t *scope_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
ext_func_p->u.function.scope_cp);
ecma_gc_set_object_visited (scope_p, true);
}
}
if (traverse_properties)
{
ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);
if (prop_iter_p != NULL
&& ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP)
{
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
prop_iter_p->next_property_cp);
}
while (prop_iter_p != NULL)
{
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
if (prop_iter_p->types[0] != ECMA_PROPERTY_TYPE_DELETED)
{
ecma_gc_mark_property (prop_iter_p->types + 0);
}
if (prop_iter_p->types[1] != ECMA_PROPERTY_TYPE_DELETED)
{
ecma_gc_mark_property (prop_iter_p->types + 1);
}
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
prop_iter_p->next_property_cp);
}
}
} /* ecma_gc_mark */
/**
* Free specified object
*/
void
ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
{
JERRY_ASSERT (object_p != NULL
&& !ecma_gc_is_object_visited (object_p)
&& object_p->type_flags_refs < ECMA_OBJECT_REF_ONE);
if (!ecma_is_lexical_environment (object_p))
{
/* if the object provides free callback, invoke it with handle stored in the object */
ecma_external_pointer_t freecb_p;
ecma_external_pointer_t native_p;
bool is_retrieved = ecma_get_external_pointer_value (object_p,
ECMA_INTERNAL_PROPERTY_FREE_CALLBACK,
&freecb_p);
if (is_retrieved && ((jerry_object_free_callback_t) freecb_p) != NULL)
{
is_retrieved = ecma_get_external_pointer_value (object_p,
ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE,
&native_p);
JERRY_ASSERT (is_retrieved);
jerry_dispatch_object_free_callback (freecb_p, native_p);
}
}
if (!ecma_is_lexical_environment (object_p)
|| ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
{
ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);
if (prop_iter_p != NULL
&& ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP)
{
ecma_property_hashmap_free (object_p);
prop_iter_p = ecma_get_property_list (object_p);
}
while (prop_iter_p != NULL)
{
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
/* Both cannot be deleted. */
JERRY_ASSERT (prop_iter_p->types[0] != ECMA_PROPERTY_TYPE_DELETED
|| prop_iter_p->types[1] != ECMA_PROPERTY_TYPE_DELETED);
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
if (prop_iter_p->types[i] != ECMA_PROPERTY_TYPE_DELETED)
{
ecma_string_t *name_p = ECMA_GET_POINTER (ecma_string_t, prop_pair_p->names_cp[i]);
ecma_free_property (object_p, name_p, prop_iter_p->types + i);
if (name_p != NULL)
{
ecma_deref_ecma_string (name_p);
}
}
}
/* Both must be deleted. */
JERRY_ASSERT (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_DELETED
&& prop_iter_p->types[1] == ECMA_PROPERTY_TYPE_DELETED);
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
prop_iter_p->next_property_cp);
ecma_dealloc_property_pair (prop_pair_p);
}
}
JERRY_ASSERT (JERRY_CONTEXT (ecma_gc_objects_number) > 0);
JERRY_CONTEXT (ecma_gc_objects_number)--;
if (!ecma_is_lexical_environment (object_p))
{
if (ecma_get_object_is_builtin (object_p)
|| ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
{
ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p);
return;
}
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
{
/* Function with byte-code (not a built-in function). */
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
ecma_bytecode_deref (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
ext_func_p->u.function.bytecode_cp));
ecma_dealloc_extended_object (ext_func_p);
return;
}
}
ecma_dealloc_object (object_p);
} /* ecma_gc_sweep */
/**
* Run garbage collection
*/
void
ecma_gc_run (jmem_free_unused_memory_severity_t severity) /**< gc severity */
{
JERRY_CONTEXT (ecma_gc_new_objects) = 0;
JERRY_ASSERT (JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_BLACK] == NULL);
/* if some object is referenced from stack or globals (i.e. it is root), mark it */
for (ecma_object_t *obj_iter_p = JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_WHITE_GRAY];
obj_iter_p != NULL;
obj_iter_p = ecma_gc_get_object_next (obj_iter_p))
{
JERRY_ASSERT (!ecma_gc_is_object_visited (obj_iter_p));
if (obj_iter_p->type_flags_refs >= ECMA_OBJECT_REF_ONE)
{
ecma_gc_set_object_visited (obj_iter_p, true);
}
}
bool marked_anything_during_current_iteration = false;
do
{
marked_anything_during_current_iteration = false;
ecma_object_t *obj_prev_p = NULL;
ecma_object_t *obj_iter_p = JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_WHITE_GRAY];
while (obj_iter_p != NULL)
{
ecma_object_t *obj_next_p = ecma_gc_get_object_next (obj_iter_p);
if (ecma_gc_is_object_visited (obj_iter_p))
{
/* Moving the object to list of marked objects */
ecma_gc_set_object_next (obj_iter_p, JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_BLACK]);
JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_BLACK] = obj_iter_p;
if (likely (obj_prev_p != NULL))
{
JERRY_ASSERT (ecma_gc_get_object_next (obj_prev_p) == obj_iter_p);
ecma_gc_set_object_next (obj_prev_p, obj_next_p);
}
else
{
JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_WHITE_GRAY] = obj_next_p;
}
ecma_gc_mark (obj_iter_p);
marked_anything_during_current_iteration = true;
}
else
{
obj_prev_p = obj_iter_p;
}
obj_iter_p = obj_next_p;
}
}
while (marked_anything_during_current_iteration);
/* Sweeping objects that are currently unmarked */
ecma_object_t *obj_iter_p = JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_WHITE_GRAY];
while (obj_iter_p != NULL)
{
ecma_object_t *obj_next_p = ecma_gc_get_object_next (obj_iter_p);
JERRY_ASSERT (!ecma_gc_is_object_visited (obj_iter_p));
ecma_gc_sweep (obj_iter_p);
obj_iter_p = obj_next_p;
}
if (severity == JMEM_FREE_UNUSED_MEMORY_SEVERITY_HIGH)
{
/* Remove the property hashmap of BLACK objects */
obj_iter_p = JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_BLACK];
while (obj_iter_p != NULL)
{
JERRY_ASSERT (ecma_gc_is_object_visited (obj_iter_p));
if (!ecma_is_lexical_environment (obj_iter_p)
|| ecma_get_lex_env_type (obj_iter_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
{
ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_iter_p);
if (prop_iter_p != NULL
&& ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP)
{
ecma_property_hashmap_free (obj_iter_p);
}
}
obj_iter_p = ecma_gc_get_object_next (obj_iter_p);
}
}
/* Unmarking all objects */
ecma_object_t *black_objects = JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_BLACK];
JERRY_CONTEXT (ecma_gc_objects_lists)[ECMA_GC_COLOR_WHITE_GRAY] = black_objects;
JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_BLACK] = NULL;
JERRY_CONTEXT (ecma_gc_visited_flip_flag) = !JERRY_CONTEXT (ecma_gc_visited_flip_flag);
#ifndef CONFIG_DISABLE_REGEXP_BUILTIN
/* Free RegExp bytecodes stored in cache */
re_cache_gc_run ();
#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
} /* ecma_gc_run */
/**
* Try to free some memory (depending on severity).
*/
void
ecma_free_unused_memory (jmem_free_unused_memory_severity_t severity, /**< severity of the request */
size_t requested_size_bytes, /**< number of bytes to be allocated */
bool fatal_if_not_freed) /**< run-time will terminate if not enough memory is freed */
{
if (severity == JMEM_FREE_UNUSED_MEMORY_SEVERITY_LOW)
{
/*
* If there is enough newly allocated objects since last GC, probably it is worthwhile to start GC now.
* Otherwise, probability to free sufficient space is considered to be low.
*/
size_t new_objects_share = CONFIG_ECMA_GC_NEW_OBJECTS_SHARE_TO_START_GC;
if (JERRY_CONTEXT (ecma_gc_new_objects) * new_objects_share > JERRY_CONTEXT (ecma_gc_objects_number))
{
ecma_gc_run (severity);
}
}
else
{
JERRY_ASSERT (severity == JMEM_FREE_UNUSED_MEMORY_SEVERITY_HIGH);
/* Freeing as much memory as we currently can */
ecma_gc_run (severity);
}
} /* ecma_free_unused_memory */
/**
* @}
* @}
*/

View file

@ -0,0 +1,40 @@
/* 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_GC_H
#define ECMA_GC_H
#include "ecma-globals.h"
#include "jmem-allocator.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmagc Garbage collector
* @{
*/
extern void ecma_init_gc_info (ecma_object_t *);
extern void ecma_ref_object (ecma_object_t *);
extern void ecma_deref_object (ecma_object_t *);
extern void ecma_gc_run (jmem_free_unused_memory_severity_t);
extern void ecma_free_unused_memory (jmem_free_unused_memory_severity_t, size_t, bool);
/**
* @}
* @}
*/
#endif /* !ECMA_GC_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,237 @@
/* Copyright 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.
*
* This file is based on work under the following copyright and permission
* notice:
*
* Copyright (c) 2016 Marc Andrysco
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <math.h>
#include "config.h"
#include "ecma-helpers.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmahelpers Helpers for operations with ECMA data types
* @{
*/
/**
* Printing Floating-Point Numbers
*
* available at http://cseweb.ucsd.edu/~mandrysc/pub/dtoa.pdf
*/
/**
* Floating point format definitions
*/
#define ECMA_NEXT_FLOAT(value) (nextafter ((value), INFINITY))
#define ECMA_PREV_FLOAT(value) (nextafter ((value), -INFINITY))
#define ERROL0_EPSILON 0.0000001
/**
* High-precision data structure.
*/
typedef struct
{
double value; /**< value */
double offset; /**< offset */
} ecma_high_prec_t;
/**
* Normalize the number by factoring in the error.
*/
static inline void __attr_always_inline___
ecma_normalize_high_prec_data (ecma_high_prec_t *hp_data_p) /**< [in, out] float pair */
{
double val = hp_data_p->value;
hp_data_p->value += hp_data_p->offset;
hp_data_p->offset += val - hp_data_p->value;
} /* ecma_normalize_high_prec_data */
/**
* Multiply the high-precision number by ten.
*/
static inline void __attr_always_inline___
ecma_multiply_high_prec_by_10 (ecma_high_prec_t *hp_data_p) /**< [in, out] high-precision number */
{
double value = hp_data_p->value;
hp_data_p->value *= 10.0;
hp_data_p->offset *= 10.0;
double offset = hp_data_p->value;
offset -= value * 8.0;
offset -= value * 2.0;
hp_data_p->offset -= offset;
ecma_normalize_high_prec_data (hp_data_p);
} /* ecma_multiply_high_prec_by_10 */
/**
* Divide the high-precision number by ten.
*/
static void
ecma_divide_high_prec_by_10 (ecma_high_prec_t *hp_data_p) /**< [in, out] high-precision number */
{
double value = hp_data_p->value;
hp_data_p->value /= 10.0;
hp_data_p->offset /= 10.0;
value -= hp_data_p->value * 8.0;
value -= hp_data_p->value * 2.0;
hp_data_p->offset += value / 10.0;
ecma_normalize_high_prec_data (hp_data_p);
} /* ecma_divide_high_prec_by_10 */
/**
* Errol0 double to ASCII conversion, guaranteed correct but possibly not optimal.
*
* @return number of generated digits
*/
inline lit_utf8_size_t __attr_always_inline___
ecma_errol0_dtoa (double val, /**< ecma number */
lit_utf8_byte_t *buffer_p, /**< buffer to generate digits into */
int32_t *exp_p) /**< [out] exponent */
{
double power_of_10 = 1.0;
int32_t exp = 1;
/* normalize the midpoint */
ecma_high_prec_t mid;
mid.value = val;
mid.offset = 0.0;
while (((mid.value > 10.0) || ((mid.value == 10.0) && (mid.offset >= 0.0))) && (exp < 308))
{
exp++;
ecma_divide_high_prec_by_10 (&mid);
power_of_10 /= 10.0;
}
while (((mid.value < 1.0) || ((mid.value == 1.0) && (mid.offset < 0.0))) && (exp > -307))
{
exp--;
ecma_multiply_high_prec_by_10 (&mid);
power_of_10 *= 10.0;
}
ecma_high_prec_t high_bound, low_bound;
high_bound.value = mid.value;
high_bound.offset = mid.offset;
if (ECMA_NEXT_FLOAT (val) != INFINITY)
{
high_bound.offset += (ECMA_NEXT_FLOAT (val) - val) * power_of_10 / (2.0 + ERROL0_EPSILON);
}
low_bound.value = mid.value;
low_bound.offset = mid.offset + (ECMA_PREV_FLOAT (val) - val) * power_of_10 / (2.0 + ERROL0_EPSILON);
ecma_normalize_high_prec_data (&high_bound);
ecma_normalize_high_prec_data (&low_bound);
/* normalized boundaries */
while (high_bound.value > 10.0 || (high_bound.value == 10.0 && (high_bound.offset >= 0.0)))
{
exp++;
ecma_divide_high_prec_by_10 (&high_bound);
ecma_divide_high_prec_by_10 (&low_bound);
}
while (high_bound.value < 1.0 || (high_bound.value == 1.0 && (high_bound.offset < 0.0)))
{
exp--;
ecma_multiply_high_prec_by_10 (&high_bound);
ecma_multiply_high_prec_by_10 (&low_bound);
}
/* digit generation */
lit_utf8_byte_t *dst_p = buffer_p;
while (high_bound.value != 0.0 || high_bound.offset != 0.0)
{
uint8_t high_digit = (uint8_t) high_bound.value;
if ((high_bound.value == high_digit) && (high_bound.offset < 0))
{
high_digit = (uint8_t) (high_digit - 1u);
}
uint8_t low_digit = (uint8_t) low_bound.value;
if ((low_bound.value == low_digit) && (low_bound.offset < 0))
{
low_digit = (uint8_t) (low_digit - 1u);
}
if (low_digit != high_digit)
{
break;
}
*dst_p++ = (lit_utf8_byte_t) ('0' + high_digit);
high_bound.value -= high_digit;
ecma_multiply_high_prec_by_10 (&high_bound);
low_bound.value -= low_digit;
ecma_multiply_high_prec_by_10 (&low_bound);
}
double mdig = (high_bound.value + low_bound.value) / 2.0 + 0.5;
*dst_p++ = (lit_utf8_byte_t) ('0' + (uint8_t) mdig);
*exp_p = exp;
return (lit_utf8_size_t) (dst_p - buffer_p);
} /* ecma_errol0_dtoa */
/**
* @}
* @}
*/

View file

@ -0,0 +1,159 @@
/* 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-alloc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmahelpers Helpers for operations with ECMA data types
* @{
*/
/**
* Create internal property with specified identifier and store external pointer in the property.
*
* Note:
* property identifier should be one of the following:
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE;
* - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK.
*
* @return true - if property was just created with specified value,
* false - otherwise, if property existed before the call, it's value was updated.
*/
bool
ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to create property in */
ecma_internal_property_id_t id, /**< identifier of internal
* property to create */
ecma_external_pointer_t ptr_value) /**< value to store in the property */
{
JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
|| id == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK);
ecma_value_t *prop_p = ecma_find_internal_property (obj_p, id);
bool is_new = (prop_p == NULL);
if (is_new)
{
prop_p = ecma_create_internal_property (obj_p, id);
}
JERRY_STATIC_ASSERT (sizeof (uint32_t) <= sizeof (ECMA_PROPERTY_VALUE_PTR (prop_p)->value),
size_of_internal_property_value_must_be_greater_than_or_equal_to_4_bytes);
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
*prop_p = (ecma_value_t) ptr_value;
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
ecma_external_pointer_t *handler_p;
if (is_new)
{
handler_p = ecma_alloc_external_pointer ();
ECMA_SET_NON_NULL_POINTER (*prop_p, handler_p);
}
else
{
handler_p = ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t, *prop_p);
}
*handler_p = ptr_value;
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
return is_new;
} /* ecma_create_external_pointer_property */
/**
* Get value of external pointer stored in the object's property with specified identifier
*
* Note:
* property identifier should be one of the following:
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE;
* - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK.
*
* @return true - if property exists and it's value is returned through out_pointer_p,
* false - otherwise (value returned through out_pointer_p is NULL).
*/
bool
ecma_get_external_pointer_value (ecma_object_t *obj_p, /**< object to get property value from */
ecma_internal_property_id_t id, /**< identifier of internal property
* to get value from */
ecma_external_pointer_t *out_pointer_p) /**< [out] value of the external pointer */
{
JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
|| id == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK);
ecma_value_t *prop_p = ecma_find_internal_property (obj_p, id);
if (prop_p == NULL)
{
*out_pointer_p = (ecma_external_pointer_t) NULL;
return false;
}
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
*out_pointer_p = *prop_p;
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
*out_pointer_p = *ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t, *prop_p);
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
return true;
} /* ecma_get_external_pointer_value */
/**
* Free memory associated with external pointer stored in the property
*
* Note:
* property identifier should be one of the following:
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE;
* - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK.
*/
void
ecma_free_external_pointer_in_property (ecma_property_t *prop_p) /**< internal property */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_p) == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
|| ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_p) == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK);
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
/* no additional memory was allocated for the pointer storage */
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
ecma_external_pointer_t *handler_p = ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t,
ECMA_PROPERTY_VALUE_PTR (prop_p)->value);
ecma_dealloc_external_pointer (handler_p);
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
} /* ecma_free_external_pointer_in_property */
/**
* @}
* @}
*/

View file

@ -0,0 +1,737 @@
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-globals.h"
#include "ecma-helpers.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmahelpers Helpers for operations with ECMA data types
* @{
*/
JERRY_STATIC_ASSERT (sizeof (ecma_value_t) == sizeof (ecma_integer_value_t),
size_of_ecma_value_t_must_be_equal_to_the_size_of_ecma_integer_value_t);
JERRY_STATIC_ASSERT (ECMA_DIRECT_SHIFT == ECMA_VALUE_SHIFT + 1,
currently_directly_encoded_values_has_one_extra_flag);
JERRY_STATIC_ASSERT (((1 << (ECMA_DIRECT_SHIFT - 1)) | ECMA_TYPE_DIRECT) == ECMA_DIRECT_TYPE_SIMPLE_VALUE,
currently_directly_encoded_values_start_after_direct_type_simple_value);
#define ECMA_NUMBER_SIGN_POS (ECMA_NUMBER_FRACTION_WIDTH + \
ECMA_NUMBER_BIASED_EXP_WIDTH)
#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
JERRY_STATIC_ASSERT (sizeof (ecma_number_t) == sizeof (uint32_t),
size_of_ecma_number_t_must_be_equal_to_4_bytes);
/**
* Packing sign, fraction and biased exponent to ecma-number
*
* @return ecma-number with specified sign, biased_exponent and fraction
*/
static ecma_number_t
ecma_number_pack (bool sign, /**< sign */
uint32_t biased_exp, /**< biased exponent */
uint64_t fraction) /**< fraction */
{
JERRY_ASSERT ((biased_exp & ~((1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1)) == 0);
JERRY_ASSERT ((fraction & ~((1ull << ECMA_NUMBER_FRACTION_WIDTH) - 1)) == 0);
uint32_t packed_value = (((sign ? 1u : 0u) << ECMA_NUMBER_SIGN_POS) |
(biased_exp << ECMA_NUMBER_FRACTION_WIDTH) |
((uint32_t) fraction));
union
{
uint32_t u32_value;
ecma_number_t float_value;
} u;
u.u32_value = packed_value;
return u.float_value;
} /* ecma_number_pack */
/**
* Unpacking sign, fraction and biased exponent from ecma-number
*/
static void
ecma_number_unpack (ecma_number_t num, /**< ecma-number */
bool *sign_p, /**< [out] sign (optional) */
uint32_t *biased_exp_p, /**< [out] biased exponent (optional) */
uint64_t *fraction_p) /**< [out] fraction (optional) */
{
union
{
uint32_t u32_value;
ecma_number_t float_value;
} u;
u.float_value = num;
uint32_t packed_value = u.u32_value;
if (sign_p != NULL)
{
*sign_p = ((packed_value >> ECMA_NUMBER_SIGN_POS) != 0);
}
if (biased_exp_p != NULL)
{
*biased_exp_p = (((packed_value) & ~(1u << ECMA_NUMBER_SIGN_POS)) >> ECMA_NUMBER_FRACTION_WIDTH);
}
if (fraction_p != NULL)
{
*fraction_p = (packed_value & ((1u << ECMA_NUMBER_FRACTION_WIDTH) - 1));
}
} /* ecma_number_unpack */
/**
* Value used to calculate exponent from biased exponent
*
* See also:
* IEEE-754 2008, 3.6, Table 3.5
*/
const int32_t ecma_number_exponent_bias = 127;
#elif CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
JERRY_STATIC_ASSERT (sizeof (ecma_number_t) == sizeof (uint64_t),
size_of_ecma_number_t_must_be_equal_to_8_bytes);
/**
* Packing sign, fraction and biased exponent to ecma-number
*
* @return ecma-number with specified sign, biased_exponent and fraction
*/
static ecma_number_t
ecma_number_pack (bool sign, /**< sign */
uint32_t biased_exp, /**< biased exponent */
uint64_t fraction) /**< fraction */
{
uint64_t packed_value = (((sign ? 1ull : 0ull) << ECMA_NUMBER_SIGN_POS) |
(((uint64_t) biased_exp) << ECMA_NUMBER_FRACTION_WIDTH) |
fraction);
JERRY_ASSERT ((biased_exp & ~((1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1)) == 0);
JERRY_ASSERT ((fraction & ~((1ull << ECMA_NUMBER_FRACTION_WIDTH) - 1)) == 0);
union
{
uint64_t u64_value;
ecma_number_t float_value;
} u;
u.u64_value = packed_value;
return u.float_value;
} /* ecma_number_pack */
/**
* Unpacking sign, fraction and biased exponent from ecma-number
*/
static void
ecma_number_unpack (ecma_number_t num, /**< ecma-number */
bool *sign_p, /**< [out] sign (optional) */
uint32_t *biased_exp_p, /**< [out] biased exponent (optional) */
uint64_t *fraction_p) /**< [out] fraction (optional) */
{
union
{
uint64_t u64_value;
ecma_number_t float_value;
} u;
u.float_value = num;
uint64_t packed_value = u.u64_value;
if (sign_p != NULL)
{
*sign_p = ((packed_value >> ECMA_NUMBER_SIGN_POS) != 0);
}
if (biased_exp_p != NULL)
{
*biased_exp_p = (uint32_t) (((packed_value) & ~(1ull << ECMA_NUMBER_SIGN_POS)) >> ECMA_NUMBER_FRACTION_WIDTH);
}
if (fraction_p != NULL)
{
*fraction_p = (packed_value & ((1ull << ECMA_NUMBER_FRACTION_WIDTH) - 1));
}
} /* ecma_number_unpack */
/**
* Value used to calculate exponent from biased exponent
*
* See also:
* IEEE-754 2008, 3.6, Table 3.5
*/
const int32_t ecma_number_exponent_bias = 1023;
#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32 */
/**
* Get fraction of number
*
* @return normalized fraction field of number
*/
static uint64_t
ecma_number_get_fraction_field (ecma_number_t num) /**< ecma-number */
{
uint64_t fraction;
ecma_number_unpack (num, NULL, NULL, &fraction);
return fraction;
} /* ecma_number_get_fraction_field */
/**
* Get exponent of number
*
* @return exponent corresponding to normalized fraction of number
*/
static uint32_t
ecma_number_get_biased_exponent_field (ecma_number_t num) /**< ecma-number */
{
uint32_t biased_exp;
ecma_number_unpack (num, NULL, &biased_exp, NULL);
return biased_exp;
} /* ecma_number_get_biased_exponent_field */
/**
* Get sign bit of number
*
* @return 0 or 1 - value of sign bit
*/
static uint32_t
ecma_number_get_sign_field (ecma_number_t num) /**< ecma-number */
{
bool sign;
ecma_number_unpack (num, &sign, NULL, NULL);
return sign;
} /* ecma_number_get_sign_field */
/**
* Check if ecma-number is NaN
*
* @return true - if biased exponent is filled with 1 bits and
fraction is filled with anything but not all zero bits,
* false - otherwise
*/
bool __attr_always_inline___
ecma_number_is_nan (ecma_number_t num) /**< ecma-number */
{
bool is_nan = (num != num);
#ifndef JERRY_NDEBUG
uint32_t biased_exp = ecma_number_get_biased_exponent_field (num);
uint64_t fraction = ecma_number_get_fraction_field (num);
/* IEEE-754 2008, 3.4, a */
bool is_nan_ieee754 = ((biased_exp == (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1)
&& (fraction != 0));
JERRY_ASSERT (is_nan == is_nan_ieee754);
#endif /* !JERRY_NDEBUG */
return is_nan;
} /* ecma_number_is_nan */
/**
* Make a NaN.
*
* @return NaN value
*/
ecma_number_t
ecma_number_make_nan (void)
{
return ecma_number_pack (false,
(1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1u,
1u);
} /* ecma_number_make_nan */
/**
* Make an Infinity.
*
* @return if !sign - +Infinity value,
* else - -Infinity value.
*/
ecma_number_t
ecma_number_make_infinity (bool sign) /**< true - for negative Infinity,
false - for positive Infinity */
{
return ecma_number_pack (sign,
(1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1u,
0u);
} /* ecma_number_make_infinity */
/**
* Check if ecma-number is negative
*
* @return true - if sign bit of ecma-number is set
* false - otherwise
*/
bool __attr_always_inline___
ecma_number_is_negative (ecma_number_t num) /**< ecma-number */
{
JERRY_ASSERT (!ecma_number_is_nan (num));
/* IEEE-754 2008, 3.4 */
return (ecma_number_get_sign_field (num) != 0);
} /* ecma_number_is_negative */
/**
* Check if ecma-number is zero
*
* @return true - if fraction is zero and biased exponent is zero,
* false - otherwise
*/
bool
ecma_number_is_zero (ecma_number_t num) /**< ecma-number */
{
JERRY_ASSERT (!ecma_number_is_nan (num));
bool is_zero = (num == ECMA_NUMBER_ZERO);
#ifndef JERRY_NDEBUG
/* IEEE-754 2008, 3.4, e */
bool is_zero_ieee754 = (ecma_number_get_fraction_field (num) == 0
&& ecma_number_get_biased_exponent_field (num) == 0);
JERRY_ASSERT (is_zero == is_zero_ieee754);
#endif /* !JERRY_NDEBUG */
return is_zero;
} /* ecma_number_is_zero */
/**
* Check if number is infinity
*
* @return true - if biased exponent is filled with 1 bits and
* fraction is filled with zero bits,
* false - otherwise.
*/
bool
ecma_number_is_infinity (ecma_number_t num) /**< ecma-number */
{
JERRY_ASSERT (!ecma_number_is_nan (num));
uint32_t biased_exp = ecma_number_get_biased_exponent_field (num);
uint64_t fraction = ecma_number_get_fraction_field (num);
/* IEEE-754 2008, 3.4, b */
return ((biased_exp == (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1)
&& (fraction == 0));
} /* ecma_number_is_infinity */
/**
* Get fraction and exponent of the number
*
* @return shift of dot in the fraction
*/
int32_t
ecma_number_get_fraction_and_exponent (ecma_number_t num, /**< ecma-number */
uint64_t *out_fraction_p, /**< [out] fraction of the number */
int32_t *out_exponent_p) /**< [out] exponent of the number */
{
JERRY_ASSERT (!ecma_number_is_nan (num));
uint32_t biased_exp = ecma_number_get_biased_exponent_field (num);
uint64_t fraction = ecma_number_get_fraction_field (num);
int32_t exponent;
if (unlikely (biased_exp == 0))
{
/* IEEE-754 2008, 3.4, d */
if (ecma_number_is_zero (num))
{
exponent = -ecma_number_exponent_bias;
}
else
{
exponent = 1 - ecma_number_exponent_bias;
while (!(fraction & (1ull << ECMA_NUMBER_FRACTION_WIDTH)))
{
JERRY_ASSERT (fraction != 0);
fraction <<= 1;
exponent--;
}
}
}
else if (ecma_number_is_infinity (num))
{
/* The fraction and exponent should round to infinity */
exponent = (int32_t) biased_exp - ecma_number_exponent_bias;
JERRY_ASSERT ((fraction & (1ull << ECMA_NUMBER_FRACTION_WIDTH)) == 0);
fraction |= 1ull << ECMA_NUMBER_FRACTION_WIDTH;
}
else
{
/* IEEE-754 2008, 3.4, c */
exponent = (int32_t) biased_exp - ecma_number_exponent_bias;
JERRY_ASSERT (biased_exp > 0 && biased_exp < (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1);
JERRY_ASSERT ((fraction & (1ull << ECMA_NUMBER_FRACTION_WIDTH)) == 0);
fraction |= 1ull << ECMA_NUMBER_FRACTION_WIDTH;
}
*out_fraction_p = fraction;
*out_exponent_p = exponent;
return ECMA_NUMBER_FRACTION_WIDTH;
} /* ecma_number_get_fraction_and_exponent */
/**
* Make normalised positive Number from given fraction and exponent
*
* @return ecma-number
*/
ecma_number_t
ecma_number_make_normal_positive_from_fraction_and_exponent (uint64_t fraction, /**< fraction */
int32_t exponent) /**< exponent */
{
uint32_t biased_exp = (uint32_t) (exponent + ecma_number_exponent_bias);
JERRY_ASSERT (biased_exp > 0 && biased_exp < (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1);
JERRY_ASSERT ((fraction & ~((1ull << (ECMA_NUMBER_FRACTION_WIDTH + 1)) - 1)) == 0);
JERRY_ASSERT ((fraction & (1ull << ECMA_NUMBER_FRACTION_WIDTH)) != 0);
return ecma_number_pack (false,
biased_exp,
fraction & ~(1ull << ECMA_NUMBER_FRACTION_WIDTH));
} /* ecma_number_make_normal_positive_from_fraction_and_exponent */
/**
* Make Number of given sign from given mantissa value and binary exponent
*
* @return ecma-number (possibly Infinity of specified sign)
*/
ecma_number_t
ecma_number_make_from_sign_mantissa_and_exponent (bool sign, /**< true - for negative sign,
false - for positive sign */
uint64_t mantissa, /**< mantissa */
int32_t exponent) /**< binary exponent */
{
/* Rounding mantissa to fit into fraction field width */
if (mantissa & ~((1ull << (ECMA_NUMBER_FRACTION_WIDTH + 1)) - 1))
{
/* Rounded mantissa looks like the following: |00...0|1|fraction_width mantissa bits| */
while ((mantissa & ~((1ull << (ECMA_NUMBER_FRACTION_WIDTH + 1)) - 1)) != 0)
{
uint64_t rightmost_bit = (mantissa & 1);
exponent++;
mantissa >>= 1;
if ((mantissa & ~((1ull << (ECMA_NUMBER_FRACTION_WIDTH + 1)) - 1)) == 0)
{
/* Rounding to nearest value */
mantissa += rightmost_bit;
/* In the first case loop is finished,
and in the second - just one shift follows and then loop finishes */
JERRY_ASSERT (((mantissa & ~((1ull << (ECMA_NUMBER_FRACTION_WIDTH + 1)) - 1)) == 0)
|| (mantissa == (1ull << (ECMA_NUMBER_FRACTION_WIDTH + 1))));
}
}
}
/* Normalizing mantissa */
while (mantissa != 0
&& ((mantissa & (1ull << ECMA_NUMBER_FRACTION_WIDTH)) == 0))
{
exponent--;
mantissa <<= 1;
}
/* Moving floating point */
exponent += ECMA_NUMBER_FRACTION_WIDTH - 1;
int32_t biased_exp_signed = exponent + ecma_number_exponent_bias;
if (biased_exp_signed < 1)
{
/* Denormalizing mantissa if biased_exponent is less than zero */
while (biased_exp_signed < 0)
{
biased_exp_signed++;
mantissa >>= 1;
}
/* Rounding to nearest value */
mantissa += 1;
mantissa >>= 1;
/* Encoding denormalized exponent */
biased_exp_signed = 0;
}
else
{
/* Clearing highest mantissa bit that should have been non-zero if mantissa is non-zero */
mantissa &= ~(1ull << ECMA_NUMBER_FRACTION_WIDTH);
}
uint32_t biased_exp = (uint32_t) biased_exp_signed;
if (biased_exp >= ((1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1))
{
return ecma_number_make_infinity (sign);
}
JERRY_ASSERT (biased_exp < (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1);
JERRY_ASSERT ((mantissa & ~((1ull << ECMA_NUMBER_FRACTION_WIDTH) - 1)) == 0);
return ecma_number_pack (sign,
biased_exp,
mantissa);
} /* ecma_number_make_from_sign_mantissa_and_exponent */
/**
* Get previous representable ecma-number
*
* @return maximum ecma-number that is less compared to passed argument
*/
ecma_number_t
ecma_number_get_prev (ecma_number_t num) /**< ecma-number */
{
JERRY_ASSERT (!ecma_number_is_nan (num));
JERRY_ASSERT (!ecma_number_is_zero (num));
if (ecma_number_is_negative (num))
{
return ecma_number_negate (ecma_number_get_next (num));
}
uint32_t biased_exp = ecma_number_get_biased_exponent_field (num);
uint64_t fraction = ecma_number_get_fraction_field (num);
if (fraction == 0 && biased_exp != 0)
{
fraction = (1ull << ECMA_NUMBER_FRACTION_WIDTH) - 1;
biased_exp--;
}
else
{
fraction--;
}
return ecma_number_pack (false,
biased_exp,
fraction);
} /* ecma_number_get_prev */
/**
* Get next representable ecma-number
*
* @return minimum ecma-number that is greater compared to passed argument
*/
ecma_number_t
ecma_number_get_next (ecma_number_t num) /**< ecma-number */
{
JERRY_ASSERT (!ecma_number_is_nan (num));
JERRY_ASSERT (!ecma_number_is_infinity (num));
if (ecma_number_is_negative (num))
{
return ecma_number_negate (ecma_number_get_prev (num));
}
uint32_t biased_exp = ecma_number_get_biased_exponent_field (num);
uint64_t fraction = ecma_number_get_fraction_field (num);
fraction |= (1ull << ECMA_NUMBER_FRACTION_WIDTH);
fraction++;
if ((fraction & (1ull << ECMA_NUMBER_FRACTION_WIDTH)) == 0)
{
fraction >>= 1;
biased_exp++;
}
JERRY_ASSERT (fraction & (1ull << ECMA_NUMBER_FRACTION_WIDTH));
fraction &= ~(1ull << ECMA_NUMBER_FRACTION_WIDTH);
return ecma_number_pack (false,
biased_exp,
fraction);
} /* ecma_number_get_next */
/**
* Negate ecma-number
*
* @return negated number
*/
ecma_number_t
ecma_number_negate (ecma_number_t num) /**< ecma-number */
{
ecma_number_t negated = -num;
#ifndef JERRY_NDEBUG
bool sign;
uint32_t biased_exp;
uint64_t fraction;
ecma_number_unpack (num, &sign, &biased_exp, &fraction);
sign = !sign;
ecma_number_t negated_ieee754 = ecma_number_pack (sign, biased_exp, fraction);
JERRY_ASSERT (negated == negated_ieee754
|| (ecma_number_is_nan (negated)
&& ecma_number_is_nan (negated_ieee754)));
#endif /* !JERRY_NDEBUG */
return negated;
} /* ecma_number_negate */
/**
* Truncate fractional part of the number
*
* @return integer part of the number
*/
ecma_number_t
ecma_number_trunc (ecma_number_t num) /**< ecma-number */
{
JERRY_ASSERT (!ecma_number_is_nan (num));
uint64_t fraction;
int32_t exponent;
const int32_t dot_shift = ecma_number_get_fraction_and_exponent (num, &fraction, &exponent);
const bool sign = ecma_number_is_negative (num);
if (exponent < 0)
{
return ECMA_NUMBER_ZERO;
}
else if (exponent < dot_shift)
{
fraction &= ~((1ull << (dot_shift - exponent)) - 1);
ecma_number_t tmp = ecma_number_make_normal_positive_from_fraction_and_exponent (fraction,
exponent);
if (sign)
{
return ecma_number_negate (tmp);
}
else
{
return tmp;
}
}
else
{
return num;
}
} /* ecma_number_trunc */
/**
* Calculate remainder of division of two numbers,
* as specified in ECMA-262 v5, 11.5.3, item 6.
*
* Note:
* operands shouldn't contain NaN, Infinity, or zero.
*
* @return number - calculated remainder.
*/
ecma_number_t
ecma_number_calc_remainder (ecma_number_t left_num, /**< left operand */
ecma_number_t right_num) /**< right operand */
{
JERRY_ASSERT (!ecma_number_is_nan (left_num)
&& !ecma_number_is_zero (left_num)
&& !ecma_number_is_infinity (left_num));
JERRY_ASSERT (!ecma_number_is_nan (right_num)
&& !ecma_number_is_zero (right_num)
&& !ecma_number_is_infinity (right_num));
const ecma_number_t q = ecma_number_trunc (ecma_number_divide (left_num, right_num));
ecma_number_t r = ecma_number_substract (left_num, ecma_number_multiply (right_num, q));
if (ecma_number_is_zero (r)
&& ecma_number_is_negative (left_num))
{
r = ecma_number_negate (r);
}
return r;
} /* ecma_number_calc_remainder */
/**
* ECMA-number addition.
*
* @return number - result of addition.
*/
ecma_number_t
ecma_number_add (ecma_number_t left_num, /**< left operand */
ecma_number_t right_num) /**< right operand */
{
return left_num + right_num;
} /* ecma_number_add */
/**
* ECMA-number substraction.
*
* @return number - result of substraction.
*/
ecma_number_t
ecma_number_substract (ecma_number_t left_num, /**< left operand */
ecma_number_t right_num) /**< right operand */
{
return ecma_number_add (left_num, ecma_number_negate (right_num));
} /* ecma_number_substract */
/**
* ECMA-number multiplication.
*
* @return number - result of multiplication.
*/
ecma_number_t
ecma_number_multiply (ecma_number_t left_num, /**< left operand */
ecma_number_t right_num) /**< right operand */
{
return left_num * right_num;
} /* ecma_number_multiply */
/**
* ECMA-number division.
*
* @return number - result of division.
*/
ecma_number_t
ecma_number_divide (ecma_number_t left_num, /**< left operand */
ecma_number_t right_num) /**< right operand */
{
return left_num / right_num;
} /* ecma_number_divide */
/**
* @}
* @}
*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,924 @@
/* 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-alloc.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "jrt.h"
#include "jrt-bit-fields.h"
#include "vm-defines.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmahelpers Helpers for operations with ECMA data types
* @{
*/
/**
* Masking the type and flags
*/
#define ECMA_VALUE_FULL_MASK (ECMA_VALUE_TYPE_MASK | ECMA_VALUE_ERROR_FLAG)
JERRY_STATIC_ASSERT (ECMA_TYPE___MAX <= ECMA_VALUE_TYPE_MASK,
ecma_types_must_be_less_than_mask);
JERRY_STATIC_ASSERT ((ECMA_VALUE_FULL_MASK + 1) == (1 << ECMA_VALUE_SHIFT),
ecma_value_part_must_start_after_flags);
JERRY_STATIC_ASSERT (ECMA_VALUE_SHIFT <= JMEM_ALIGNMENT_LOG,
ecma_value_shift_must_be_less_than_or_equal_than_mem_alignment_log);
JERRY_STATIC_ASSERT (sizeof (jmem_cpointer_t) <= sizeof (ecma_value_t),
size_of_jmem_cpointer_t_must_be_less_or_equal_to_the_size_of_ecma_value_t);
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
JERRY_STATIC_ASSERT (sizeof (uintptr_t) <= sizeof (ecma_value_t),
uintptr_t_must_fit_in_ecma_value_t);
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
JERRY_STATIC_ASSERT (sizeof (uintptr_t) > sizeof (ecma_value_t),
uintptr_t_must_not_fit_in_ecma_value_t);
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
JERRY_STATIC_ASSERT ((ECMA_SIMPLE_VALUE_FALSE | 0x1) == ECMA_SIMPLE_VALUE_TRUE
&& ECMA_SIMPLE_VALUE_FALSE != ECMA_SIMPLE_VALUE_TRUE,
only_the_lowest_bit_must_be_different_for_simple_value_true_and_false);
/**
* Get type field of ecma value
*
* @return type field
*/
static inline ecma_type_t __attr_pure___ __attr_always_inline___
ecma_get_value_type_field (ecma_value_t value) /**< ecma value */
{
return value & ECMA_VALUE_TYPE_MASK;
} /* ecma_get_value_type_field */
/**
* Convert a pointer into an ecma value.
*
* @return ecma value
*/
static inline ecma_value_t __attr_pure___ __attr_always_inline___
ecma_pointer_to_ecma_value (const void *ptr) /**< pointer */
{
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
uintptr_t uint_ptr = (uintptr_t) ptr;
JERRY_ASSERT ((uint_ptr & ECMA_VALUE_FULL_MASK) == 0);
return (ecma_value_t) uint_ptr;
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
jmem_cpointer_t ptr_cp;
ECMA_SET_NON_NULL_POINTER (ptr_cp, ptr);
return ((ecma_value_t) ptr_cp) << ECMA_VALUE_SHIFT;
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
} /* ecma_pointer_to_ecma_value */
/**
* Get a pointer from an ecma value
*
* @return pointer
*/
static inline void * __attr_pure___ __attr_always_inline___
ecma_get_pointer_from_ecma_value (ecma_value_t value) /**< value */
{
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
return (void *) (uintptr_t) ((value) & ~ECMA_VALUE_FULL_MASK);
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
return ECMA_GET_NON_NULL_POINTER (ecma_number_t,
value >> ECMA_VALUE_SHIFT);
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
} /* ecma_get_pointer_from_ecma_value */
/**
* Check if the value is direct ecma-value.
*
* @return true - if the value is a direct value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_direct (ecma_value_t value) /**< ecma value */
{
return (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT);
} /* ecma_is_value_direct */
/**
* Check if the value is simple ecma-value.
*
* @return true - if the value is a simple value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_simple (ecma_value_t value) /**< ecma value */
{
return (value & ECMA_DIRECT_TYPE_MASK) == ECMA_DIRECT_TYPE_SIMPLE_VALUE;
} /* ecma_is_value_simple */
/**
* Check whether the value is a given simple value.
*
* @return true - if the value is equal to the given simple value,
* false - otherwise.
*/
static inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_equal_to_simple_value (ecma_value_t value, /**< ecma value */
ecma_simple_value_t simple_value) /**< simple value */
{
return (value | ECMA_VALUE_ERROR_FLAG) == (ecma_make_simple_value (simple_value) | ECMA_VALUE_ERROR_FLAG);
} /* ecma_is_value_equal_to_simple_value */
/**
* Check if the value is empty.
*
* @return true - if the value contains implementation-defined empty simple value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_empty (ecma_value_t value) /**< ecma value */
{
return ecma_is_value_equal_to_simple_value (value, ECMA_SIMPLE_VALUE_EMPTY);
} /* ecma_is_value_empty */
/**
* Check if the value is undefined.
*
* @return true - if the value contains ecma-undefined simple value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_undefined (ecma_value_t value) /**< ecma value */
{
return ecma_is_value_equal_to_simple_value (value, ECMA_SIMPLE_VALUE_UNDEFINED);
} /* ecma_is_value_undefined */
/**
* Check if the value is null.
*
* @return true - if the value contains ecma-null simple value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_null (ecma_value_t value) /**< ecma value */
{
return ecma_is_value_equal_to_simple_value (value, ECMA_SIMPLE_VALUE_NULL);
} /* ecma_is_value_null */
/**
* Check if the value is boolean.
*
* @return true - if the value contains ecma-true or ecma-false simple values,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_boolean (ecma_value_t value) /**< ecma value */
{
return ecma_is_value_true (value | (1 << ECMA_DIRECT_SHIFT));
} /* ecma_is_value_boolean */
/**
* Check if the value is true.
*
* @return true - if the value contains ecma-true simple value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_true (ecma_value_t value) /**< ecma value */
{
return ecma_is_value_equal_to_simple_value (value, ECMA_SIMPLE_VALUE_TRUE);
} /* ecma_is_value_true */
/**
* Check if the value is false.
*
* @return true - if the value contains ecma-false simple value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_false (ecma_value_t value) /**< ecma value */
{
return ecma_is_value_equal_to_simple_value (value, ECMA_SIMPLE_VALUE_FALSE);
} /* ecma_is_value_false */
/**
* Check if the value is not found.
*
* @return true - if the value contains ecma-not-found simple value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_found (ecma_value_t value) /**< ecma value */
{
return value != ecma_make_simple_value (ECMA_SIMPLE_VALUE_NOT_FOUND);
} /* ecma_is_value_found */
/**
* Check if the value is array hole.
*
* @return true - if the value contains ecma-array-hole simple value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_array_hole (ecma_value_t value) /**< ecma value */
{
return ecma_is_value_equal_to_simple_value (value, ECMA_SIMPLE_VALUE_ARRAY_HOLE);
} /* ecma_is_value_array_hole */
/**
* Check if the value is integer ecma-number.
*
* @return true - if the value contains an integer ecma-number value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_integer_number (ecma_value_t value) /**< ecma value */
{
return (value & ECMA_DIRECT_TYPE_MASK) == ECMA_DIRECT_TYPE_INTEGER_VALUE;
} /* ecma_is_value_integer_number */
/**
* Check if both values are integer ecma-numbers.
*
* @return true - if both values contain integer ecma-number values,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_are_values_integer_numbers (ecma_value_t first_value, /**< first ecma value */
ecma_value_t second_value) /**< second ecma value */
{
JERRY_STATIC_ASSERT (ECMA_DIRECT_TYPE_INTEGER_VALUE == 0,
ecma_direct_type_integer_value_must_be_zero);
return ((first_value | second_value) & ECMA_DIRECT_TYPE_MASK) == ECMA_DIRECT_TYPE_INTEGER_VALUE;
} /* ecma_are_values_integer_numbers */
/**
* Check if the value is floating-point ecma-number.
*
* @return true - if the value contains a floating-point ecma-number value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_float_number (ecma_value_t value) /**< ecma value */
{
return (ecma_get_value_type_field (value) == ECMA_TYPE_FLOAT);
} /* ecma_is_value_float_number */
/**
* Check if the value is ecma-number.
*
* @return true - if the value contains ecma-number value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_number (ecma_value_t value) /**< ecma value */
{
return (ecma_is_value_integer_number (value)
|| ecma_is_value_float_number (value));
} /* ecma_is_value_number */
/**
* Check if the value is ecma-string.
*
* @return true - if the value contains ecma-string value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_string (ecma_value_t value) /**< ecma value */
{
return (ecma_get_value_type_field (value) == ECMA_TYPE_STRING);
} /* ecma_is_value_string */
/**
* Check if the value is object.
*
* @return true - if the value contains object value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_object (ecma_value_t value) /**< ecma value */
{
return (ecma_get_value_type_field (value) == ECMA_TYPE_OBJECT);
} /* ecma_is_value_object */
/**
* Debug assertion that specified value's type is one of ECMA-defined
* script-visible types, i.e.: undefined, null, boolean, number, string, object.
*/
void
ecma_check_value_type_is_spec_defined (ecma_value_t value) /**< ecma value */
{
JERRY_ASSERT (ecma_is_value_undefined (value)
|| ecma_is_value_null (value)
|| ecma_is_value_boolean (value)
|| ecma_is_value_number (value)
|| ecma_is_value_string (value)
|| ecma_is_value_object (value));
} /* ecma_check_value_type_is_spec_defined */
/**
* Simple value constructor
*/
inline ecma_value_t __attr_const___ __attr_always_inline___
ecma_make_simple_value (const ecma_simple_value_t simple_value) /**< simple value */
{
return (((ecma_value_t) (simple_value)) << ECMA_DIRECT_SHIFT) | ECMA_DIRECT_TYPE_SIMPLE_VALUE;
} /* ecma_make_simple_value */
/**
* Creates an ecma value from the given raw boolean.
*
* @return boolean ecma_value
*/
inline ecma_value_t __attr_const___ __attr_always_inline___
ecma_make_boolean_value (bool boolean_value) /**< raw bool value from which the ecma value will be created */
{
return ecma_make_simple_value (boolean_value ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE);
} /* ecma_make_boolean_value */
/**
* Encode an integer number into an ecma-value without allocating memory
*
* Note:
* The value must fit into the range of allowed ecma integer values
*
* @return ecma-value
*/
inline ecma_value_t __attr_const___ __attr_always_inline___
ecma_make_integer_value (ecma_integer_value_t integer_value) /**< integer number to be encoded */
{
JERRY_ASSERT (ECMA_IS_INTEGER_NUMBER (integer_value));
return ((ecma_value_t) (integer_value << ECMA_DIRECT_SHIFT)) | ECMA_DIRECT_TYPE_INTEGER_VALUE;
} /* ecma_make_integer_value */
/**
* Allocate and initialize a new float number without checks.
*
* @return ecma-value
*/
static ecma_value_t __attr_const___
ecma_create_float_number (ecma_number_t ecma_number) /**< value of the float number */
{
ecma_number_t *ecma_num_p = ecma_alloc_number ();
*ecma_num_p = ecma_number;
return ecma_pointer_to_ecma_value (ecma_num_p) | ECMA_TYPE_FLOAT;
} /* ecma_create_float_number */
/**
* Create a new NaN value.
*
* @return ecma-value
*/
inline ecma_value_t __attr_always_inline___
ecma_make_nan_value (void)
{
return ecma_create_float_number (ecma_number_make_nan ());
} /* ecma_make_nan_value */
/**
* Checks whether the passed number is +0.0
*
* @return true, if it is +0.0, false otherwise
*/
static inline bool __attr_const___ __attr_always_inline___
ecma_is_number_equal_to_positive_zero (ecma_number_t ecma_number) /**< number */
{
#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
union
{
uint32_t u32_value;
ecma_number_t float_value;
} u;
u.float_value = ecma_number;
return u.u32_value == 0;
#else /* CONFIG_ECMA_NUMBER_TYPE != CONFIG_ECMA_NUMBER_FLOAT32 */
union
{
uint64_t u64_value;
ecma_number_t float_value;
} u;
u.float_value = ecma_number;
return u.u64_value == 0;
#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32 */
} /* ecma_is_number_equal_to_positive_zero */
/**
* Encode a number into an ecma-value
*
* @return ecma-value
*/
ecma_value_t
ecma_make_number_value (ecma_number_t ecma_number) /**< number to be encoded */
{
ecma_integer_value_t integer_value = (ecma_integer_value_t) ecma_number;
if ((ecma_number_t) integer_value == ecma_number
&& ((integer_value == 0) ? ecma_is_number_equal_to_positive_zero (ecma_number)
: ECMA_IS_INTEGER_NUMBER (integer_value)))
{
return ecma_make_integer_value (integer_value);
}
return ecma_create_float_number (ecma_number);
} /* ecma_make_number_value */
/**
* Encode an int32 number into an ecma-value
*
* @return ecma-value
*/
ecma_value_t
ecma_make_int32_value (int32_t int32_number) /**< int32 number to be encoded */
{
if (ECMA_IS_INTEGER_NUMBER (int32_number))
{
return ecma_make_integer_value ((ecma_integer_value_t) int32_number);
}
return ecma_create_float_number ((ecma_number_t) int32_number);
} /* ecma_make_int32_value */
/**
* Encode an unsigned int32 number into an ecma-value
*
* @return ecma-value
*/
ecma_value_t
ecma_make_uint32_value (uint32_t uint32_number) /**< uint32 number to be encoded */
{
if (uint32_number <= ECMA_INTEGER_NUMBER_MAX)
{
return ecma_make_integer_value ((ecma_integer_value_t) uint32_number);
}
return ecma_create_float_number ((ecma_number_t) uint32_number);
} /* ecma_make_uint32_value */
/**
* String value constructor
*/
ecma_value_t __attr_const___
ecma_make_string_value (const ecma_string_t *ecma_string_p) /**< string to reference in value */
{
JERRY_ASSERT (ecma_string_p != NULL);
return ecma_pointer_to_ecma_value (ecma_string_p) | ECMA_TYPE_STRING;
} /* ecma_make_string_value */
/**
* Object value constructor
*/
ecma_value_t __attr_const___
ecma_make_object_value (const ecma_object_t *object_p) /**< object to reference in value */
{
JERRY_ASSERT (object_p != NULL);
return ecma_pointer_to_ecma_value (object_p) | ECMA_TYPE_OBJECT;
} /* ecma_make_object_value */
/**
* Error value constructor
*/
ecma_value_t __attr_const___
ecma_make_error_value (ecma_value_t value) /**< original ecma value */
{
/* Error values cannot be converted. */
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (value));
return value | ECMA_VALUE_ERROR_FLAG;
} /* ecma_make_error_value */
/**
* Error value constructor
*/
ecma_value_t __attr_const___
ecma_make_error_obj_value (const ecma_object_t *object_p) /**< object to reference in value */
{
return ecma_make_error_value (ecma_make_object_value (object_p));
} /* ecma_make_error_obj_value */
/**
* Get integer value from an integer ecma value
*
* @return floating point value
*/
inline ecma_integer_value_t __attr_pure___ __attr_always_inline___
ecma_get_integer_from_value (ecma_value_t value) /**< ecma value */
{
JERRY_ASSERT (ecma_is_value_integer_number (value));
return ((ecma_integer_value_t) value) >> ECMA_DIRECT_SHIFT;
} /* ecma_get_integer_from_value */
inline ecma_number_t __attr_pure___ __attr_always_inline___
ecma_get_float_from_value (ecma_value_t value) /**< ecma value */
{
JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_FLOAT);
return *(ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
} /* ecma_get_float_from_value */
/**
* Get floating point value from an ecma value
*
* @return floating point value
*/
ecma_number_t __attr_pure___
ecma_get_number_from_value (ecma_value_t value) /**< ecma value */
{
if (ecma_is_value_integer_number (value))
{
return (ecma_number_t) ecma_get_integer_from_value (value);
}
return ecma_get_float_from_value (value);
} /* ecma_get_number_from_value */
/**
* Get uint32 value from an ecma value
*
* @return floating point value
*/
uint32_t __attr_pure___
ecma_get_uint32_from_value (ecma_value_t value) /**< ecma value */
{
if (ecma_is_value_integer_number (value))
{
/* Works with negative numbers as well. */
return (uint32_t) (((ecma_integer_value_t) value) >> ECMA_DIRECT_SHIFT);
}
JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_FLOAT);
return ecma_number_to_uint32 (*(ecma_number_t *) ecma_get_pointer_from_ecma_value (value));
} /* ecma_get_uint32_from_value */
/**
* Get pointer to ecma-string from ecma value
*
* @return the pointer
*/
inline ecma_string_t *__attr_pure___ __attr_always_inline___
ecma_get_string_from_value (ecma_value_t value) /**< ecma value */
{
JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_STRING);
return (ecma_string_t *) ecma_get_pointer_from_ecma_value (value);
} /* ecma_get_string_from_value */
/**
* Get pointer to ecma-object from ecma value
*
* @return the pointer
*/
inline ecma_object_t *__attr_pure___ __attr_always_inline___
ecma_get_object_from_value (ecma_value_t value) /**< ecma value */
{
JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_OBJECT);
return (ecma_object_t *) ecma_get_pointer_from_ecma_value (value);
} /* ecma_get_object_from_value */
/**
* Invert a boolean value
*
* @return ecma value
*/
inline ecma_value_t __attr_pure___ __attr_always_inline___
ecma_invert_boolean_value (ecma_value_t value) /**< ecma value */
{
JERRY_ASSERT (ecma_is_value_boolean (value));
return (value ^ (1 << ECMA_DIRECT_SHIFT));
} /* ecma_invert_boolean_value */
/**
* Get the value from an error ecma value
*
* @return ecma value
*/
ecma_value_t __attr_pure___
ecma_get_value_from_error_value (ecma_value_t value) /**< ecma value */
{
JERRY_ASSERT (ECMA_IS_VALUE_ERROR (value));
value = (ecma_value_t) (value & ~ECMA_VALUE_ERROR_FLAG);
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (value));
return value;
} /* ecma_get_value_from_error_value */
/**
* Copy ecma value.
*
* @return copy of the given value
*/
ecma_value_t
ecma_copy_value (ecma_value_t value) /**< value description */
{
switch (ecma_get_value_type_field (value))
{
case ECMA_TYPE_DIRECT:
{
return value;
}
case ECMA_TYPE_FLOAT:
{
ecma_number_t *num_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
return ecma_create_float_number (*num_p);
}
case ECMA_TYPE_STRING:
{
ecma_ref_ecma_string (ecma_get_string_from_value (value));
return value;
}
case ECMA_TYPE_OBJECT:
{
ecma_ref_object (ecma_get_object_from_value (value));
return value;
}
}
JERRY_UNREACHABLE ();
} /* ecma_copy_value */
/**
* Copy ecma value.
*
* Note:
* this function is similar to ecma_copy_value, but it is
* faster for direct values since no function call is performed.
* It also increases the binary size so it is recommended for
* critical code paths only.
*
* @return copy of the given value
*/
inline ecma_value_t __attr_always_inline___
ecma_fast_copy_value (ecma_value_t value) /**< value description */
{
return (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT) ? value : ecma_copy_value (value);
} /* ecma_fast_copy_value */
/**
* Copy the ecma value if not an object
*
* @return copy of the given value
*/
ecma_value_t
ecma_copy_value_if_not_object (ecma_value_t value) /**< value description */
{
if (ecma_get_value_type_field (value) != ECMA_TYPE_OBJECT)
{
return ecma_copy_value (value);
}
return value;
} /* ecma_copy_value_if_not_object */
/**
* Assign a new value to an ecma-value
*
* Note:
* value previously stored in the property is freed
*/
void
ecma_value_assign_value (ecma_value_t *value_p, /**< [in, out] ecma value */
ecma_value_t ecma_value) /**< value to assign */
{
JERRY_STATIC_ASSERT (ECMA_TYPE_DIRECT == 0,
ecma_type_direct_must_be_zero_for_the_next_check);
if (*value_p == ecma_value)
{
return;
}
if (ecma_get_value_type_field (ecma_value || *value_p) == ECMA_TYPE_DIRECT)
{
*value_p = ecma_value;
}
else if (ecma_is_value_float_number (ecma_value)
&& ecma_is_value_float_number (*value_p))
{
const ecma_number_t *num_src_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (ecma_value);
ecma_number_t *num_dst_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (*value_p);
*num_dst_p = *num_src_p;
}
else
{
ecma_free_value_if_not_object (*value_p);
*value_p = ecma_copy_value_if_not_object (ecma_value);
}
} /* ecma_value_assign_value */
/**
* Update the value of a float number to a new value
*
* Note:
* The original value is destroyed.
*
* @return updated ecma value
*/
ecma_value_t
ecma_update_float_number (ecma_value_t float_value, /**< original float value */
ecma_number_t new_number) /**< updated number value */
{
JERRY_ASSERT (ecma_is_value_float_number (float_value));
ecma_integer_value_t integer_number = (ecma_integer_value_t) new_number;
ecma_number_t *number_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (float_value);
if ((ecma_number_t) integer_number == new_number
&& ((integer_number == 0) ? ecma_is_number_equal_to_positive_zero (new_number)
: ECMA_IS_INTEGER_NUMBER (integer_number)))
{
ecma_dealloc_number (number_p);
return ecma_make_integer_value (integer_number);
}
*number_p = new_number;
return float_value;
} /* ecma_update_float_number */
/**
* Assign a float number to an ecma-value
*
* Note:
* value previously stored in the property is freed
*/
static void
ecma_value_assign_float_number (ecma_value_t *value_p, /**< [in, out] ecma value */
ecma_number_t ecma_number) /**< number to assign */
{
if (ecma_is_value_float_number (*value_p))
{
ecma_number_t *num_dst_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (*value_p);
*num_dst_p = ecma_number;
return;
}
if (ecma_get_value_type_field (*value_p) != ECMA_TYPE_DIRECT
&& ecma_get_value_type_field (*value_p) != ECMA_TYPE_OBJECT)
{
ecma_free_value (*value_p);
}
*value_p = ecma_create_float_number (ecma_number);
} /* ecma_value_assign_float_number */
/**
* Assign a number to an ecma-value
*
* Note:
* value previously stored in the property is freed
*/
void
ecma_value_assign_number (ecma_value_t *value_p, /**< [in, out] ecma value */
ecma_number_t ecma_number) /**< number to assign */
{
ecma_integer_value_t integer_value = (ecma_integer_value_t) ecma_number;
if ((ecma_number_t) integer_value == ecma_number
&& ((integer_value == 0) ? ecma_is_number_equal_to_positive_zero (ecma_number)
: ECMA_IS_INTEGER_NUMBER (integer_value)))
{
if (ecma_get_value_type_field (*value_p) != ECMA_TYPE_DIRECT
&& ecma_get_value_type_field (*value_p) != ECMA_TYPE_OBJECT)
{
ecma_free_value (*value_p);
}
*value_p = ecma_make_integer_value (integer_value);
return;
}
ecma_value_assign_float_number (value_p, ecma_number);
} /* ecma_value_assign_number */
/**
* Assign an uint32 value to an ecma-value
*
* Note:
* value previously stored in the property is freed
*/
void
ecma_value_assign_uint32 (ecma_value_t *value_p, /**< [in, out] ecma value */
uint32_t uint32_number) /**< number to assign */
{
if (uint32_number <= ECMA_INTEGER_NUMBER_MAX)
{
if (ecma_get_value_type_field (*value_p) != ECMA_TYPE_DIRECT
&& ecma_get_value_type_field (*value_p) != ECMA_TYPE_OBJECT)
{
ecma_free_value (*value_p);
}
*value_p = ecma_make_integer_value ((ecma_integer_value_t) uint32_number);
return;
}
ecma_value_assign_float_number (value_p, (ecma_number_t) uint32_number);
} /* ecma_value_assign_uint32 */
/**
* Free the ecma value
*/
void
ecma_free_value (ecma_value_t value) /**< value description */
{
switch (ecma_get_value_type_field (value))
{
case ECMA_TYPE_DIRECT:
{
/* no memory is allocated */
break;
}
case ECMA_TYPE_FLOAT:
{
ecma_number_t *number_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
ecma_dealloc_number (number_p);
break;
}
case ECMA_TYPE_STRING:
{
ecma_string_t *string_p = ecma_get_string_from_value (value);
ecma_deref_ecma_string (string_p);
break;
}
case ECMA_TYPE_OBJECT:
{
ecma_deref_object (ecma_get_object_from_value (value));
break;
}
}
} /* ecma_free_value */
/**
* Free the ecma value
*
* Note:
* this function is similar to ecma_free_value, but it is
* faster for direct values since no function call is performed.
* It also increases the binary size so it is recommended for
* critical code paths only.
*/
inline void __attr_always_inline___
ecma_fast_free_value (ecma_value_t value) /**< value description */
{
if (ecma_get_value_type_field (value) != ECMA_TYPE_DIRECT)
{
ecma_free_value (value);
}
} /* ecma_fast_free_value */
/**
* Free the ecma value if not an object
*/
void
ecma_free_value_if_not_object (ecma_value_t value) /**< value description */
{
if (ecma_get_value_type_field (value) != ECMA_TYPE_OBJECT)
{
ecma_free_value (value);
}
} /* ecma_free_value_if_not_object */
/**
* @}
* @}
*/

View file

@ -0,0 +1,374 @@
/* 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-globals.h"
#include "ecma-helpers.h"
#include "jrt.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmahelpers Helpers for operations with ECMA data types
* @{
*/
/**
* Allocate a collection of ecma values.
*
* @return pointer to the collection's header
*/
ecma_collection_header_t *
ecma_new_values_collection (const ecma_value_t values_buffer[], /**< ecma values */
ecma_length_t values_number, /**< number of ecma values */
bool do_ref_if_object) /**< if the value is object value,
increase reference counter of the object */
{
JERRY_ASSERT (values_buffer != NULL || values_number == 0);
const size_t values_in_chunk = JERRY_SIZE_OF_STRUCT_MEMBER (ecma_collection_chunk_t, data) / sizeof (ecma_value_t);
ecma_collection_header_t *header_p = ecma_alloc_collection_header ();
header_p->unit_number = values_number;
jmem_cpointer_t *next_chunk_cp_p = &header_p->first_chunk_cp;
ecma_collection_chunk_t *last_chunk_p = NULL;
ecma_value_t *cur_value_buf_iter_p = NULL;
ecma_value_t *cur_value_buf_end_p = NULL;
for (ecma_length_t value_index = 0;
value_index < values_number;
value_index++)
{
if (cur_value_buf_iter_p == cur_value_buf_end_p)
{
ecma_collection_chunk_t *chunk_p = ecma_alloc_collection_chunk ();
ECMA_SET_POINTER (*next_chunk_cp_p, chunk_p);
next_chunk_cp_p = &chunk_p->next_chunk_cp;
cur_value_buf_iter_p = (ecma_value_t *) chunk_p->data;
cur_value_buf_end_p = cur_value_buf_iter_p + values_in_chunk;
last_chunk_p = chunk_p;
}
JERRY_ASSERT (cur_value_buf_iter_p + 1 <= cur_value_buf_end_p);
if (do_ref_if_object)
{
*cur_value_buf_iter_p++ = ecma_copy_value (values_buffer[value_index]);
}
else
{
*cur_value_buf_iter_p++ = ecma_copy_value_if_not_object (values_buffer[value_index]);
}
}
*next_chunk_cp_p = ECMA_NULL_POINTER;
ECMA_SET_POINTER (header_p->last_chunk_cp, last_chunk_p);
return header_p;
} /* ecma_new_values_collection */
/**
* Free the collection of ecma values.
*/
void
ecma_free_values_collection (ecma_collection_header_t *header_p, /**< collection's header */
bool do_deref_if_object) /**< if the value is object value,
decrement reference counter of the object */
{
JERRY_ASSERT (header_p != NULL);
const size_t values_in_chunk = JERRY_SIZE_OF_STRUCT_MEMBER (ecma_collection_chunk_t, data) / sizeof (ecma_value_t);
ecma_collection_chunk_t *chunk_p = ECMA_GET_POINTER (ecma_collection_chunk_t,
header_p->first_chunk_cp);
ecma_length_t value_index = 0;
while (chunk_p != NULL)
{
JERRY_ASSERT (value_index < header_p->unit_number);
ecma_value_t *cur_value_buf_iter_p = (ecma_value_t *) chunk_p->data;
ecma_value_t *cur_value_buf_end_p = cur_value_buf_iter_p + values_in_chunk;
while (cur_value_buf_iter_p != cur_value_buf_end_p
&& value_index < header_p->unit_number)
{
JERRY_ASSERT (cur_value_buf_iter_p < cur_value_buf_end_p);
if (do_deref_if_object)
{
ecma_free_value (*cur_value_buf_iter_p);
}
else
{
ecma_free_value_if_not_object (*cur_value_buf_iter_p);
}
cur_value_buf_iter_p++;
value_index++;
}
ecma_collection_chunk_t *next_chunk_p = ECMA_GET_POINTER (ecma_collection_chunk_t,
chunk_p->next_chunk_cp);
ecma_dealloc_collection_chunk (chunk_p);
chunk_p = next_chunk_p;
}
ecma_dealloc_collection_header (header_p);
} /* ecma_free_values_collection */
/**
* Append new value to ecma values collection
*/
void
ecma_append_to_values_collection (ecma_collection_header_t *header_p, /**< collection's header */
ecma_value_t v, /**< ecma value to append */
bool do_ref_if_object) /**< if the value is object value,
increase reference counter of the object */
{
const size_t values_in_chunk = JERRY_SIZE_OF_STRUCT_MEMBER (ecma_collection_chunk_t, data) / sizeof (ecma_value_t);
size_t values_number = header_p->unit_number;
size_t pos_of_new_value_in_chunk = values_number % values_in_chunk;
values_number++;
if ((ecma_length_t) values_number == values_number)
{
header_p->unit_number = (ecma_length_t) values_number;
}
else
{
jerry_fatal (ERR_OUT_OF_MEMORY);
}
ecma_collection_chunk_t *chunk_p = ECMA_GET_POINTER (ecma_collection_chunk_t,
header_p->last_chunk_cp);
if (pos_of_new_value_in_chunk == 0)
{
/* all chunks are currently filled with values */
chunk_p = ecma_alloc_collection_chunk ();
chunk_p->next_chunk_cp = ECMA_NULL_POINTER;
if (header_p->last_chunk_cp == ECMA_NULL_POINTER)
{
JERRY_ASSERT (header_p->first_chunk_cp == ECMA_NULL_POINTER);
ECMA_SET_NON_NULL_POINTER (header_p->first_chunk_cp, chunk_p);
}
else
{
ecma_collection_chunk_t *last_chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
header_p->last_chunk_cp);
JERRY_ASSERT (last_chunk_p->next_chunk_cp == ECMA_NULL_POINTER);
ECMA_SET_NON_NULL_POINTER (last_chunk_p->next_chunk_cp, chunk_p);
}
ECMA_SET_NON_NULL_POINTER (header_p->last_chunk_cp, chunk_p);
}
else
{
/* last chunk can be appended with the new value */
JERRY_ASSERT (chunk_p != NULL);
}
ecma_value_t *values_p = (ecma_value_t *) chunk_p->data;
JERRY_ASSERT ((uint8_t *) (values_p + pos_of_new_value_in_chunk + 1) <= (uint8_t *) (chunk_p + 1));
if (do_ref_if_object)
{
values_p[pos_of_new_value_in_chunk] = ecma_copy_value (v);
}
else
{
values_p[pos_of_new_value_in_chunk] = ecma_copy_value_if_not_object (v);
}
} /* ecma_append_to_values_collection */
/**
* Remove last element of the collection
*
* Warning:
* the function invalidates all iterators that are configured to access the passed collection
*/
void
ecma_remove_last_value_from_values_collection (ecma_collection_header_t *header_p) /**< collection's header */
{
JERRY_ASSERT (header_p != NULL && header_p->unit_number > 0);
const size_t values_in_chunk = JERRY_SIZE_OF_STRUCT_MEMBER (ecma_collection_chunk_t, data) / sizeof (ecma_value_t);
size_t values_number = header_p->unit_number;
size_t pos_of_value_to_remove_in_chunk = (values_number - 1u) % values_in_chunk;
ecma_collection_chunk_t *last_chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
header_p->last_chunk_cp);
ecma_value_t *values_p = (ecma_value_t *) last_chunk_p->data;
JERRY_ASSERT ((uint8_t *) (values_p + pos_of_value_to_remove_in_chunk + 1) <= (uint8_t *) (last_chunk_p + 1));
ecma_value_t value_to_remove = values_p[pos_of_value_to_remove_in_chunk];
ecma_free_value (value_to_remove);
header_p->unit_number--;
if (pos_of_value_to_remove_in_chunk == 0)
{
ecma_collection_chunk_t *chunk_to_remove_p = last_chunk_p;
/* free last chunk */
if (header_p->first_chunk_cp == header_p->last_chunk_cp)
{
header_p->first_chunk_cp = ECMA_NULL_POINTER;
header_p->last_chunk_cp = ECMA_NULL_POINTER;
}
else
{
ecma_collection_chunk_t *chunk_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
header_p->first_chunk_cp);
while (chunk_iter_p->next_chunk_cp != header_p->last_chunk_cp)
{
chunk_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
chunk_iter_p->next_chunk_cp);
}
ecma_collection_chunk_t *new_last_chunk_p = chunk_iter_p;
JERRY_ASSERT (ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
new_last_chunk_p->next_chunk_cp) == chunk_to_remove_p);
ECMA_SET_NON_NULL_POINTER (header_p->last_chunk_cp, new_last_chunk_p);
new_last_chunk_p->next_chunk_cp = ECMA_NULL_POINTER;
}
ecma_dealloc_collection_chunk (chunk_to_remove_p);
}
} /* ecma_remove_last_value_from_values_collection */
/**
* Allocate a collection of ecma-strings.
*
* @return pointer to the collection's header
*/
ecma_collection_header_t *
ecma_new_strings_collection (ecma_string_t *string_ptrs_buffer[], /**< pointers to ecma-strings */
ecma_length_t strings_number) /**< number of ecma-strings */
{
JERRY_ASSERT (string_ptrs_buffer != NULL || strings_number == 0);
ecma_collection_header_t *new_collection_p;
new_collection_p = ecma_new_values_collection (NULL, 0, false);
for (ecma_length_t string_index = 0;
string_index < strings_number;
string_index++)
{
ecma_append_to_values_collection (new_collection_p,
ecma_make_string_value (string_ptrs_buffer[string_index]),
false);
}
return new_collection_p;
} /* ecma_new_strings_collection */
/**
* Initialize new collection iterator for the collection
*/
void
ecma_collection_iterator_init (ecma_collection_iterator_t *iterator_p, /**< context of iterator */
ecma_collection_header_t *collection_p) /**< header of collection */
{
iterator_p->header_p = collection_p;
iterator_p->next_chunk_cp = (collection_p != NULL ? collection_p->first_chunk_cp : JMEM_CP_NULL);
iterator_p->current_index = 0;
iterator_p->current_value_p = NULL;
iterator_p->current_chunk_end_p = NULL;
} /* ecma_collection_iterator_init */
/**
* Move collection iterator to next element if there is any.
*
* @return true - if iterator moved,
* false - otherwise (current element is last element in the collection)
*/
bool
ecma_collection_iterator_next (ecma_collection_iterator_t *iterator_p) /**< context of iterator */
{
if (iterator_p->header_p == NULL
|| unlikely (iterator_p->header_p->unit_number == 0))
{
return false;
}
const size_t values_in_chunk = JERRY_SIZE_OF_STRUCT_MEMBER (ecma_collection_chunk_t, data) / sizeof (ecma_value_t);
if (iterator_p->current_value_p == NULL)
{
JERRY_ASSERT (iterator_p->current_index == 0);
ecma_collection_chunk_t *first_chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
iterator_p->header_p->first_chunk_cp);
iterator_p->next_chunk_cp = first_chunk_p->next_chunk_cp;
iterator_p->current_value_p = (ecma_value_t *) &first_chunk_p->data;
iterator_p->current_chunk_end_p = (iterator_p->current_value_p + values_in_chunk);
}
else
{
if (iterator_p->current_index + 1 == iterator_p->header_p->unit_number)
{
return false;
}
JERRY_ASSERT (iterator_p->current_index + 1 < iterator_p->header_p->unit_number);
iterator_p->current_index++;
iterator_p->current_value_p++;
}
if (iterator_p->current_value_p == iterator_p->current_chunk_end_p)
{
ecma_collection_chunk_t *next_chunk_p = ECMA_GET_POINTER (ecma_collection_chunk_t,
iterator_p->next_chunk_cp);
JERRY_ASSERT (next_chunk_p != NULL);
iterator_p->next_chunk_cp = next_chunk_p->next_chunk_cp;
iterator_p->current_value_p = (ecma_value_t *) &next_chunk_p->data;
iterator_p->current_chunk_end_p = iterator_p->current_value_p + values_in_chunk;
}
else
{
JERRY_ASSERT (iterator_p->current_value_p < iterator_p->current_chunk_end_p);
}
return true;
} /* ecma_collection_iterator_next */
/**
* @}
* @}
*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,340 @@
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ECMA_HELPERS_H
#define ECMA_HELPERS_H
#include "ecma-globals.h"
#include "jmem-allocator.h"
#include "lit-strings.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmahelpers Helpers for operations with ECMA data types
* @{
*/
/**
* Get value of pointer from specified non-null compressed pointer.
*/
#define ECMA_GET_NON_NULL_POINTER(type, field) JMEM_CP_GET_NON_NULL_POINTER (type, field)
/**
* Get value of pointer from specified compressed pointer.
*/
#define ECMA_GET_POINTER(type, field) JMEM_CP_GET_POINTER (type, field)
/**
* Set value of non-null compressed pointer so that it will correspond
* to specified non_compressed_pointer.
*/
#define ECMA_SET_NON_NULL_POINTER(field, non_compressed_pointer) JMEM_CP_SET_NON_NULL_POINTER (field, \
non_compressed_pointer)
/**
* Set value of compressed pointer so that it will correspond
* to specified non_compressed_pointer.
*/
#define ECMA_SET_POINTER(field, non_compressed_pointer) JMEM_CP_SET_POINTER (field, non_compressed_pointer)
/**
* Convert ecma-string's contents to a cesu-8 string and put it into a buffer.
*/
#define ECMA_STRING_TO_UTF8_STRING(ecma_str_ptr, /**< ecma string pointer */ \
utf8_ptr, /**< [out] output buffer pointer */ \
utf8_str_size) /**< [out] output buffer size */ \
lit_utf8_size_t utf8_str_size; \
bool utf8_ptr ## must_be_freed; \
const lit_utf8_byte_t *utf8_ptr = ecma_string_raw_chars (ecma_str_ptr, &utf8_str_size, &utf8_ptr ## must_be_freed); \
utf8_ptr ## must_be_freed = false; /* it was used as 'is_ascii' in 'ecma_string_raw_chars', so we must reset it */ \
\
if (utf8_ptr == NULL) \
{ \
utf8_ptr = (const lit_utf8_byte_t *) jmem_heap_alloc_block (utf8_str_size); \
ecma_string_to_utf8_bytes (ecma_str_ptr, (lit_utf8_byte_t *) utf8_ptr, utf8_str_size); \
utf8_ptr ## must_be_freed = true; \
}
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
/**
* Set an internal property value of pointer
*/
#define ECMA_SET_INTERNAL_VALUE_POINTER(field, pointer) \
(field) = ((ecma_value_t) pointer)
/**
* Get an internal property value of pointer
*/
#define ECMA_GET_INTERNAL_VALUE_POINTER(type, field) \
((type *) field)
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
/**
* Set an internal property value of non-null pointer so that it will correspond
* to specified non_compressed_pointer.
*/
#define ECMA_SET_INTERNAL_VALUE_POINTER(field, non_compressed_pointer) \
ECMA_SET_NON_NULL_POINTER (field, non_compressed_pointer)
/**
* Get an internal property value of pointer from specified compressed pointer.
*/
#define ECMA_GET_INTERNAL_VALUE_POINTER(type, field) \
ECMA_GET_POINTER (type, field)
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
/**
* Free the cesu-8 string buffer allocated by 'ECMA_STRING_TO_UTF8_STRING'
*/
#define ECMA_FINALIZE_UTF8_STRING(utf8_ptr, /**< pointer to character buffer */ \
utf8_str_size) /**< buffer size */ \
if (utf8_ptr ## must_be_freed) \
{ \
JERRY_ASSERT (utf8_ptr != NULL); \
jmem_heap_free_block ((void *) utf8_ptr, utf8_str_size); \
}
/* ecma-helpers-value.c */
extern bool ecma_is_value_direct (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_simple (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_empty (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_undefined (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_null (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_boolean (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_true (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_false (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_found (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_array_hole (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_integer_number (ecma_value_t) __attr_pure___;
extern bool ecma_are_values_integer_numbers (ecma_value_t, ecma_value_t) __attr_pure___;
extern bool ecma_is_value_float_number (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_number (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_string (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_object (ecma_value_t) __attr_pure___;
extern void ecma_check_value_type_is_spec_defined (ecma_value_t);
extern ecma_value_t ecma_make_simple_value (const ecma_simple_value_t value) __attr_const___;
extern ecma_value_t ecma_make_boolean_value (bool) __attr_const___;
extern ecma_value_t ecma_make_integer_value (ecma_integer_value_t) __attr_const___;
extern ecma_value_t ecma_make_nan_value (void);
extern ecma_value_t ecma_make_number_value (ecma_number_t);
extern ecma_value_t ecma_make_int32_value (int32_t);
extern ecma_value_t ecma_make_uint32_value (uint32_t);
extern ecma_value_t ecma_make_string_value (const ecma_string_t *);
extern ecma_value_t ecma_make_object_value (const ecma_object_t *);
extern ecma_value_t ecma_make_error_value (ecma_value_t);
extern ecma_value_t ecma_make_error_obj_value (const ecma_object_t *);
extern ecma_integer_value_t ecma_get_integer_from_value (ecma_value_t) __attr_pure___;
extern ecma_number_t ecma_get_float_from_value (ecma_value_t) __attr_pure___;
extern ecma_number_t ecma_get_number_from_value (ecma_value_t) __attr_pure___;
extern uint32_t ecma_get_uint32_from_value (ecma_value_t) __attr_pure___;
extern ecma_string_t *ecma_get_string_from_value (ecma_value_t) __attr_pure___;
extern ecma_object_t *ecma_get_object_from_value (ecma_value_t) __attr_pure___;
extern ecma_value_t ecma_get_value_from_error_value (ecma_value_t) __attr_pure___;
extern ecma_value_t ecma_invert_boolean_value (ecma_value_t) __attr_pure___;
extern ecma_value_t ecma_copy_value (ecma_value_t);
extern ecma_value_t ecma_fast_copy_value (ecma_value_t);
extern ecma_value_t ecma_copy_value_if_not_object (ecma_value_t);
extern ecma_value_t ecma_update_float_number (ecma_value_t, ecma_number_t);
extern void ecma_value_assign_value (ecma_value_t *, ecma_value_t);
extern void ecma_value_assign_number (ecma_value_t *, ecma_number_t);
extern void ecma_value_assign_uint32 (ecma_value_t *, uint32_t);
extern void ecma_free_value (ecma_value_t);
extern void ecma_fast_free_value (ecma_value_t);
extern void ecma_free_value_if_not_object (ecma_value_t);
/* ecma-helpers-string.c */
extern ecma_string_t *ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *, lit_utf8_size_t);
extern ecma_string_t *ecma_new_ecma_string_from_utf8_to_cesu8 (const lit_utf8_byte_t *, lit_utf8_size_t);
extern ecma_string_t *ecma_new_ecma_string_from_code_unit (ecma_char_t);
extern ecma_string_t *ecma_new_ecma_string_from_uint32 (uint32_t);
extern ecma_string_t *ecma_new_ecma_string_from_number (ecma_number_t);
extern ecma_string_t *ecma_new_ecma_string_from_magic_string_id (lit_magic_string_id_t);
extern ecma_string_t *ecma_new_ecma_string_from_magic_string_ex_id (lit_magic_string_ex_id_t);
extern ecma_string_t *ecma_new_ecma_length_string ();
extern ecma_string_t *ecma_concat_ecma_strings (ecma_string_t *, ecma_string_t *);
extern void ecma_ref_ecma_string (ecma_string_t *);
extern void ecma_deref_ecma_string (ecma_string_t *);
extern ecma_number_t ecma_string_to_number (const ecma_string_t *);
extern bool ecma_string_get_array_index (const ecma_string_t *, uint32_t *);
extern lit_utf8_size_t __attr_return_value_should_be_checked___
ecma_string_copy_to_utf8_buffer (const ecma_string_t *, lit_utf8_byte_t *, lit_utf8_size_t);
extern lit_utf8_size_t __attr_return_value_should_be_checked___
ecma_string_copy_and_convert_to_utf8_buffer (const ecma_string_t *, lit_utf8_byte_t *, lit_utf8_size_t);
extern void ecma_string_to_utf8_bytes (const ecma_string_t *, lit_utf8_byte_t *, lit_utf8_size_t);
extern const lit_utf8_byte_t *ecma_string_raw_chars (const ecma_string_t *, lit_utf8_size_t *, bool *);
extern void ecma_init_ecma_string_from_uint32 (ecma_string_t *, uint32_t);
extern void ecma_init_ecma_length_string (ecma_string_t *);
extern bool ecma_string_is_empty (const ecma_string_t *);
extern bool ecma_string_is_length (const ecma_string_t *);
extern bool ecma_compare_ecma_strings_equal_hashes (const ecma_string_t *, const ecma_string_t *);
extern bool ecma_compare_ecma_strings (const ecma_string_t *, const ecma_string_t *);
extern bool ecma_compare_ecma_strings_relational (const ecma_string_t *, const ecma_string_t *);
extern ecma_length_t ecma_string_get_length (const ecma_string_t *);
extern lit_utf8_size_t ecma_string_get_size (const ecma_string_t *);
extern lit_utf8_size_t ecma_string_get_utf8_size (const ecma_string_t *);
extern ecma_char_t ecma_string_get_char_at_pos (const ecma_string_t *, ecma_length_t);
extern ecma_string_t *ecma_get_magic_string (lit_magic_string_id_t);
extern ecma_string_t *ecma_get_magic_string_ex (lit_magic_string_ex_id_t);
extern bool ecma_is_string_magic (const ecma_string_t *, lit_magic_string_id_t *);
extern lit_string_hash_t ecma_string_hash (const ecma_string_t *);
extern ecma_string_t *ecma_string_substr (const ecma_string_t *, ecma_length_t, ecma_length_t);
extern ecma_string_t *ecma_string_trim (const ecma_string_t *);
/* ecma-helpers-number.c */
extern ecma_number_t ecma_number_make_nan (void);
extern ecma_number_t ecma_number_make_infinity (bool);
extern bool ecma_number_is_nan (ecma_number_t);
extern bool ecma_number_is_negative (ecma_number_t);
extern bool ecma_number_is_zero (ecma_number_t);
extern bool ecma_number_is_infinity (ecma_number_t);
extern int32_t
ecma_number_get_fraction_and_exponent (ecma_number_t, uint64_t *, int32_t *);
extern ecma_number_t
ecma_number_make_normal_positive_from_fraction_and_exponent (uint64_t, int32_t);
extern ecma_number_t
ecma_number_make_from_sign_mantissa_and_exponent (bool, uint64_t, int32_t);
extern ecma_number_t ecma_number_get_prev (ecma_number_t);
extern ecma_number_t ecma_number_get_next (ecma_number_t);
extern ecma_number_t ecma_number_negate (ecma_number_t);
extern ecma_number_t ecma_number_trunc (ecma_number_t);
extern ecma_number_t ecma_number_calc_remainder (ecma_number_t, ecma_number_t);
extern ecma_number_t ecma_number_add (ecma_number_t, ecma_number_t);
extern ecma_number_t ecma_number_substract (ecma_number_t, ecma_number_t);
extern ecma_number_t ecma_number_multiply (ecma_number_t, ecma_number_t);
extern ecma_number_t ecma_number_divide (ecma_number_t, ecma_number_t);
extern lit_utf8_size_t ecma_number_to_decimal (ecma_number_t, lit_utf8_byte_t *, int32_t *);
/* ecma-helpers-values-collection.c */
extern ecma_collection_header_t *ecma_new_values_collection (const ecma_value_t[], ecma_length_t, bool);
extern void ecma_free_values_collection (ecma_collection_header_t *, bool);
extern void ecma_append_to_values_collection (ecma_collection_header_t *, ecma_value_t, bool);
extern void ecma_remove_last_value_from_values_collection (ecma_collection_header_t *);
extern ecma_collection_header_t *ecma_new_strings_collection (ecma_string_t *[], ecma_length_t);
/**
* Context of ecma values' collection iterator
*/
typedef struct
{
ecma_collection_header_t *header_p; /**< collection header */
jmem_cpointer_t next_chunk_cp; /**< compressed pointer to next chunk */
ecma_length_t current_index; /**< index of current element */
const ecma_value_t *current_value_p; /**< pointer to current element */
const ecma_value_t *current_chunk_beg_p; /**< pointer to beginning of current chunk's data */
const ecma_value_t *current_chunk_end_p; /**< pointer to place right after the end of current chunk's data */
} ecma_collection_iterator_t;
extern void
ecma_collection_iterator_init (ecma_collection_iterator_t *, ecma_collection_header_t *);
extern bool
ecma_collection_iterator_next (ecma_collection_iterator_t *);
/* ecma-helpers.c */
extern ecma_object_t *ecma_create_object (ecma_object_t *, bool, bool, ecma_object_type_t);
extern ecma_object_t *ecma_create_decl_lex_env (ecma_object_t *);
extern ecma_object_t *ecma_create_object_lex_env (ecma_object_t *, ecma_object_t *, bool);
extern bool ecma_is_lexical_environment (const ecma_object_t *) __attr_pure___;
extern bool ecma_get_object_extensible (const ecma_object_t *) __attr_pure___;
extern void ecma_set_object_extensible (ecma_object_t *, bool);
extern ecma_object_type_t ecma_get_object_type (const ecma_object_t *) __attr_pure___;
extern void ecma_set_object_type (ecma_object_t *, ecma_object_type_t);
extern ecma_object_t *ecma_get_object_prototype (const ecma_object_t *) __attr_pure___;
extern bool ecma_get_object_is_builtin (const ecma_object_t *) __attr_pure___;
extern void ecma_set_object_is_builtin (ecma_object_t *);
extern ecma_lexical_environment_type_t ecma_get_lex_env_type (const ecma_object_t *) __attr_pure___;
extern ecma_object_t *ecma_get_lex_env_outer_reference (const ecma_object_t *) __attr_pure___;
extern ecma_property_header_t *ecma_get_property_list (const ecma_object_t *) __attr_pure___;
extern ecma_object_t *ecma_get_lex_env_binding_object (const ecma_object_t *) __attr_pure___;
extern bool ecma_get_lex_env_provide_this (const ecma_object_t *) __attr_pure___;
extern ecma_value_t *ecma_create_internal_property (ecma_object_t *, ecma_internal_property_id_t);
extern ecma_value_t *ecma_find_internal_property (ecma_object_t *, ecma_internal_property_id_t);
extern ecma_value_t *ecma_get_internal_property (ecma_object_t *, ecma_internal_property_id_t);
extern ecma_property_value_t *
ecma_create_named_data_property (ecma_object_t *, ecma_string_t *, uint8_t, ecma_property_t **);
extern ecma_property_value_t *
ecma_create_named_accessor_property (ecma_object_t *, ecma_string_t *, ecma_object_t *, ecma_object_t *, uint8_t);
extern ecma_property_t *
ecma_find_named_property (ecma_object_t *, ecma_string_t *);
extern ecma_property_value_t *
ecma_get_named_data_property (ecma_object_t *, ecma_string_t *);
extern void ecma_free_property (ecma_object_t *, ecma_string_t *, ecma_property_t *);
extern void ecma_delete_property (ecma_object_t *, ecma_property_value_t *);
extern void ecma_named_data_property_assign_value (ecma_object_t *, ecma_property_value_t *, ecma_value_t);
extern ecma_object_t *ecma_get_named_accessor_property_getter (const ecma_property_value_t *);
extern ecma_object_t *ecma_get_named_accessor_property_setter (const ecma_property_value_t *);
extern void ecma_set_named_accessor_property_getter (ecma_object_t *, ecma_property_value_t *, ecma_object_t *);
extern void ecma_set_named_accessor_property_setter (ecma_object_t *, ecma_property_value_t *, ecma_object_t *);
extern bool ecma_is_property_writable (ecma_property_t);
extern void ecma_set_property_writable_attr (ecma_property_t *, bool);
extern bool ecma_is_property_enumerable (ecma_property_t);
extern void ecma_set_property_enumerable_attr (ecma_property_t *, bool);
extern bool ecma_is_property_configurable (ecma_property_t);
extern void ecma_set_property_configurable_attr (ecma_property_t *, bool);
extern bool ecma_is_property_lcached (ecma_property_t *);
extern void ecma_set_property_lcached (ecma_property_t *, bool);
extern ecma_property_descriptor_t ecma_make_empty_property_descriptor (void);
extern void ecma_free_property_descriptor (ecma_property_descriptor_t *);
extern ecma_property_t *ecma_get_next_property_pair (ecma_property_pair_t *);
extern void ecma_bytecode_ref (ecma_compiled_code_t *);
extern void ecma_bytecode_deref (ecma_compiled_code_t *);
/* ecma-helpers-external-pointers.c */
extern bool
ecma_create_external_pointer_property (ecma_object_t *, ecma_internal_property_id_t, ecma_external_pointer_t);
extern bool
ecma_get_external_pointer_value (ecma_object_t *, ecma_internal_property_id_t, ecma_external_pointer_t *);
extern void
ecma_free_external_pointer_in_property (ecma_property_t *);
/* ecma-helpers-conversion.c */
extern ecma_number_t ecma_utf8_string_to_number (const lit_utf8_byte_t *, lit_utf8_size_t);
extern lit_utf8_size_t ecma_uint32_to_utf8_string (uint32_t, lit_utf8_byte_t *, lit_utf8_size_t);
extern uint32_t ecma_number_to_uint32 (ecma_number_t);
extern int32_t ecma_number_to_int32 (ecma_number_t);
extern lit_utf8_size_t ecma_number_to_utf8_string (ecma_number_t, lit_utf8_byte_t *, lit_utf8_size_t);
/* ecma-helpers-errol.c */
extern lit_utf8_size_t ecma_errol0_dtoa (double, lit_utf8_byte_t *, int32_t *);
/**
* @}
* @}
*/
#endif /* !ECMA_HELPERS_H */

View 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.
*/
#include "ecma-builtins.h"
#include "ecma-gc.h"
#include "ecma-helpers.h"
#include "ecma-init-finalize.h"
#include "ecma-lcache.h"
#include "ecma-lex-env.h"
#include "ecma-literal-storage.h"
#include "jmem-allocator.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmainitfinalize Initialization and finalization of ECMA components
* @{
*/
/**
* Initialize ECMA components
*/
void
ecma_init (void)
{
ecma_lcache_init ();
ecma_init_global_lex_env ();
jmem_register_free_unused_memory_callback (ecma_free_unused_memory);
} /* ecma_init */
/**
* Finalize ECMA components
*/
void
ecma_finalize (void)
{
jmem_unregister_free_unused_memory_callback (ecma_free_unused_memory);
ecma_finalize_global_lex_env ();
ecma_finalize_builtins ();
ecma_gc_run (JMEM_FREE_UNUSED_MEMORY_SEVERITY_LOW);
ecma_finalize_lit_storage ();
} /* ecma_finalize */
/**
* @}
* @}
*/

View 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_INIT_FINALIZE_H
#define ECMA_INIT_FINALIZE_H
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmainitfinalize Initialization and finalization of ECMA components
* @{
*/
extern void ecma_init (void);
extern void ecma_finalize (void);
/**
* @}
* @}
*/
#endif /* !ECMA_INIT_FINALIZE_H */

View file

@ -0,0 +1,229 @@
/* 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-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-lcache.h"
#include "jcontext.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmalcache Property lookup cache
* @{
*/
#ifndef CONFIG_ECMA_LCACHE_DISABLE
/**
* Mask for hash bits
*/
#define ECMA_LCACHE_HASH_MASK (ECMA_LCACHE_HASH_ROWS_COUNT - 1)
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
/**
* Initialize LCache
*/
void
ecma_lcache_init (void)
{
#ifndef CONFIG_ECMA_LCACHE_DISABLE
memset (JERRY_HASH_TABLE_CONTEXT (table), 0, sizeof (jerry_hash_table_t));
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
} /* ecma_lcache_init */
#ifndef CONFIG_ECMA_LCACHE_DISABLE
/**
* Invalidate specified LCache entry
*/
static inline void __attr_always_inline___
ecma_lcache_invalidate_entry (ecma_lcache_hash_entry_t *entry_p) /**< entry to invalidate */
{
JERRY_ASSERT (entry_p != NULL);
JERRY_ASSERT (entry_p->object_cp != ECMA_NULL_POINTER);
JERRY_ASSERT (entry_p->prop_name_cp != ECMA_NULL_POINTER);
JERRY_ASSERT (entry_p->prop_p != NULL);
entry_p->object_cp = ECMA_NULL_POINTER;
ecma_set_property_lcached (entry_p->prop_p, false);
} /* ecma_lcache_invalidate_entry */
/**
* Compute the row index of object / property name pair
*
* @return row index
*/
static inline size_t __attr_always_inline___
ecma_lcache_row_index (jmem_cpointer_t object_cp, /**< compressed pointer to object */
const ecma_string_t *prop_name_p) /**< proeprty name */
{
/* Randomize the hash of the property name with the object pointer using a xor operation,
* so properties of different objects with the same name can be cached effectively. */
return (size_t) ((ecma_string_hash (prop_name_p) ^ object_cp) & ECMA_LCACHE_HASH_MASK);
} /* ecma_lcache_row_index */
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
/**
* Insert an entry into LCache
*/
void
ecma_lcache_insert (ecma_object_t *object_p, /**< object */
ecma_string_t *prop_name_p, /**< property name */
ecma_property_t *prop_p) /**< property */
{
JERRY_ASSERT (object_p != NULL);
JERRY_ASSERT (prop_name_p != NULL);
JERRY_ASSERT (prop_p != NULL && !ecma_is_property_lcached (prop_p));
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
#ifndef CONFIG_ECMA_LCACHE_DISABLE
jmem_cpointer_t object_cp;
ECMA_SET_NON_NULL_POINTER (object_cp, object_p);
size_t row_index = ecma_lcache_row_index (object_cp, prop_name_p);
ecma_lcache_hash_entry_t *entries_p = JERRY_HASH_TABLE_CONTEXT (table)[row_index];
int32_t entry_index;
for (entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++)
{
if (entries_p[entry_index].object_cp == ECMA_NULL_POINTER)
{
break;
}
}
if (entry_index == ECMA_LCACHE_HASH_ROW_LENGTH)
{
/* Invalidate the last entry. */
ecma_lcache_invalidate_entry (entries_p + ECMA_LCACHE_HASH_ROW_LENGTH - 1);
/* Shift other entries towards the end. */
for (uint32_t i = ECMA_LCACHE_HASH_ROW_LENGTH - 1; i > 0; i--)
{
entries_p[i] = entries_p[i - 1];
}
entry_index = 0;
}
ecma_lcache_hash_entry_t *entry_p = entries_p + entry_index;
ECMA_SET_NON_NULL_POINTER (entry_p->object_cp, object_p);
ECMA_SET_NON_NULL_POINTER (entry_p->prop_name_cp, prop_name_p);
entry_p->prop_p = prop_p;
ecma_set_property_lcached (entry_p->prop_p, true);
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
} /* ecma_lcache_insert */
/**
* Lookup property in the LCache
*
* @return a pointer to an ecma_property_t if the lookup is successful
* NULL otherwise
*/
inline ecma_property_t * __attr_always_inline___
ecma_lcache_lookup (ecma_object_t *object_p, /**< object */
const ecma_string_t *prop_name_p) /**< property's name */
{
JERRY_ASSERT (object_p != NULL);
JERRY_ASSERT (prop_name_p != NULL);
#ifndef CONFIG_ECMA_LCACHE_DISABLE
jmem_cpointer_t object_cp;
ECMA_SET_NON_NULL_POINTER (object_cp, object_p);
size_t row_index = ecma_lcache_row_index (object_cp, prop_name_p);
ecma_lcache_hash_entry_t *entry_p = JERRY_HASH_TABLE_CONTEXT (table) [row_index];
ecma_lcache_hash_entry_t *entry_end_p = entry_p + ECMA_LCACHE_HASH_ROW_LENGTH;
ecma_string_container_t prop_container = ECMA_STRING_GET_CONTAINER (prop_name_p);
while (entry_p < entry_end_p)
{
if (entry_p->object_cp == object_cp)
{
ecma_string_t *entry_prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
entry_p->prop_name_cp);
JERRY_ASSERT ((prop_name_p->hash & ECMA_LCACHE_HASH_MASK) == (entry_prop_name_p->hash & ECMA_LCACHE_HASH_MASK));
if (prop_name_p == entry_prop_name_p
|| (prop_container > ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING
&& prop_container == ECMA_STRING_GET_CONTAINER (entry_prop_name_p)
&& prop_name_p->u.common_field == entry_prop_name_p->u.common_field))
{
ecma_property_t *prop_p = entry_p->prop_p;
JERRY_ASSERT (prop_p != NULL && ecma_is_property_lcached (prop_p));
return prop_p;
}
else
{
/* They can be equal, but generic string comparison is too costly. */
}
}
entry_p++;
}
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
return NULL;
} /* ecma_lcache_lookup */
/**
* Invalidate LCache entries associated with given object and property name / property
*/
void
ecma_lcache_invalidate (ecma_object_t *object_p, /**< object */
ecma_string_t *prop_name_p, /**< property's name */
ecma_property_t *prop_p) /**< property */
{
JERRY_ASSERT (object_p != NULL);
JERRY_ASSERT (prop_name_p != NULL);
JERRY_ASSERT (prop_p != NULL && ecma_is_property_lcached (prop_p));
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
#ifndef CONFIG_ECMA_LCACHE_DISABLE
jmem_cpointer_t object_cp;
ECMA_SET_NON_NULL_POINTER (object_cp, object_p);
size_t row_index = ecma_lcache_row_index (object_cp, prop_name_p);
ecma_lcache_hash_entry_t *entry_p = JERRY_HASH_TABLE_CONTEXT (table) [row_index];
for (uint32_t entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++)
{
if (entry_p->object_cp != ECMA_NULL_POINTER && entry_p->prop_p == prop_p)
{
JERRY_ASSERT (entry_p->object_cp == object_cp);
ecma_lcache_invalidate_entry (entry_p);
return;
}
entry_p++;
}
/* The property must be present. */
JERRY_UNREACHABLE ();
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
} /* ecma_lcache_invalidate */
/**
* @}
* @}
*/

View file

@ -0,0 +1,36 @@
/* 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_LCACHE_H
#define ECMA_LCACHE_H
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmalcache Property lookup cache
* @{
*/
extern void ecma_lcache_init (void);
extern void ecma_lcache_insert (ecma_object_t *, ecma_string_t *, ecma_property_t *);
extern ecma_property_t *ecma_lcache_lookup (ecma_object_t *, const ecma_string_t *);
extern void ecma_lcache_invalidate (ecma_object_t *, ecma_string_t *, ecma_property_t *);
/**
* @}
* @}
*/
#endif /* !ECMA_LCACHE_H */

View file

@ -0,0 +1,514 @@
/* Copyright 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-literal-storage.h"
#include "ecma-helpers.h"
#include "jcontext.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmalitstorage Literal storage
* @{
*/
/**
* Free string list
*/
static void
ecma_free_string_list (ecma_lit_storage_item_t *string_list_p) /**< string list */
{
while (string_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (string_list_p->values[i] != JMEM_CP_NULL)
{
ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
string_list_p->values[i]);
JERRY_ASSERT (ECMA_STRING_IS_REF_EQUALS_TO_ONE (string_p));
ecma_deref_ecma_string (string_p);
}
}
ecma_lit_storage_item_t *prev_item = string_list_p;
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
jmem_pools_free (prev_item, sizeof (ecma_lit_storage_item_t));
}
} /* ecma_free_string_list */
/**
* Finalize literal storage
*/
void
ecma_finalize_lit_storage (void)
{
ecma_free_string_list (JERRY_CONTEXT (string_list_first_p));
ecma_free_string_list (JERRY_CONTEXT (number_list_first_p));
} /* ecma_finalize_lit_storage */
/**
* Find or create a literal string.
*
* @return ecma_string_t compressed pointer
*/
jmem_cpointer_t
ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string to be searched */
lit_utf8_size_t size) /**< size of the string */
{
ecma_string_t *string_p = ecma_new_ecma_string_from_utf8 (chars_p, size);
ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p);
jmem_cpointer_t *empty_cpointer_p = NULL;
while (string_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (string_list_p->values[i] == JMEM_CP_NULL)
{
if (empty_cpointer_p == NULL)
{
empty_cpointer_p = string_list_p->values + i;
}
}
else
{
ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
string_list_p->values[i]);
if (ecma_compare_ecma_strings (string_p, value_p))
{
/* Return with string if found in the list. */
ecma_deref_ecma_string (string_p);
return string_list_p->values[i];
}
}
}
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
}
jmem_cpointer_t result;
JMEM_CP_SET_NON_NULL_POINTER (result, string_p);
if (empty_cpointer_p != NULL)
{
*empty_cpointer_p = result;
return result;
}
ecma_lit_storage_item_t *new_item_p;
new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc (sizeof (ecma_lit_storage_item_t));
new_item_p->values[0] = result;
for (int i = 1; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
new_item_p->values[i] = JMEM_CP_NULL;
}
JMEM_CP_SET_POINTER (new_item_p->next_cp, JERRY_CONTEXT (string_list_first_p));
JERRY_CONTEXT (string_list_first_p) = new_item_p;
return result;
} /* ecma_find_or_create_literal_string */
/**
* Find or create a literal number.
*
* @return ecma_string_t compressed pointer
*/
jmem_cpointer_t
ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be searched */
{
ecma_value_t num = ecma_make_number_value (number_arg);
ecma_lit_storage_item_t *number_list_p = JERRY_CONTEXT (number_list_first_p);
jmem_cpointer_t *empty_cpointer_p = NULL;
while (number_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (number_list_p->values[i] == JMEM_CP_NULL)
{
if (empty_cpointer_p == NULL)
{
empty_cpointer_p = number_list_p->values + i;
}
}
else
{
ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
number_list_p->values[i]);
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER);
if (ecma_is_value_integer_number (num))
{
if (value_p->u.lit_number == num)
{
return number_list_p->values[i];
}
}
else
{
if (ecma_is_value_float_number (value_p->u.lit_number)
&& ecma_get_float_from_value (value_p->u.lit_number) == ecma_get_float_from_value (num))
{
ecma_free_value (num);
return number_list_p->values[i];
}
}
}
}
number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp);
}
ecma_string_t *string_p = (ecma_string_t *) jmem_pools_alloc (sizeof (ecma_string_t));
string_p->refs_and_container = ECMA_STRING_REF_ONE | ECMA_STRING_LITERAL_NUMBER;
string_p->u.lit_number = num;
jmem_cpointer_t result;
JMEM_CP_SET_NON_NULL_POINTER (result, string_p);
if (empty_cpointer_p != NULL)
{
*empty_cpointer_p = result;
return result;
}
ecma_lit_storage_item_t *new_item_p;
new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc (sizeof (ecma_lit_storage_item_t));
new_item_p->values[0] = result;
for (int i = 1; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
new_item_p->values[i] = JMEM_CP_NULL;
}
JMEM_CP_SET_POINTER (new_item_p->next_cp, JERRY_CONTEXT (number_list_first_p));
JERRY_CONTEXT (number_list_first_p) = new_item_p;
return result;
} /* ecma_find_or_create_literal_number */
/**
* Log2 of snapshot literal alignment.
*/
#define JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG 2
/**
* Snapshot literal alignment.
*/
#define JERRY_SNAPSHOT_LITERAL_ALIGNMENT (1u << JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG)
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
/**
* Save literals to specified snapshot buffer.
*
* @return true, if save was performed successfully (i.e. buffer size is sufficient),
* false - otherwise.
*/
bool
ecma_save_literals_for_snapshot (uint8_t *buffer_p, /**< [out] output snapshot buffer */
size_t buffer_size, /**< size of the buffer */
size_t *in_out_buffer_offset_p, /**< [in,out] write position in the buffer */
lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal identifiers
* to the literal offsets
* in snapshot */
uint32_t *out_map_len_p, /**< [out] number of literals */
uint32_t *out_lit_table_size_p) /**< [out] number of bytes, saved to snapshot buffer */
{
/* Count literals and literal space. */
uint32_t string_count = 0;
uint32_t number_count = 0;
uint32_t lit_table_size = 2 * sizeof (uint32_t);
ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p);
while (string_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (string_list_p->values[i] != JMEM_CP_NULL)
{
ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
string_list_p->values[i]);
lit_table_size += (uint32_t) JERRY_ALIGNUP (sizeof (uint16_t) + ecma_string_get_size (string_p),
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
string_count++;
}
}
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
}
ecma_lit_storage_item_t *number_list_p = JERRY_CONTEXT (number_list_first_p);
while (number_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (number_list_p->values[i] != JMEM_CP_NULL)
{
lit_table_size += (uint32_t) sizeof (ecma_number_t);
number_count++;
}
}
number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp);
}
/* Check whether enough space is available. */
if (*in_out_buffer_offset_p + lit_table_size > buffer_size)
{
return false;
}
/* Check whether the maximum literal table size is reached. */
if ((lit_table_size >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG) > UINT16_MAX)
{
return false;
}
uint32_t total_count = string_count + number_count;
lit_mem_to_snapshot_id_map_entry_t *map_p;
map_p = jmem_heap_alloc_block (total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
/* Set return values (no error is possible from here). */
buffer_p += *in_out_buffer_offset_p;
*in_out_buffer_offset_p += lit_table_size;
*out_map_p = map_p;
*out_map_len_p = total_count;
*out_lit_table_size_p = lit_table_size;
/* Write data into the buffer. */
/* The zero value is reserved for NULL (no literal)
* constant so the first literal must have offset one. */
uint32_t literal_offset = JERRY_SNAPSHOT_LITERAL_ALIGNMENT;
((uint32_t *) buffer_p)[0] = string_count;
((uint32_t *) buffer_p)[1] = number_count;
buffer_p += 2 * sizeof (uint32_t);
string_list_p = JERRY_CONTEXT (string_list_first_p);
while (string_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (string_list_p->values[i] != JMEM_CP_NULL)
{
map_p->literal_id = string_list_p->values[i];
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
map_p++;
ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
string_list_p->values[i]);
ecma_length_t length = ecma_string_get_size (string_p);
*((uint16_t *) buffer_p) = (uint16_t) length;
ecma_string_to_utf8_bytes (string_p, buffer_p + sizeof (uint16_t), length);
length = JERRY_ALIGNUP (sizeof (uint16_t) + length,
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
buffer_p += length;
literal_offset += length;
}
}
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
}
number_list_p = JERRY_CONTEXT (number_list_first_p);
while (number_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (number_list_p->values[i] != JMEM_CP_NULL)
{
map_p->literal_id = number_list_p->values[i];
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
map_p++;
ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
number_list_p->values[i]);
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER);
ecma_number_t num = ecma_get_number_from_value (value_p->u.lit_number);
memcpy (buffer_p, &num, sizeof (ecma_number_t));
ecma_length_t length = JERRY_ALIGNUP (sizeof (ecma_number_t),
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
buffer_p += length;
literal_offset += length;
}
}
number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp);
}
return true;
} /* ecma_save_literals_for_snapshot */
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
/**
* Helper function for ecma_load_literals_from_snapshot.
*
* Note: always inline because it is used only once.
*
* @return true, if load was performed successfully
* false - otherwise (i.e. buffer length is incorrect).
*/
static inline bool __attr_always_inline___
ecma_load_literals_from_buffer (const uint8_t *buffer_p, /**< buffer with literal table in snapshot */
uint32_t lit_table_size, /**< size of literal table in snapshot */
lit_mem_to_snapshot_id_map_entry_t *map_p, /**< literal map */
uint32_t string_count, /**< number of strings */
uint32_t number_count) /**< number of numbers */
{
/* The zero value is reserved for NULL (no literal)
* constant so the first literal must have offset one. */
uint32_t literal_offset = JERRY_SNAPSHOT_LITERAL_ALIGNMENT;
/* Load strings first. */
while (string_count > 0)
{
if (lit_table_size < literal_offset + sizeof (uint32_t))
{
/* Buffer is not sufficent. */
return false;
}
lit_utf8_size_t length = *((uint16_t *) buffer_p);
lit_utf8_size_t aligned_length = JERRY_ALIGNUP (sizeof (uint16_t) + length,
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
if (lit_table_size < literal_offset + aligned_length)
{
/* Buffer is not sufficent. */
return false;
}
map_p->literal_id = ecma_find_or_create_literal_string (buffer_p + sizeof (uint16_t), length);
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
map_p++;
buffer_p += aligned_length;
literal_offset += aligned_length;
string_count--;
}
/* Load numbers. */
while (number_count > 0)
{
if (lit_table_size < literal_offset + sizeof (ecma_number_t))
{
/* Buffer is not sufficent. */
return false;
}
ecma_number_t num;
memcpy (&num, buffer_p, sizeof (ecma_number_t));
map_p->literal_id = ecma_find_or_create_literal_number (num);
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
map_p++;
ecma_length_t length = JERRY_ALIGNUP (sizeof (ecma_number_t),
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
buffer_p += length;
literal_offset += length;
number_count--;
}
return (lit_table_size == (literal_offset + 2 * sizeof (uint32_t) - JERRY_SNAPSHOT_LITERAL_ALIGNMENT));
} /* ecma_load_literals_from_buffer */
/**
* Load literals from snapshot.
*
* @return true, if load was performed successfully (i.e. literals saved in the snapshot are consistent),
* false - otherwise (i.e. snapshot is incorrect).
*/
bool
ecma_load_literals_from_snapshot (const uint8_t *buffer_p, /**< buffer with literal table in snapshot */
uint32_t lit_table_size, /**< size of literal table in snapshot */
lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal offsets
* in snapshot to identifiers
* of loaded literals in literal
* storage */
uint32_t *out_map_len_p) /**< [out] literals number */
{
*out_map_p = NULL;
if (lit_table_size < 2 * sizeof (uint32_t))
{
/* Buffer is not sufficent. */
return false;
}
uint32_t string_count = ((uint32_t *) buffer_p)[0];
uint32_t number_count = ((uint32_t *) buffer_p)[1];
buffer_p += 2 * sizeof (uint32_t);
uint32_t total_count = string_count + number_count;
lit_mem_to_snapshot_id_map_entry_t *map_p;
*out_map_len_p = total_count;
if (total_count == 0)
{
return true;
}
map_p = jmem_heap_alloc_block (total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
*out_map_p = map_p;
if (ecma_load_literals_from_buffer (buffer_p, lit_table_size, map_p, string_count, number_count))
{
return true;
}
jmem_heap_free_block (map_p, total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
*out_map_p = NULL;
return false;
} /* ecma_load_literals_from_snapshot */
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
/**
* @}
* @}
*/

View file

@ -0,0 +1,62 @@
/* Copyright 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_LIT_STORAGE_H
#define ECMA_LIT_STORAGE_H
#include "ecma-globals.h"
#include "jmem-allocator.h"
#include "lit-globals.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmalitstorage Literal storage
* @{
*/
/**
* Snapshot literal - offset map
*/
typedef struct
{
jmem_cpointer_t literal_id; /**< literal id */
jmem_cpointer_t literal_offset; /**< literal offset */
} lit_mem_to_snapshot_id_map_entry_t;
extern void ecma_finalize_lit_storage (void);
extern jmem_cpointer_t ecma_find_or_create_literal_string (const lit_utf8_byte_t *, lit_utf8_size_t);
extern jmem_cpointer_t ecma_find_or_create_literal_number (ecma_number_t);
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
extern bool
ecma_save_literals_for_snapshot (uint8_t *, size_t, size_t *,
lit_mem_to_snapshot_id_map_entry_t **, uint32_t *, uint32_t *);
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
extern bool
ecma_load_literals_from_snapshot (const uint8_t *, uint32_t,
lit_mem_to_snapshot_id_map_entry_t **, uint32_t *);
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
/**
* @}
* @}
*/
#endif /* !ECMA_LIT_STORAGE_H */

View file

@ -0,0 +1,519 @@
/* 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-globals.h"
#include "ecma-helpers.h"
#include "ecma-property-hashmap.h"
#include "jrt-libc-includes.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmapropertyhashmap Property hashmap
* @{
*/
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
/**
* Compute the total size of the property hashmap.
*/
#define ECMA_PROPERTY_HASHMAP_GET_TOTAL_SIZE(max_property_count) \
(sizeof (ecma_property_hashmap_t) + (max_property_count * sizeof (jmem_cpointer_t)) + (max_property_count >> 3))
/**
* Number of items in the stepping table.
*/
#define ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS 8
/**
* Stepping values for searching items in the hashmap.
*/
static const uint8_t ecma_property_hashmap_steps[ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS] JERRY_CONST_DATA =
{
3, 5, 7, 11, 13, 17, 19, 23
};
/**
* Get the value of a bit in a bitmap.
*/
#define ECMA_PROPERTY_HASHMAP_GET_BIT(byte_p, index) \
((byte_p)[(index) >> 3] & (1 << ((index) & 0x7)))
/**
* Clear the value of a bit in a bitmap.
*/
#define ECMA_PROPERTY_HASHMAP_CLEAR_BIT(byte_p, index) \
((byte_p)[(index) >> 3] = (uint8_t) ((byte_p)[(index) >> 3] & ~(1 << ((index) & 0x7))))
/**
* Set the value of a bit in a bitmap.
*/
#define ECMA_PROPERTY_HASHMAP_SET_BIT(byte_p, index) \
((byte_p)[(index) >> 3] = (uint8_t) ((byte_p)[(index) >> 3] | (1 << ((index) & 0x7))))
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
/**
* Create a new property hashmap for the object.
* The object must not have a property hashmap.
*/
void
ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
{
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
JERRY_ASSERT (ecma_get_property_list (object_p) != NULL);
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (ecma_get_property_list (object_p)));
uint32_t named_property_count = 0;
ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);
while (prop_iter_p != NULL)
{
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
ecma_property_types_t type = ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[i]);
if (type == ECMA_PROPERTY_TYPE_NAMEDDATA || type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
{
named_property_count++;
}
}
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
prop_iter_p->next_property_cp);
}
/* The max_property_count must be power of 2. */
uint32_t max_property_count = ECMA_PROPERTY_HASMAP_MINIMUM_SIZE;
/* At least 1/3 items must be NULL. */
while (max_property_count < (named_property_count + (named_property_count >> 1)))
{
max_property_count <<= 1;
}
size_t total_size = ECMA_PROPERTY_HASHMAP_GET_TOTAL_SIZE (max_property_count);
ecma_property_hashmap_t *hashmap_p = (ecma_property_hashmap_t *) jmem_heap_alloc_block_null_on_error (total_size);
if (hashmap_p == NULL)
{
return;
}
memset (hashmap_p, 0, total_size);
hashmap_p->header.types[0] = ECMA_PROPERTY_TYPE_HASHMAP;
hashmap_p->header.next_property_cp = object_p->property_list_or_bound_object_cp;
hashmap_p->max_property_count = max_property_count;
hashmap_p->null_count = max_property_count - named_property_count;
jmem_cpointer_t *pair_list_p = (jmem_cpointer_t *) (hashmap_p + 1);
uint8_t *bits_p = (uint8_t *) (pair_list_p + max_property_count);
uint32_t mask = max_property_count - 1;
uint8_t shift_counter = 0;
if (max_property_count <= LIT_STRING_HASH_LIMIT)
{
hashmap_p->header.types[1] = 0;
}
else
{
while (max_property_count > LIT_STRING_HASH_LIMIT)
{
shift_counter++;
max_property_count >>= 1;
}
}
hashmap_p->header.types[1] = shift_counter;
prop_iter_p = ecma_get_property_list (object_p);
ECMA_SET_POINTER (object_p->property_list_or_bound_object_cp, hashmap_p);
while (prop_iter_p != NULL)
{
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
ecma_property_types_t type = ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[i]);
if (!(type == ECMA_PROPERTY_TYPE_NAMEDDATA || type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR))
{
continue;
}
ecma_property_pair_t *property_pair_p = (ecma_property_pair_t *) prop_iter_p;
ecma_string_t *name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_pair_p->names_cp[i]);
uint32_t entry_index = name_p->hash;
uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)];
if (mask < LIT_STRING_HASH_LIMIT)
{
entry_index &= mask;
}
else
{
entry_index <<= shift_counter;
JERRY_ASSERT (entry_index <= mask);
}
#ifndef JERRY_NDEBUG
/* Because max_property_count (power of 2) and step (a prime
* number) are relative primes, all entries of the hasmap are
* visited exactly once before the start entry index is reached
* again. Furthermore because at least one NULL is present in
* the hashmap, the while loop must be terminated before the
* the starting index is reached again. */
uint32_t start_entry_index = entry_index;
#endif /* !JERRY_NDEBUG */
while (pair_list_p[entry_index] != ECMA_NULL_POINTER)
{
entry_index = (entry_index + step) & mask;
#ifndef JERRY_NDEBUG
JERRY_ASSERT (entry_index != start_entry_index);
#endif /* !JERRY_NDEBUG */
}
ECMA_SET_POINTER (pair_list_p[entry_index], property_pair_p);
if (i != 0)
{
ECMA_PROPERTY_HASHMAP_SET_BIT (bits_p, entry_index);
}
}
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
prop_iter_p->next_property_cp);
}
#else /* CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
JERRY_UNUSED (object_p);
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
} /* ecma_property_hashmap_create */
/**
* Free the hashmap of the object.
* The object must have a property hashmap.
*/
void
ecma_property_hashmap_free (ecma_object_t *object_p) /**< object */
{
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
/* Property hash must be exists and must be the first property. */
ecma_property_header_t *property_p = ecma_get_property_list (object_p);
JERRY_ASSERT (property_p != NULL
&& ECMA_PROPERTY_GET_TYPE (property_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP);
ecma_property_hashmap_t *hashmap_p = (ecma_property_hashmap_t *) property_p;
object_p->property_list_or_bound_object_cp = property_p->next_property_cp;
jmem_heap_free_block (hashmap_p,
ECMA_PROPERTY_HASHMAP_GET_TOTAL_SIZE (hashmap_p->max_property_count));
#else /* CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
JERRY_UNUSED (object_p);
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
} /* ecma_property_hashmap_free */
/**
* Insert named property into the hashmap.
*/
void
ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
ecma_string_t *name_p, /**< name of the property */
ecma_property_pair_t *property_pair_p, /**< property pair */
int property_index) /**< property index in the pair (0 or 1) */
{
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
ecma_property_hashmap_t *hashmap_p = ECMA_GET_NON_NULL_POINTER (ecma_property_hashmap_t,
object_p->property_list_or_bound_object_cp);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (hashmap_p->header.types[0]) == ECMA_PROPERTY_TYPE_HASHMAP);
/* The NULLs are reduced below 1/8 of the hashmap. */
if (hashmap_p->null_count < (hashmap_p->max_property_count >> 3))
{
ecma_property_hashmap_free (object_p);
ecma_property_hashmap_create (object_p);
return;
}
JERRY_ASSERT (property_index < ECMA_PROPERTY_PAIR_ITEM_COUNT);
uint32_t entry_index = name_p->hash;
uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)];
uint32_t mask = hashmap_p->max_property_count - 1;
if (mask < LIT_STRING_HASH_LIMIT)
{
entry_index &= mask;
}
else
{
entry_index <<= hashmap_p->header.types[1];
}
#ifndef JERRY_NDEBUG
/* See the comment for this variable in ecma_property_hashmap_create. */
uint32_t start_entry_index = entry_index;
#endif /* !JERRY_NDEBUG */
jmem_cpointer_t *pair_list_p = (jmem_cpointer_t *) (hashmap_p + 1);
while (pair_list_p[entry_index] != ECMA_NULL_POINTER)
{
entry_index = (entry_index + step) & mask;
#ifndef JERRY_NDEBUG
JERRY_ASSERT (entry_index != start_entry_index);
#endif /* !JERRY_NDEBUG */
}
ECMA_SET_POINTER (pair_list_p[entry_index], property_pair_p);
uint8_t *bits_p = (uint8_t *) (pair_list_p + hashmap_p->max_property_count);
bits_p += (entry_index >> 3);
mask = (uint32_t) (1 << (entry_index & 0x7));
if (!(*bits_p & mask))
{
/* Deleted entries also has ECMA_NULL_POINTER
* value, but they are not NULL values. */
hashmap_p->null_count--;
JERRY_ASSERT (hashmap_p->null_count > 0);
}
if (property_index == 0)
{
*bits_p = (uint8_t) ((*bits_p) & ~mask);
}
else
{
*bits_p = (uint8_t) ((*bits_p) | mask);
}
#else /* CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
JERRY_UNUSED (object_p);
JERRY_UNUSED (name_p);
JERRY_UNUSED (property_pair_p);
JERRY_UNUSED (property_index);
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
} /* ecma_property_hashmap_insert */
/**
* Delete named property from the hashmap.
*/
void
ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
ecma_string_t *name_p, /**< name of the property */
ecma_property_t *property_p) /**< property */
{
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
ecma_property_hashmap_t *hashmap_p = ECMA_GET_NON_NULL_POINTER (ecma_property_hashmap_t,
object_p->property_list_or_bound_object_cp);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (hashmap_p->header.types[0]) == ECMA_PROPERTY_TYPE_HASHMAP);
uint32_t entry_index = name_p->hash;
uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)];
uint32_t mask = hashmap_p->max_property_count - 1;
jmem_cpointer_t *pair_list_p = (jmem_cpointer_t *) (hashmap_p + 1);
uint8_t *bits_p = (uint8_t *) (pair_list_p + hashmap_p->max_property_count);
if (mask < LIT_STRING_HASH_LIMIT)
{
entry_index &= mask;
}
else
{
entry_index <<= hashmap_p->header.types[1];
JERRY_ASSERT (entry_index <= mask);
}
#ifndef JERRY_NDEBUG
/* See the comment for this variable in ecma_property_hashmap_create. */
uint32_t start_entry_index = entry_index;
#endif /* !JERRY_NDEBUG */
while (true)
{
if (pair_list_p[entry_index] != ECMA_NULL_POINTER)
{
size_t offset = 0;
if (ECMA_PROPERTY_HASHMAP_GET_BIT (bits_p, entry_index))
{
offset = 1;
}
ecma_property_pair_t *property_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_property_pair_t,
pair_list_p[entry_index]);
if ((property_pair_p->header.types + offset) == property_p)
{
JERRY_ASSERT (ecma_compare_ecma_strings (ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_pair_p->names_cp[offset]),
name_p));
pair_list_p[entry_index] = ECMA_NULL_POINTER;
ECMA_PROPERTY_HASHMAP_SET_BIT (bits_p, entry_index);
return;
}
}
else
{
/* Must be a deleted entry. */
JERRY_ASSERT (ECMA_PROPERTY_HASHMAP_GET_BIT (bits_p, entry_index));
}
entry_index = (entry_index + step) & mask;
#ifndef JERRY_NDEBUG
JERRY_ASSERT (entry_index != start_entry_index);
#endif /* !JERRY_NDEBUG */
}
#else /* CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
JERRY_UNUSED (object_p);
JERRY_UNUSED (name_p);
JERRY_UNUSED (property_p);
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
} /* ecma_property_hashmap_delete */
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
/**
* Find a named property.
*
* @return pointer to the property if found or NULL otherwise
*/
ecma_property_t *
ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
ecma_string_t *name_p, /**< property name */
ecma_string_t **property_real_name_p) /**< [out] property real name */
{
#ifndef JERRY_NDEBUG
/* A sanity check in debug mode: a named property must be present
* in both the property hashmap and in the property chain, or missing
* from both data collection. The following code checks the property
* chain, and sets the property_found variable. */
bool property_found = false;
ecma_property_header_t *prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
hashmap_p->header.next_property_cp);
while (prop_iter_p != NULL && !property_found)
{
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
if (prop_pair_p->names_cp[i] != ECMA_NULL_POINTER)
{
ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
prop_pair_p->names_cp[i]);
if (ecma_compare_ecma_strings (name_p, property_name_p))
{
property_found = true;
break;
}
}
}
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
prop_iter_p->next_property_cp);
}
#endif /* !JERRY_NDEBUG */
uint32_t entry_index = name_p->hash;
uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)];
uint32_t mask = hashmap_p->max_property_count - 1;
jmem_cpointer_t *pair_list_p = (jmem_cpointer_t *) (hashmap_p + 1);
uint8_t *bits_p = (uint8_t *) (pair_list_p + hashmap_p->max_property_count);
if (mask < LIT_STRING_HASH_LIMIT)
{
entry_index &= mask;
}
else
{
entry_index <<= hashmap_p->header.types[1];
JERRY_ASSERT (entry_index <= mask);
}
#ifndef JERRY_NDEBUG
/* See the comment for this variable in ecma_property_hashmap_create. */
uint32_t start_entry_index = entry_index;
#endif /* !JERRY_NDEBUG */
while (true)
{
if (pair_list_p[entry_index] != ECMA_NULL_POINTER)
{
size_t offset = 0;
if (ECMA_PROPERTY_HASHMAP_GET_BIT (bits_p, entry_index))
{
offset = 1;
}
ecma_property_pair_t *property_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_property_pair_t,
pair_list_p[entry_index]);
ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_pair_p->names_cp[offset]);
if (ecma_compare_ecma_strings (name_p, property_name_p))
{
#ifndef JERRY_NDEBUG
JERRY_ASSERT (property_found);
#endif /* !JERRY_NDEBUG */
*property_real_name_p = property_name_p;
return property_pair_p->header.types + offset;
}
}
else
{
if (!ECMA_PROPERTY_HASHMAP_GET_BIT (bits_p, entry_index))
{
#ifndef JERRY_NDEBUG
JERRY_ASSERT (!property_found);
#endif /* !JERRY_NDEBUG */
return NULL;
}
/* Otherwise it is a deleted entry. */
}
entry_index = (entry_index + step) & mask;
#ifndef JERRY_NDEBUG
JERRY_ASSERT (entry_index != start_entry_index);
#endif /* !JERRY_NDEBUG */
}
} /* ecma_property_hashmap_find */
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
/**
* @}
* @}
*/

View file

@ -0,0 +1,70 @@
/* Copyright 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_PROPERTY_HASHMAP_H
#define ECMA_PROPERTY_HASHMAP_H
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmapropertyhashmap Property hashmap
* @{
*/
/**
* Recommended minimum number of items in a property cache.
*/
#define ECMA_PROPERTY_HASMAP_MINIMUM_SIZE 32
/**
* Property hash.
*/
typedef struct
{
ecma_property_header_t header; /**< header of the property */
uint32_t max_property_count; /**< maximum property count (power of 2) */
uint32_t null_count; /**< number of NULLs in the map */
/*
* The hash is followed by max_property_count ecma_cpointer_t
* compressed pointers and (max_property_count + 7) / 8 bytes
* which stores a flag for each compressed pointer.
*
* If the compressed pointer is equal to ECMA_NULL_POINTER
* - flag is cleared if the entry is NULL
* - flag is set if the entry is deleted
*
* If the compressed pointer is not equal to ECMA_NULL_POINTER
* - flag is cleared if the first entry of a property pair is referenced
* - flag is set if the second entry of a property pair is referenced
*/
} ecma_property_hashmap_t;
extern void ecma_property_hashmap_create (ecma_object_t *);
extern void ecma_property_hashmap_free (ecma_object_t *);
extern void ecma_property_hashmap_insert (ecma_object_t *, ecma_string_t *, ecma_property_pair_t *, int);
extern void ecma_property_hashmap_delete (ecma_object_t *, ecma_string_t *, ecma_property_t *);
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
extern ecma_property_t *ecma_property_hashmap_find (ecma_property_hashmap_t *, ecma_string_t *, ecma_string_t **);
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
/**
* @}
* @}
*/
#endif /* !ECMA_PROPERTY_HASHMAP_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,86 @@
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
* Copyright 2015 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.
*/
/*
* Array.prototype built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_ARRAY_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
// 15.4.4.1
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_ARRAY,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
/* Number properties:
* (property name, object pointer getter) */
// 15.4.4
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
0,
ECMA_PROPERTY_FLAG_WRITABLE)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_array_prototype_object_to_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_STRING_UL, ecma_builtin_array_prototype_object_to_locale_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_CONCAT, ecma_builtin_array_prototype_object_concat, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_JOIN, ecma_builtin_array_prototype_join, 1, 1)
ROUTINE (LIT_MAGIC_STRING_POP, ecma_builtin_array_prototype_object_pop, 0, 0)
ROUTINE (LIT_MAGIC_STRING_PUSH, ecma_builtin_array_prototype_object_push, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_REVERSE, ecma_builtin_array_prototype_object_reverse, 0, 0)
ROUTINE (LIT_MAGIC_STRING_SHIFT, ecma_builtin_array_prototype_object_shift, 0, 0)
ROUTINE (LIT_MAGIC_STRING_SLICE, ecma_builtin_array_prototype_object_slice, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SORT, ecma_builtin_array_prototype_object_sort, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SPLICE, ecma_builtin_array_prototype_object_splice, NON_FIXED, 2)
ROUTINE (LIT_MAGIC_STRING_UNSHIFT, ecma_builtin_array_prototype_object_unshift, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_INDEX_OF_UL, ecma_builtin_array_prototype_object_index_of, 2, 1)
ROUTINE (LIT_MAGIC_STRING_LAST_INDEX_OF_UL, ecma_builtin_array_prototype_object_last_index_of, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_EVERY, ecma_builtin_array_prototype_object_every, 2, 1)
ROUTINE (LIT_MAGIC_STRING_SOME, ecma_builtin_array_prototype_object_some, 2, 1)
ROUTINE (LIT_MAGIC_STRING_FOR_EACH_UL, ecma_builtin_array_prototype_object_for_each, 2, 1)
ROUTINE (LIT_MAGIC_STRING_MAP, ecma_builtin_array_prototype_object_map, 2, 1)
ROUTINE (LIT_MAGIC_STRING_FILTER, ecma_builtin_array_prototype_object_filter, 2, 1)
ROUTINE (LIT_MAGIC_STRING_REDUCE, ecma_builtin_array_prototype_object_reduce, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_REDUCE_RIGHT_UL, ecma_builtin_array_prototype_object_reduce_right, NON_FIXED, 1)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,110 @@
/* 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-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-array-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_ARRAY_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-array.inc.h"
#define BUILTIN_UNDERSCORED_ID array
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup array ECMA Array object built-in
* @{
*/
/**
* The Array object's 'isArray' routine
*
* See also:
* ECMA-262 v5, 15.4.3.2
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_array_object_is_array (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< first argument */
{
JERRY_UNUSED (this_arg);
ecma_simple_value_t is_array = ECMA_SIMPLE_VALUE_FALSE;
if (ecma_is_value_object (arg))
{
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_ARRAY_UL)
{
is_array = ECMA_SIMPLE_VALUE_TRUE;
}
}
return ecma_make_simple_value (is_array);
} /* ecma_builtin_array_object_is_array */
/**
* Handle calling [[Call]] of built-in Array object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_array_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
return ecma_builtin_array_dispatch_construct (arguments_list_p, arguments_list_len);
} /* ecma_builtin_array_dispatch_call */
/**
* Handle calling [[Construct]] of built-in Array object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_array_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
return ecma_op_create_array_object (arguments_list_p, arguments_list_len, true);
} /* ecma_builtin_array_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_ARRAY_BUILTIN */

View file

@ -0,0 +1,65 @@
/* 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.
*/
/*
* Array description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_ARRAY)
/* Object properties:
* (property name, object pointer getter) */
// 15.4.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_ARRAY_PROTOTYPE,
ECMA_PROPERTY_FIXED)
/* Number properties:
* (property name, object pointer getter) */
// 15.4.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_IS_ARRAY_UL, ecma_builtin_array_object_is_array, 1, 1)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,125 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_BOOLEAN_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-boolean-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID boolean_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup booleanprototype ECMA Boolean.prototype object built-in
* @{
*/
/**
* The Boolean.prototype object's 'toString' routine
*
* See also:
* ECMA-262 v5, 15.6.4.2
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_boolean_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_TRY_CATCH (value_of_ret,
ecma_builtin_boolean_prototype_object_value_of (this_arg),
ret_value);
ecma_string_t *ret_str_p;
if (ecma_is_value_true (value_of_ret))
{
ret_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_TRUE);
}
else
{
JERRY_ASSERT (ecma_is_value_boolean (value_of_ret));
ret_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_FALSE);
}
ret_value = ecma_make_string_value (ret_str_p);
ECMA_FINALIZE (value_of_ret);
return ret_value;
} /* ecma_builtin_boolean_prototype_object_to_string */
/**
* The Boolean.prototype object's 'valueOf' routine
*
* See also:
* ECMA-262 v5, 15.6.4.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_boolean_prototype_object_value_of (ecma_value_t this_arg) /**< this argument */
{
if (ecma_is_value_boolean (this_arg))
{
return this_arg;
}
else if (ecma_is_value_object (this_arg))
{
ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_BOOLEAN_UL)
{
ecma_value_t *prim_value_prop_p = ecma_get_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
JERRY_ASSERT (ecma_is_value_boolean (*prim_value_prop_p));
return *prim_value_prop_p;
}
}
return ecma_raise_type_error (ECMA_ERR_MSG (""));
} /* ecma_builtin_boolean_prototype_object_value_of */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_BOOLEAN_BUILTIN */

View file

@ -0,0 +1,53 @@
/* 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.
*/
/*
* Boolean.prototype description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_id)
#endif /* !OBJECT_ID */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
// 15.6.4.1
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_BOOLEAN,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_boolean_prototype_object_to_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_VALUE_OF_UL, ecma_builtin_boolean_prototype_object_value_of, 0, 0)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,100 @@
/* 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-alloc.h"
#include "ecma-boolean-object.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_BOOLEAN_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-boolean.inc.h"
#define BUILTIN_UNDERSCORED_ID boolean
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup boolean ECMA Boolean object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in Boolean object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_boolean_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
ecma_value_t arg_value;
if (arguments_list_len == 0)
{
arg_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
}
else
{
arg_value = arguments_list_p[0];
}
return ecma_make_simple_value (ecma_op_to_boolean (arg_value) ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE);
} /* ecma_builtin_boolean_dispatch_call */
/**
* Handle calling [[Construct]] of built-in Boolean object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_boolean_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
if (arguments_list_len == 0)
{
return ecma_op_create_boolean_object (ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE));
}
else
{
return ecma_op_create_boolean_object (arguments_list_p[0]);
}
} /* ecma_builtin_boolean_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_BOOLEAN_BUILTIN */

View file

@ -0,0 +1,60 @@
/* 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.
*/
/*
* Boolean description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_BOOLEAN)
/* Object properties:
* (property name, object pointer getter) */
// 15.6.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE,
ECMA_PROPERTY_FIXED)
/* Number properties:
* (property name, object pointer getter) */
// 15.6.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,97 @@
/* 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.
*/
/*
* Date.prototype built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_DATE_PROTOTYPE)
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_DATE,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_date_prototype_to_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_DATE_STRING_UL, ecma_builtin_date_prototype_to_date_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_TIME_STRING_UL, ecma_builtin_date_prototype_to_time_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_STRING_UL, ecma_builtin_date_prototype_to_locale_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_DATE_STRING_UL, ecma_builtin_date_prototype_to_locale_date_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_TIME_STRING_UL, ecma_builtin_date_prototype_to_locale_time_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_VALUE_OF_UL, ecma_builtin_date_prototype_value_of, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_TIME_UL, ecma_builtin_date_prototype_get_time, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_FULL_YEAR_UL, ecma_builtin_date_prototype_get_full_year, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_FULL_YEAR_UL, ecma_builtin_date_prototype_get_utc_full_year, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_MONTH_UL, ecma_builtin_date_prototype_get_month, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_MONTH_UL, ecma_builtin_date_prototype_get_utc_month, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_DATE_UL, ecma_builtin_date_prototype_get_date, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_DATE_UL, ecma_builtin_date_prototype_get_utc_date, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_DAY_UL, ecma_builtin_date_prototype_get_day, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_DAY_UL, ecma_builtin_date_prototype_get_utc_day, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_HOURS_UL, ecma_builtin_date_prototype_get_hours, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_HOURS_UL, ecma_builtin_date_prototype_get_utc_hours, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_MINUTES_UL, ecma_builtin_date_prototype_get_minutes, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_MINUTES_UL, ecma_builtin_date_prototype_get_utc_minutes, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_SECONDS_UL, ecma_builtin_date_prototype_get_seconds, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_SECONDS_UL, ecma_builtin_date_prototype_get_utc_seconds, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_MILLISECONDS_UL, ecma_builtin_date_prototype_get_milliseconds, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_MILLISECONDS_UL, ecma_builtin_date_prototype_get_utc_milliseconds, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_TIMEZONE_OFFSET_UL, ecma_builtin_date_prototype_get_timezone_offset, 0, 0)
ROUTINE (LIT_MAGIC_STRING_SET_TIME_UL, ecma_builtin_date_prototype_set_time, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_MILLISECONDS_UL, ecma_builtin_date_prototype_set_milliseconds, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_MILLISECONDS_UL, ecma_builtin_date_prototype_set_utc_milliseconds, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_SECONDS_UL, ecma_builtin_date_prototype_set_seconds, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_SECONDS_UL, ecma_builtin_date_prototype_set_utc_seconds, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SET_MINUTES_UL, ecma_builtin_date_prototype_set_minutes, NON_FIXED, 3)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_MINUTES_UL, ecma_builtin_date_prototype_set_utc_minutes, NON_FIXED, 3)
ROUTINE (LIT_MAGIC_STRING_SET_HOURS_UL, ecma_builtin_date_prototype_set_hours, NON_FIXED, 4)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_HOURS_UL, ecma_builtin_date_prototype_set_utc_hours, NON_FIXED, 4)
ROUTINE (LIT_MAGIC_STRING_SET_DATE_UL, ecma_builtin_date_prototype_set_date, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_DATE_UL, ecma_builtin_date_prototype_set_utc_date, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_MONTH_UL, ecma_builtin_date_prototype_set_month, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_MONTH_UL, ecma_builtin_date_prototype_set_utc_month, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SET_FULL_YEAR_UL, ecma_builtin_date_prototype_set_full_year, NON_FIXED, 3)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_FULL_YEAR_UL, ecma_builtin_date_prototype_set_utc_full_year, NON_FIXED, 3)
ROUTINE (LIT_MAGIC_STRING_TO_UTC_STRING_UL, ecma_builtin_date_prototype_to_utc_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_ISO_STRING_UL, ecma_builtin_date_prototype_to_iso_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_JSON_UL, ecma_builtin_date_prototype_to_json, 1, 1)
#ifndef CONFIG_DISABLE_ANNEXB_BUILTIN
ROUTINE (LIT_MAGIC_STRING_GET_YEAR_UL, ecma_builtin_date_prototype_get_year, 0, 0)
ROUTINE (LIT_MAGIC_STRING_SET_YEAR_UL, ecma_builtin_date_prototype_set_year, 1, 1)
ROUTINE (LIT_MAGIC_STRING_TO_GMT_STRING_UL, ecma_builtin_date_prototype_to_utc_string, 0, 0)
#endif /* !CONFIG_DISABLE_ANNEXB_BUILTIN */
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,577 @@
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-alloc.h"
#include "ecma-builtin-helpers.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-try-catch-macro.h"
#include "lit-char-helpers.h"
#ifndef CONFIG_DISABLE_DATE_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-date.inc.h"
#define BUILTIN_UNDERSCORED_ID date
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup date ECMA Date object built-in
* @{
*/
/**
* Helper function to try to parse a part of a date string
*
* @return NaN if cannot read from string, ToNumber() otherwise
*/
static ecma_number_t
ecma_date_parse_date_chars (const lit_utf8_byte_t **str_p, /**< pointer to the cesu8 string */
const lit_utf8_byte_t *str_end_p, /**< pointer to the end of the string */
uint32_t num_of_chars) /**< number of characters to read and convert */
{
JERRY_ASSERT (num_of_chars > 0);
const lit_utf8_byte_t *str_start_p = *str_p;
while (num_of_chars--)
{
if (*str_p >= str_end_p || !lit_char_is_decimal_digit (lit_utf8_read_next (str_p)))
{
return ecma_number_make_nan ();
}
}
return ecma_utf8_string_to_number (str_start_p, (lit_utf8_size_t) (*str_p - str_start_p));
} /* ecma_date_parse_date_chars */
/**
* Calculate MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)) for Date constructor and UTC
*
* See also:
* ECMA-262 v5, 15.9.3.1
* ECMA-262 v5, 15.9.4.3
*
* @return result of MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli))
*/
static ecma_value_t
ecma_date_construct_helper (const ecma_value_t *args, /**< arguments passed to the Date constructor */
ecma_length_t args_len) /**< number of arguments */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_number_t prim_value = ecma_number_make_nan ();
ECMA_TRY_CATCH (year_value, ecma_op_to_number (args[0]), ret_value);
ECMA_TRY_CATCH (month_value, ecma_op_to_number (args[1]), ret_value);
ecma_number_t year = ecma_get_number_from_value (year_value);
ecma_number_t month = ecma_get_number_from_value (month_value);
ecma_number_t date = ECMA_NUMBER_ONE;
ecma_number_t hours = ECMA_NUMBER_ZERO;
ecma_number_t minutes = ECMA_NUMBER_ZERO;
ecma_number_t seconds = ECMA_NUMBER_ZERO;
ecma_number_t milliseconds = ECMA_NUMBER_ZERO;
/* 3. */
if (args_len >= 3 && ecma_is_value_empty (ret_value))
{
ECMA_TRY_CATCH (date_value, ecma_op_to_number (args[2]), ret_value);
date = ecma_get_number_from_value (date_value);
ECMA_FINALIZE (date_value);
}
/* 4. */
if (args_len >= 4 && ecma_is_value_empty (ret_value))
{
ECMA_TRY_CATCH (hours_value, ecma_op_to_number (args[3]), ret_value);
hours = ecma_get_number_from_value (hours_value);
ECMA_FINALIZE (hours_value);
}
/* 5. */
if (args_len >= 5 && ecma_is_value_empty (ret_value))
{
ECMA_TRY_CATCH (minutes_value, ecma_op_to_number (args[4]), ret_value);
minutes = ecma_get_number_from_value (minutes_value);
ECMA_FINALIZE (minutes_value);
}
/* 6. */
if (args_len >= 6 && ecma_is_value_empty (ret_value))
{
ECMA_TRY_CATCH (seconds_value, ecma_op_to_number (args[5]), ret_value);
seconds = ecma_get_number_from_value (seconds_value);
ECMA_FINALIZE (seconds_value);
}
/* 7. */
if (args_len >= 7 && ecma_is_value_empty (ret_value))
{
ECMA_TRY_CATCH (milliseconds_value, ecma_op_to_number (args[6]), ret_value);
milliseconds = ecma_get_number_from_value (milliseconds_value);
ECMA_FINALIZE (milliseconds_value);
}
if (ecma_is_value_empty (ret_value))
{
if (!ecma_number_is_nan (year))
{
/* 8. */
ecma_number_t y = ecma_number_trunc (year);
if (y >= 0 && y <= 99)
{
year = 1900 + y;
}
}
prim_value = ecma_date_make_date (ecma_date_make_day (year,
month,
date),
ecma_date_make_time (hours,
minutes,
seconds,
milliseconds));
}
ECMA_FINALIZE (month_value);
ECMA_FINALIZE (year_value);
if (ecma_is_value_empty (ret_value))
{
ret_value = ecma_make_number_value (prim_value);
}
return ret_value;
} /* ecma_date_construct_helper */
/**
* The Date object's 'parse' routine
*
* See also:
* ECMA-262 v5, 15.9.4.2
* ECMA-262 v5, 15.9.1.15
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg) /**< string */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_number_t date_num = ecma_number_make_nan ();
/* Date Time String fromat (ECMA-262 v5, 15.9.1.15) */
ECMA_TRY_CATCH (date_str_value,
ecma_op_to_string (arg),
ret_value);
ecma_string_t *date_str_p = ecma_get_string_from_value (date_str_value);
ECMA_STRING_TO_UTF8_STRING (date_str_p, date_start_p, date_start_size);
const lit_utf8_byte_t *date_str_curr_p = date_start_p;
const lit_utf8_byte_t *date_str_end_p = date_start_p + date_start_size;
/* 1. read year */
ecma_number_t year = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 4);
if (!ecma_number_is_nan (year)
&& year >= 0)
{
ecma_number_t month = ECMA_NUMBER_ONE;
ecma_number_t day = ECMA_NUMBER_ONE;
ecma_number_t time = ECMA_NUMBER_ZERO;
/* 2. read month if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == '-')
{
/* eat up '-' */
date_str_curr_p++;
month = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
if (month > 12 || month < 1)
{
month = ecma_number_make_nan ();
}
}
/* 3. read day if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == '-')
{
/* eat up '-' */
date_str_curr_p++;
day = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
if (day < 1 || day > 31)
{
day = ecma_number_make_nan ();
}
}
/* 4. read time if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == 'T')
{
/* eat up 'T' */
date_str_curr_p++;
ecma_number_t hours = ECMA_NUMBER_ZERO;
ecma_number_t minutes = ECMA_NUMBER_ZERO;
ecma_number_t seconds = ECMA_NUMBER_ZERO;
ecma_number_t milliseconds = ECMA_NUMBER_ZERO;
ecma_length_t remaining_length = lit_utf8_string_length (date_str_curr_p,
(lit_utf8_size_t) (date_str_end_p - date_str_curr_p));
if (remaining_length >= 5)
{
/* 4.1 read hours and minutes */
hours = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
if (hours < 0 || hours > 24)
{
hours = ecma_number_make_nan ();
}
else if (hours == 24)
{
hours = ECMA_NUMBER_ZERO;
}
/* eat up ':' */
date_str_curr_p++;
minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
if (minutes < 0 || minutes > 59)
{
minutes = ecma_number_make_nan ();
}
/* 4.2 read seconds if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == ':')
{
/* eat up ':' */
date_str_curr_p++;
seconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
if (seconds < 0 || seconds > 59)
{
seconds = ecma_number_make_nan ();
}
/* 4.3 read milliseconds if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == '.')
{
/* eat up '.' */
date_str_curr_p++;
milliseconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 3);
if (milliseconds < 0)
{
milliseconds = ecma_number_make_nan ();
}
}
}
time = ecma_date_make_time (hours, minutes, seconds, milliseconds);
}
else
{
time = ecma_number_make_nan ();
}
/* 4.4 read timezone if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == 'Z'
&& !ecma_number_is_nan (time))
{
date_str_curr_p++;
time = ecma_date_make_time (hours, minutes, seconds, milliseconds);
}
else if (date_str_curr_p < date_str_end_p
&& (*date_str_curr_p == '+' || *date_str_curr_p == '-'))
{
ecma_length_t remaining_length;
remaining_length = lit_utf8_string_length (date_str_curr_p,
(lit_utf8_size_t) (date_str_end_p - date_str_curr_p)) - 1;
if (remaining_length == 5)
{
bool is_negative = false;
if (*date_str_curr_p == '-')
{
is_negative = true;
}
/* eat up '+/-' */
date_str_curr_p++;
/* read hours and minutes */
hours = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
if (hours < 0 || hours > 24)
{
hours = ecma_number_make_nan ();
}
else if (hours == 24)
{
hours = ECMA_NUMBER_ZERO;
}
/* eat up ':' */
date_str_curr_p++;
minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
if (minutes < 0 || minutes > 59)
{
minutes = ecma_number_make_nan ();
}
if (is_negative)
{
time += ecma_date_make_time (hours, minutes, ECMA_NUMBER_ZERO, ECMA_NUMBER_ZERO);
}
else
{
time -= ecma_date_make_time (hours, minutes, ECMA_NUMBER_ZERO, ECMA_NUMBER_ZERO);
}
}
}
}
if (date_str_curr_p >= date_str_end_p)
{
ecma_number_t date = ecma_date_make_day (year, month - 1, day);
date_num = ecma_date_make_date (date, time);
}
}
ret_value = ecma_make_number_value (date_num);
ECMA_FINALIZE_UTF8_STRING (date_start_p, date_start_size);
ECMA_FINALIZE (date_str_value);
return ret_value;
} /* ecma_builtin_date_parse */
/**
* The Date object's 'UTC' routine
*
* See also:
* ECMA-262 v5, 15.9.4.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_date_utc (ecma_value_t this_arg, /**< this argument */
const ecma_value_t args[], /**< arguments list */
ecma_length_t args_number) /**< number of arguments */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (args_number < 2)
{
/* Note:
* When the UTC function is called with fewer than two arguments,
* the behaviour is implementation-dependent, so just return NaN.
*/
return ecma_make_number_value (ecma_number_make_nan ());
}
ECMA_TRY_CATCH (time_value, ecma_date_construct_helper (args, args_number), ret_value);
ecma_number_t time = ecma_get_number_from_value (time_value);
ret_value = ecma_make_number_value (ecma_date_time_clip (time));
ECMA_FINALIZE (time_value);
return ret_value;
} /* ecma_builtin_date_utc */
/**
* The Date object's 'now' routine
*
* See also:
* ECMA-262 v5, 15.9.4.4
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_date_now (ecma_value_t this_arg) /**< this argument */
{
JERRY_UNUSED (this_arg);
return ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (jerry_port_get_current_time ()));
} /* ecma_builtin_date_now */
/**
* Handle calling [[Call]] of built-in Date object
*
* See also:
* ECMA-262 v5, 15.9.2.1
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_date_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_UNUSED (arguments_list_p);
JERRY_UNUSED (arguments_list_len);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_TRY_CATCH (now_val,
ecma_builtin_date_now (ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED)),
ret_value);
ret_value = ecma_date_value_to_string (ecma_get_number_from_value (now_val));
ECMA_FINALIZE (now_val);
return ret_value;
} /* ecma_builtin_date_dispatch_call */
/**
* Handle calling [[Construct]] of built-in Date object
*
* See also:
* ECMA-262 v5, 15.9.3.1
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_number_t prim_value_num = ECMA_NUMBER_ZERO;
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_DATE_PROTOTYPE);
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p,
false,
true,
ECMA_OBJECT_TYPE_GENERAL);
ecma_deref_object (prototype_obj_p);
if (arguments_list_len == 0)
{
ECMA_TRY_CATCH (parse_res_value,
ecma_builtin_date_now (ecma_make_object_value (obj_p)),
ret_value);
prim_value_num = ecma_get_number_from_value (parse_res_value);
ECMA_FINALIZE (parse_res_value)
}
else if (arguments_list_len == 1)
{
ECMA_TRY_CATCH (prim_comp_value,
ecma_op_to_primitive (arguments_list_p[0], ECMA_PREFERRED_TYPE_NUMBER),
ret_value);
if (ecma_is_value_string (prim_comp_value))
{
ECMA_TRY_CATCH (parse_res_value,
ecma_builtin_date_parse (ecma_make_object_value (obj_p), prim_comp_value),
ret_value);
prim_value_num = ecma_get_number_from_value (parse_res_value);
ECMA_FINALIZE (parse_res_value);
}
else
{
ECMA_TRY_CATCH (prim_value, ecma_op_to_number (arguments_list_p[0]), ret_value);
prim_value_num = ecma_date_time_clip (ecma_get_number_from_value (prim_value));
ECMA_FINALIZE (prim_value);
}
ECMA_FINALIZE (prim_comp_value);
}
else if (arguments_list_len >= 2)
{
ECMA_TRY_CATCH (time_value,
ecma_date_construct_helper (arguments_list_p, arguments_list_len),
ret_value);
ecma_number_t time = ecma_get_number_from_value (time_value);
prim_value_num = ecma_date_time_clip (ecma_date_utc (time));
ECMA_FINALIZE (time_value);
}
else
{
prim_value_num = ecma_number_make_nan ();
}
if (ecma_is_value_empty (ret_value))
{
if (!ecma_number_is_nan (prim_value_num) && ecma_number_is_infinity (prim_value_num))
{
prim_value_num = ecma_number_make_nan ();
}
ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_CLASS);
*class_prop_p = LIT_MAGIC_STRING_DATE_UL;
ecma_value_t *date_prop_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_DATE_FLOAT);
ecma_number_t *date_num_p = ecma_alloc_number ();
*date_num_p = prim_value_num;
ECMA_SET_INTERNAL_VALUE_POINTER (*date_prop_p, date_num_p);
ret_value = ecma_make_object_value (obj_p);
}
else
{
JERRY_ASSERT (ECMA_IS_VALUE_ERROR (ret_value));
ecma_deref_object (obj_p);
}
return ret_value;
} /* ecma_builtin_date_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_DATE_BUILTIN */

View file

@ -0,0 +1,58 @@
/* Copyright 2015 Samsung Electronics Co., Ltd.
* Copyright 2015 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.
*/
/*
* Date built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_DATE)
// ECMA-262 v5, 15.9.4.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_DATE_PROTOTYPE,
ECMA_PROPERTY_FIXED)
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
7,
ECMA_PROPERTY_FIXED)
ROUTINE (LIT_MAGIC_STRING_PARSE, ecma_builtin_date_parse, 1, 1)
ROUTINE (LIT_MAGIC_STRING_UTC_U, ecma_builtin_date_utc, NON_FIXED, 7)
ROUTINE (LIT_MAGIC_STRING_NOW, ecma_builtin_date_now, 0, 0)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,195 @@
/* 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-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#include "lit-magic-strings.h"
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-error-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID error_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup errorprototype ECMA Error.prototype object built-in
* @{
*/
/**
* The Error.prototype object's 'toString' routine
*
* See also:
* ECMA-262 v5, 15.11.4.4
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_error_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
// 2.
if (!ecma_is_value_object (this_arg))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
ecma_string_t *name_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_NAME);
ECMA_TRY_CATCH (name_get_ret_value,
ecma_op_object_get (obj_p, name_magic_string_p),
ret_value);
ecma_value_t name_to_str_completion;
if (ecma_is_value_undefined (name_get_ret_value))
{
ecma_string_t *error_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ERROR_UL);
name_to_str_completion = ecma_make_string_value (error_magic_string_p);
}
else
{
name_to_str_completion = ecma_op_to_string (name_get_ret_value);
}
if (unlikely (ECMA_IS_VALUE_ERROR (name_to_str_completion)))
{
ret_value = ecma_copy_value (name_to_str_completion);
}
else
{
ecma_string_t *message_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MESSAGE);
ECMA_TRY_CATCH (msg_get_ret_value,
ecma_op_object_get (obj_p, message_magic_string_p),
ret_value);
ecma_value_t msg_to_str_completion;
if (ecma_is_value_undefined (msg_get_ret_value))
{
ecma_string_t *empty_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
msg_to_str_completion = ecma_make_string_value (empty_magic_string_p);
}
else
{
msg_to_str_completion = ecma_op_to_string (msg_get_ret_value);
}
if (unlikely (ECMA_IS_VALUE_ERROR (msg_to_str_completion)))
{
ret_value = ecma_copy_value (msg_to_str_completion);
}
else
{
ecma_string_t *name_string_p = ecma_get_string_from_value (name_to_str_completion);
ecma_string_t *msg_string_p = ecma_get_string_from_value (msg_to_str_completion);
ecma_string_t *ret_str_p;
if (ecma_string_is_empty (name_string_p))
{
ret_str_p = msg_string_p;
ecma_ref_ecma_string (ret_str_p);
}
else if (ecma_string_is_empty (msg_string_p))
{
ret_str_p = name_string_p;
ecma_ref_ecma_string (ret_str_p);
}
else
{
const lit_utf8_size_t name_size = ecma_string_get_size (name_string_p);
const lit_utf8_size_t msg_size = ecma_string_get_size (msg_string_p);
const lit_utf8_size_t colon_size = lit_get_magic_string_size (LIT_MAGIC_STRING_COLON_CHAR);
const lit_utf8_size_t space_size = lit_get_magic_string_size (LIT_MAGIC_STRING_SPACE_CHAR);
const lit_utf8_size_t size = name_size + msg_size + colon_size + space_size;
JMEM_DEFINE_LOCAL_ARRAY (ret_str_buffer, size, lit_utf8_byte_t);
lit_utf8_byte_t *ret_str_buffer_p = ret_str_buffer;
lit_utf8_size_t bytes = ecma_string_copy_to_utf8_buffer (name_string_p, ret_str_buffer_p, name_size);
JERRY_ASSERT (bytes == name_size);
ret_str_buffer_p = ret_str_buffer_p + bytes;
JERRY_ASSERT (ret_str_buffer_p <= ret_str_buffer + size);
ret_str_buffer_p = lit_copy_magic_string_to_buffer (LIT_MAGIC_STRING_COLON_CHAR,
ret_str_buffer_p,
colon_size);
JERRY_ASSERT (ret_str_buffer_p <= ret_str_buffer + size);
ret_str_buffer_p = lit_copy_magic_string_to_buffer (LIT_MAGIC_STRING_SPACE_CHAR,
ret_str_buffer_p,
space_size);
JERRY_ASSERT (ret_str_buffer_p <= ret_str_buffer + size);
bytes = ecma_string_copy_to_utf8_buffer (msg_string_p, ret_str_buffer_p, msg_size);
JERRY_ASSERT (bytes == msg_size);
ret_str_buffer_p = ret_str_buffer_p + bytes;
JERRY_ASSERT (ret_str_buffer_p == ret_str_buffer + size);
ret_str_p = ecma_new_ecma_string_from_utf8 (ret_str_buffer,
size);
JMEM_FINALIZE_LOCAL_ARRAY (ret_str_buffer);
}
ret_value = ecma_make_string_value (ret_str_p);
}
ecma_free_value (msg_to_str_completion);
ECMA_FINALIZE (msg_get_ret_value);
ecma_deref_ecma_string (message_magic_string_p);
}
ecma_free_value (name_to_str_completion);
ECMA_FINALIZE (name_get_ret_value);
ecma_deref_ecma_string (name_magic_string_p);
}
return ret_value;
} /* ecma_builtin_error_prototype_object_to_string */
/**
* @}
* @}
* @}
*/

View file

@ -0,0 +1,66 @@
/* 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.
*/
/*
* Error.prototype built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_ERROR_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
// 15.11.4.1
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// 15.11.4.2
STRING_VALUE (LIT_MAGIC_STRING_NAME,
LIT_MAGIC_STRING_ERROR_UL,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// 15.11.4.3
STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
LIT_MAGIC_STRING__EMPTY,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_error_prototype_object_to_string, 0, 0)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,73 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-builtin-helpers.h"
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-error.inc.h"
#define BUILTIN_UNDERSCORED_ID error
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup error ECMA Error object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in Error object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_error_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_helper_error_dispatch_call (ECMA_ERROR_COMMON, arguments_list_p, arguments_list_len);
} /* ecma_builtin_error_dispatch_call */
/**
* Handle calling [[Construct]] of built-in Error object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_error_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_error_dispatch_call (arguments_list_p, arguments_list_len);
} /* ecma_builtin_error_dispatch_construct */
/**
* @}
* @}
* @}
*/

View file

@ -0,0 +1,60 @@
/* 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.
*/
/*
* Error built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_ERROR)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
// 15.11.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
/* Object properties:
* (property name, object pointer getter) */
// 15.7.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_ERROR_PROTOTYPE,
ECMA_PROPERTY_FIXED)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,37 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-evalerror-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID eval_error_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */

View file

@ -0,0 +1,58 @@
/* 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.
*/
/*
* EvalError.prototype built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_EVAL_ERROR_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
// 15.11.7.8
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_EVAL_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// 15.11.7.9
STRING_VALUE (LIT_MAGIC_STRING_NAME,
LIT_MAGIC_STRING_EVAL_ERROR_UL,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// 15.11.7.10
STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
LIT_MAGIC_STRING__EMPTY,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,77 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-builtin-helpers.h"
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-evalerror.inc.h"
#define BUILTIN_UNDERSCORED_ID eval_error
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup evalerror ECMA EvalError object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in EvalError object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_eval_error_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_helper_error_dispatch_call (ECMA_ERROR_EVAL, arguments_list_p, arguments_list_len);
} /* ecma_builtin_eval_error_dispatch_call */
/**
* Handle calling [[Construct]] of built-in EvalError object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_eval_error_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_eval_error_dispatch_call (arguments_list_p, arguments_list_len);
} /* ecma_builtin_eval_error_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */

View file

@ -0,0 +1,60 @@
/* 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.
*/
/*
* EvalError built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_EVAL_ERROR)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
// 15.11.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
/* Object properties:
* (property name, object pointer getter) */
// 15.11.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_EVAL_ERROR_PROTOTYPE,
ECMA_PROPERTY_FIXED)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,400 @@
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-alloc.h"
#include "ecma-builtin-helpers.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-function-object.h"
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-function-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID function_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup functionprototype ECMA Function.prototype object built-in
* @{
*/
/**
* The Function.prototype object's 'toString' routine
*
* See also:
* ECMA-262 v5, 15.3.4.2
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_function_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (!ecma_op_is_callable (this_arg))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_string_t *function_to_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__FUNCTION_TO_STRING);
ret_value = ecma_make_string_value (function_to_string_p);
}
return ret_value;
} /* ecma_builtin_function_prototype_object_to_string */
/**
* The Function.prototype object's 'apply' routine
*
* See also:
* ECMA-262 v5, 15.3.4.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_function_prototype_object_apply (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg1, /**< first argument */
ecma_value_t arg2) /**< second argument */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
/* 1. */
if (!ecma_op_is_callable (this_arg))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_object_t *func_obj_p = ecma_get_object_from_value (this_arg);
/* 2. */
if (ecma_is_value_null (arg2) || ecma_is_value_undefined (arg2))
{
ret_value = ecma_op_function_call (func_obj_p, arg1, NULL, 0);
}
else
{
/* 3. */
if (!ecma_is_value_object (arg2))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_object_t *obj_p = ecma_get_object_from_value (arg2);
ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string ();
/* 4. */
ECMA_TRY_CATCH (length_value,
ecma_op_object_get (obj_p, length_magic_string_p),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (length_number,
length_value,
ret_value);
/* 5. */
const uint32_t length = ecma_number_to_uint32 (length_number);
/* 6. */
JMEM_DEFINE_LOCAL_ARRAY (arguments_list_p, length, ecma_value_t);
uint32_t last_index = 0;
/* 7. */
for (uint32_t index = 0;
index < length && ecma_is_value_empty (ret_value);
index++)
{
ecma_string_t *curr_idx_str_p = ecma_new_ecma_string_from_uint32 (index);
ECMA_TRY_CATCH (get_value,
ecma_op_object_get (obj_p, curr_idx_str_p),
ret_value);
arguments_list_p[index] = ecma_copy_value (get_value);
last_index = index + 1;
ECMA_FINALIZE (get_value);
ecma_deref_ecma_string (curr_idx_str_p);
}
if (ecma_is_value_empty (ret_value))
{
JERRY_ASSERT (last_index == length);
ret_value = ecma_op_function_call (func_obj_p,
arg1,
arguments_list_p,
length);
}
for (uint32_t index = 0; index < last_index; index++)
{
ecma_free_value (arguments_list_p[index]);
}
JMEM_FINALIZE_LOCAL_ARRAY (arguments_list_p);
ECMA_OP_TO_NUMBER_FINALIZE (length_number);
ECMA_FINALIZE (length_value);
ecma_deref_ecma_string (length_magic_string_p);
}
}
}
return ret_value;
} /* ecma_builtin_function_prototype_object_apply */
/**
* The Function.prototype object's 'call' routine
*
* See also:
* ECMA-262 v5, 15.3.4.4
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_function_prototype_object_call (ecma_value_t this_arg, /**< this argument */
const ecma_value_t *arguments_list_p, /**< list of arguments */
ecma_length_t arguments_number) /**< number of arguments */
{
if (!ecma_op_is_callable (this_arg))
{
return ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_object_t *func_obj_p = ecma_get_object_from_value (this_arg);
if (arguments_number == 0)
{
/* Even a 'this' argument is missing. */
return ecma_op_function_call (func_obj_p,
ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
NULL,
0);
}
else
{
return ecma_op_function_call (func_obj_p,
arguments_list_p[0],
arguments_list_p + 1,
(ecma_length_t) (arguments_number - 1u));
}
}
} /* ecma_builtin_function_prototype_object_call */
/**
* The Function.prototype object's 'bind' routine
*
* See also:
* ECMA-262 v5, 15.3.4.5
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_function_prototype_object_bind (ecma_value_t this_arg, /**< this argument */
const ecma_value_t *arguments_list_p, /**< list of arguments */
ecma_length_t arguments_number) /**< number of arguments */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
/* 2. */
if (!ecma_op_is_callable (this_arg))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
/* 4. 11. 18. */
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
ecma_object_t *function_p = ecma_create_object (prototype_obj_p,
false,
true,
ECMA_OBJECT_TYPE_BOUND_FUNCTION);
ecma_deref_object (prototype_obj_p);
/* 7. */
ecma_value_t *target_function_prop_p;
target_function_prop_p = ecma_create_internal_property (function_p,
ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION);
ecma_object_t *this_arg_obj_p = ecma_get_object_from_value (this_arg);
ECMA_SET_INTERNAL_VALUE_POINTER (*target_function_prop_p, this_arg_obj_p);
/* 8. */
ecma_value_t *bound_this_prop_p;
bound_this_prop_p = ecma_create_internal_property (function_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_THIS);
const ecma_length_t arg_count = arguments_number;
if (arg_count > 0)
{
*bound_this_prop_p = ecma_copy_value_if_not_object (arguments_list_p[0]);
}
else
{
*bound_this_prop_p = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
}
if (arg_count > 1)
{
ecma_collection_header_t *bound_args_collection_p;
bound_args_collection_p = ecma_new_values_collection (&arguments_list_p[1], arg_count - 1, false);
ecma_value_t *bound_args_prop_p;
bound_args_prop_p = ecma_create_internal_property (function_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS);
ECMA_SET_INTERNAL_VALUE_POINTER (*bound_args_prop_p, bound_args_collection_p);
}
/*
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_FUNCTION type.
*
* See also: ecma_object_get_class_name
*/
/* 16. */
ecma_number_t length = ECMA_NUMBER_ZERO;
ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string ();
/* 15. */
if (ecma_object_get_class_name (this_arg_obj_p) == LIT_MAGIC_STRING_FUNCTION_UL)
{
ecma_value_t get_len_value = ecma_op_object_get (this_arg_obj_p, magic_string_length_p);
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (get_len_value));
JERRY_ASSERT (ecma_is_value_number (get_len_value));
const ecma_length_t bound_arg_count = arg_count > 1 ? arg_count - 1 : 0;
/* 15.a */
length = ecma_get_number_from_value (get_len_value) - ((ecma_number_t) bound_arg_count);
ecma_free_value (get_len_value);
/* 15.b */
if (ecma_number_is_negative (length))
{
length = ECMA_NUMBER_ZERO;
}
}
/* 17. */
ecma_value_t completion = ecma_builtin_helper_def_prop (function_p,
magic_string_length_p,
ecma_make_number_value (length),
false, /* Writable */
false, /* Enumerable */
false, /* Configurable */
false); /* Failure handling */
JERRY_ASSERT (ecma_is_value_boolean (completion));
ecma_deref_ecma_string (magic_string_length_p);
/* 19-21. */
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);
completion = ecma_op_object_define_own_property (function_p,
magic_string_caller_p,
&prop_desc,
false);
JERRY_ASSERT (ecma_is_value_boolean (completion));
ecma_deref_ecma_string (magic_string_caller_p);
ecma_string_t *magic_string_arguments_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS);
completion = ecma_op_object_define_own_property (function_p,
magic_string_arguments_p,
&prop_desc,
false);
JERRY_ASSERT (ecma_is_value_boolean (completion));
ecma_deref_ecma_string (magic_string_arguments_p);
ecma_deref_object (thrower_p);
/* 22. */
ret_value = ecma_make_object_value (function_p);
}
return ret_value;
} /* ecma_builtin_function_prototype_object_bind */
/**
* Handle calling [[Call]] of built-in Function.prototype object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_function_prototype_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
} /* ecma_builtin_function_prototype_dispatch_call */
/**
* Handle calling [[Construct]] of built-in Function.prototype object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_function_prototype_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
return ecma_raise_type_error (ECMA_ERR_MSG (""));
} /* ecma_builtin_function_prototype_dispatch_construct */
/**
* @}
* @}
* @}
*/

View file

@ -0,0 +1,67 @@
/* 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.
*/
/*
* Function.prototype built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
// 15.3.4.1
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_FUNCTION,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
/* Number properties:
* (property name, object pointer getter) */
// 15.3.4
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
0,
ECMA_PROPERTY_FIXED)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_function_prototype_object_to_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_APPLY, ecma_builtin_function_prototype_object_apply, 2, 2)
ROUTINE (LIT_MAGIC_STRING_CALL, ecma_builtin_function_prototype_object_call, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_BIND, ecma_builtin_function_prototype_object_bind, NON_FIXED, 1)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,213 @@
/* 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-alloc.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-eval.h"
#include "ecma-gc.h"
#include "ecma-function-object.h"
#include "ecma-lex-env.h"
#include "ecma-try-catch-macro.h"
#include "lit-magic-strings.h"
#include "js-parser.h"
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-function.inc.h"
#define BUILTIN_UNDERSCORED_ID function
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup function ECMA Function object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in Function object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_function_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
return ecma_builtin_function_dispatch_construct (arguments_list_p, arguments_list_len);
} /* ecma_builtin_function_dispatch_call */
/**
* Helper method to count and convert the arguments for the Function constructor call.
*
* Performs the operation described in ECMA 262 v5.1 15.3.2.1 steps 5.a-d
*
*
* @return ecma value - concatenated arguments as a string.
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_function_helper_get_function_expression (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_string_t *left_parenthesis_str_p, *right_parenthesis_str_p;
ecma_string_t *left_brace_str_p, *right_brace_str_p;
ecma_string_t *comma_str_p;
ecma_string_t *function_kw_str_p, *empty_str_p;
ecma_string_t *expr_str_p, *concated_str_p;
left_parenthesis_str_p = ecma_new_ecma_string_from_magic_string_id (LIT_MAGIC_STRING_LEFT_PARENTHESIS_CHAR);
right_parenthesis_str_p = ecma_new_ecma_string_from_magic_string_id (LIT_MAGIC_STRING_RIGHT_PARENTHESIS_CHAR);
left_brace_str_p = ecma_new_ecma_string_from_magic_string_id (LIT_MAGIC_STRING_LEFT_BRACE_CHAR);
right_brace_str_p = ecma_new_ecma_string_from_magic_string_id (LIT_MAGIC_STRING_RIGHT_BRACE_CHAR);
comma_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_COMMA_CHAR);
function_kw_str_p = ecma_new_ecma_string_from_magic_string_id (LIT_MAGIC_STRING_FUNCTION);
empty_str_p = ecma_new_ecma_string_from_magic_string_id (LIT_MAGIC_STRING__EMPTY);
/* First, we only process the function arguments skipping the function body */
ecma_length_t number_of_function_args = (arguments_list_len == 0 ? 0 : arguments_list_len - 1);
expr_str_p = ecma_concat_ecma_strings (left_parenthesis_str_p, function_kw_str_p);
concated_str_p = ecma_concat_ecma_strings (expr_str_p, left_parenthesis_str_p);
ecma_deref_ecma_string (expr_str_p);
expr_str_p = concated_str_p;
for (ecma_length_t idx = 0;
idx < number_of_function_args && ecma_is_value_empty (ret_value);
idx++)
{
ECMA_TRY_CATCH (str_arg_value,
ecma_op_to_string (arguments_list_p[idx]),
ret_value);
ecma_string_t *str_p = ecma_get_string_from_value (str_arg_value);
concated_str_p = ecma_concat_ecma_strings (expr_str_p, str_p);
ecma_deref_ecma_string (expr_str_p);
expr_str_p = concated_str_p;
if (idx < number_of_function_args - 1)
{
concated_str_p = ecma_concat_ecma_strings (expr_str_p, comma_str_p);
ecma_deref_ecma_string (expr_str_p);
expr_str_p = concated_str_p;
}
ECMA_FINALIZE (str_arg_value);
}
if (ecma_is_value_empty (ret_value))
{
concated_str_p = ecma_concat_ecma_strings (expr_str_p, right_parenthesis_str_p);
ecma_deref_ecma_string (expr_str_p);
expr_str_p = concated_str_p;
concated_str_p = ecma_concat_ecma_strings (expr_str_p, left_brace_str_p);
ecma_deref_ecma_string (expr_str_p);
expr_str_p = concated_str_p;
if (arguments_list_len != 0)
{
ECMA_TRY_CATCH (str_arg_value,
ecma_op_to_string (arguments_list_p[arguments_list_len - 1]),
ret_value);
ecma_string_t *body_str_p = ecma_get_string_from_value (str_arg_value);
concated_str_p = ecma_concat_ecma_strings (expr_str_p, body_str_p);
ecma_deref_ecma_string (expr_str_p);
expr_str_p = concated_str_p;
ECMA_FINALIZE (str_arg_value);
}
concated_str_p = ecma_concat_ecma_strings (expr_str_p, right_brace_str_p);
ecma_deref_ecma_string (expr_str_p);
expr_str_p = concated_str_p;
concated_str_p = ecma_concat_ecma_strings (expr_str_p, right_parenthesis_str_p);
ecma_deref_ecma_string (expr_str_p);
expr_str_p = concated_str_p;
}
ecma_deref_ecma_string (left_parenthesis_str_p);
ecma_deref_ecma_string (right_parenthesis_str_p);
ecma_deref_ecma_string (left_brace_str_p);
ecma_deref_ecma_string (right_brace_str_p);
ecma_deref_ecma_string (comma_str_p);
ecma_deref_ecma_string (function_kw_str_p);
ecma_deref_ecma_string (empty_str_p);
if (ecma_is_value_empty (ret_value))
{
ret_value = ecma_make_string_value (expr_str_p);
}
else
{
ecma_deref_ecma_string (expr_str_p);
}
return ret_value;
} /* ecma_builtin_function_helper_get_function_expression */
/**
* Handle calling [[Construct]] of built-in Function object
*
* See also:
* ECMA-262 v5, 15.3.
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_function_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_TRY_CATCH (arguments_value,
ecma_builtin_function_helper_get_function_expression (arguments_list_p,
arguments_list_len),
ret_value);
ecma_string_t *function_expression_p = ecma_get_string_from_value (arguments_value);
ret_value = ecma_op_eval (function_expression_p, false, false);
ECMA_FINALIZE (arguments_value);
return ret_value;
} /* ecma_builtin_function_dispatch_construct */
/**
* @}
* @}
* @}
*/

View file

@ -0,0 +1,60 @@
/* 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.
*/
/*
* Function built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_FUNCTION)
/* Object properties:
* (property name, object pointer getter) */
// 15.3.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE,
ECMA_PROPERTY_FIXED)
/* Number properties:
* (property name, object pointer getter) */
// 15.3.3.2
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,199 @@
/* 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.
*/
/*
* Global built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef SIMPLE_VALUE
# define SIMPLE_VALUE(name, simple_value, prop_attributes)
#endif /* !SIMPLE_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_GLOBAL)
/* Simple value properties:
* (property name, simple value, writable, enumerable, configurable) */
// ECMA-262 v5, 15.1.1.3
SIMPLE_VALUE (LIT_MAGIC_STRING_UNDEFINED,
ECMA_SIMPLE_VALUE_UNDEFINED,
ECMA_PROPERTY_FIXED)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
// ECMA-262 v5, 15.1.1.1
NUMBER_VALUE (LIT_MAGIC_STRING_NAN,
ECMA_BUILTIN_NUMBER_NAN,
ECMA_PROPERTY_FIXED)
// ECMA-262 v5, 15.1.1.2
NUMBER_VALUE (LIT_MAGIC_STRING_INFINITY_UL,
ECMA_BUILTIN_NUMBER_POSITIVE_INFINITY,
ECMA_PROPERTY_FIXED)
/* Object properties:
* (property name, object pointer getter) */
// ECMA-262 v5, 15.1.4.1
OBJECT_VALUE (LIT_MAGIC_STRING_OBJECT_UL,
ECMA_BUILTIN_ID_OBJECT,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// ECMA-262 v5, 15.1.4.2
OBJECT_VALUE (LIT_MAGIC_STRING_FUNCTION_UL,
ECMA_BUILTIN_ID_FUNCTION,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// ECMA-262 v5, 15.1.4.3
#ifndef CONFIG_DISABLE_ARRAY_BUILTIN
OBJECT_VALUE (LIT_MAGIC_STRING_ARRAY_UL,
ECMA_BUILTIN_ID_ARRAY,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* !CONFIG_DISABLE_ARRAY_BUILTIN*/
#ifndef CONFIG_DISABLE_STRING_BUILTIN
// ECMA-262 v5, 15.1.4.4
OBJECT_VALUE (LIT_MAGIC_STRING_STRING_UL,
ECMA_BUILTIN_ID_STRING,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* !CONFIG_DISABLE_STRING_BUILTIN */
#ifndef CONFIG_DISABLE_BOOLEAN_BUILTIN
// ECMA-262 v5, 15.1.4.5
OBJECT_VALUE (LIT_MAGIC_STRING_BOOLEAN_UL,
ECMA_BUILTIN_ID_BOOLEAN,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* !CONFIG_DISABLE_BOOLEAN_BUILTIN */
#ifndef CONFIG_DISABLE_NUMBER_BUILTIN
// ECMA-262 v5, 15.1.4.6
OBJECT_VALUE (LIT_MAGIC_STRING_NUMBER_UL,
ECMA_BUILTIN_ID_NUMBER,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* !CONFIG_DISABLE_NUMBER_BUILTIN */
#ifndef CONFIG_DISABLE_DATE_BUILTIN
// ECMA-262 v5, 15.1.4.7
OBJECT_VALUE (LIT_MAGIC_STRING_DATE_UL,
ECMA_BUILTIN_ID_DATE,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* !CONFIG_DISABLE_DATE_BUILTIN */
#ifndef CONFIG_DISABLE_REGEXP_BUILTIN
// ECMA-262 v5, 15.1.4.8
OBJECT_VALUE (LIT_MAGIC_STRING_REGEXP_UL,
ECMA_BUILTIN_ID_REGEXP,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
// ECMA-262 v5, 15.1.4.9
OBJECT_VALUE (LIT_MAGIC_STRING_ERROR_UL,
ECMA_BUILTIN_ID_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
// ECMA-262 v5, 15.1.4.10
OBJECT_VALUE (LIT_MAGIC_STRING_EVAL_ERROR_UL,
ECMA_BUILTIN_ID_EVAL_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// ECMA-262 v5, 15.1.4.11
OBJECT_VALUE (LIT_MAGIC_STRING_RANGE_ERROR_UL,
ECMA_BUILTIN_ID_RANGE_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// ECMA-262 v5, 15.1.4.12
OBJECT_VALUE (LIT_MAGIC_STRING_REFERENCE_ERROR_UL,
ECMA_BUILTIN_ID_REFERENCE_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// ECMA-262 v5, 15.1.4.13
OBJECT_VALUE (LIT_MAGIC_STRING_SYNTAX_ERROR_UL,
ECMA_BUILTIN_ID_SYNTAX_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// ECMA-262 v5, 15.1.4.14
OBJECT_VALUE (LIT_MAGIC_STRING_TYPE_ERROR_UL,
ECMA_BUILTIN_ID_TYPE_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// ECMA-262 v5, 15.1.4.15
OBJECT_VALUE (LIT_MAGIC_STRING_URI_ERROR_UL,
ECMA_BUILTIN_ID_URI_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */
#ifndef CONFIG_DISABLE_MATH_BUILTIN
// ECMA-262 v5, 15.1.5.1
OBJECT_VALUE (LIT_MAGIC_STRING_MATH_UL,
ECMA_BUILTIN_ID_MATH,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* !CONFIG_DISABLE_MATH_BUILTIN */
#ifndef CONFIG_DISABLE_JSON_BUILTIN
// ECMA-262 v5, 15.1.5.2
OBJECT_VALUE (LIT_MAGIC_STRING_JSON_U,
ECMA_BUILTIN_ID_JSON,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* !CONFIG_DISABLE_JSON_BUILTIN */
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
// Implementation-defined 'print' routine
#ifndef CONFIG_DISABLE_PRINT_BUILTIN
ROUTINE (LIT_MAGIC_STRING_PRINT, ecma_builtin_global_object_print, NON_FIXED, 1)
#endif
ROUTINE (LIT_MAGIC_STRING_EVAL, ecma_builtin_global_object_eval, 1, 1)
ROUTINE (LIT_MAGIC_STRING_PARSE_FLOAT, ecma_builtin_global_object_parse_float, 1, 1)
ROUTINE (LIT_MAGIC_STRING_IS_NAN, ecma_builtin_global_object_is_nan, 1, 1)
ROUTINE (LIT_MAGIC_STRING_IS_FINITE, ecma_builtin_global_object_is_finite, 1, 1)
ROUTINE (LIT_MAGIC_STRING_DECODE_URI, ecma_builtin_global_object_decode_uri, 1, 1)
ROUTINE (LIT_MAGIC_STRING_DECODE_URI_COMPONENT, ecma_builtin_global_object_decode_uri_component, 1, 1)
ROUTINE (LIT_MAGIC_STRING_ENCODE_URI, ecma_builtin_global_object_encode_uri, 1, 1)
ROUTINE (LIT_MAGIC_STRING_ENCODE_URI_COMPONENT, ecma_builtin_global_object_encode_uri_component, 1, 1)
ROUTINE (LIT_MAGIC_STRING_PARSE_INT, ecma_builtin_global_object_parse_int, 2, 2)
#ifndef CONFIG_DISABLE_ANNEXB_BUILTIN
ROUTINE (LIT_MAGIC_STRING_ESCAPE, ecma_builtin_global_object_escape, 1, 1)
ROUTINE (LIT_MAGIC_STRING_UNESCAPE, ecma_builtin_global_object_unescape, 1, 1)
#endif /* !CONFIG_DISABLE_ANNEXB_BUILTIN */
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,78 @@
/* Copyright 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-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-builtin-helpers.h"
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltinhelpers ECMA builtin helper operations
* @{
*/
/**
* Handle calling [[Call]] of a built-in error object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_helper_error_dispatch_call (ecma_standard_error_t error_type, /**< native error type */
const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
if (arguments_list_len != 0
&& !ecma_is_value_undefined (arguments_list_p[0]))
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_TRY_CATCH (msg_str_value,
ecma_op_to_string (arguments_list_p[0]),
ret_value);
ecma_string_t *message_string_p = ecma_get_string_from_value (msg_str_value);
ecma_object_t *new_error_object_p = ecma_new_standard_error_with_message (error_type,
message_string_p);
ret_value = ecma_make_object_value (new_error_object_p);
ECMA_FINALIZE (msg_str_value);
return ret_value;
}
else
{
ecma_object_t *new_error_object_p = ecma_new_standard_error (error_type);
return ecma_make_object_value (new_error_object_p);
}
} /* ecma_builtin_helper_error_dispatch_call */
/**
* @}
* @}
*/

View file

@ -0,0 +1,310 @@
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-alloc.h"
#include "ecma-helpers.h"
#include "ecma-builtin-helpers.h"
#include "lit-char-helpers.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltinhelpers ECMA builtin helper operations
* @{
*/
/**
* Check the object value existance in the collection.
*
* Used by:
* - ecma_builtin_json_object step 1
* - ecma_builtin_json_array step 1
*
* @return true, if the object is already in the collection.
*/
bool
ecma_has_object_value_in_collection (ecma_collection_header_t *collection_p, /**< collection */
ecma_value_t object_value) /**< object value */
{
JERRY_ASSERT (ecma_is_value_object (object_value));
ecma_object_t *obj_p = ecma_get_object_from_value (object_value);
ecma_collection_iterator_t iterator;
ecma_collection_iterator_init (&iterator, collection_p);
while (ecma_collection_iterator_next (&iterator))
{
ecma_value_t value = *iterator.current_value_p;
ecma_object_t *current_p = ecma_get_object_from_value (value);
if (current_p == obj_p)
{
return true;
}
}
return false;
} /* ecma_has_object_value_in_collection */
/**
* Check the string value existance in the collection.
*
* Used by:
* - ecma_builtin_json_stringify step 4.b.ii.5
*
* @return true, if the string is already in the collection.
*/
bool
ecma_has_string_value_in_collection (ecma_collection_header_t *collection_p, /**< collection */
ecma_value_t string_value) /**< string value */
{
JERRY_ASSERT (ecma_is_value_string (string_value));
ecma_string_t *string_p = ecma_get_string_from_value (string_value);
ecma_collection_iterator_t iterator;
ecma_collection_iterator_init (&iterator, collection_p);
while (ecma_collection_iterator_next (&iterator))
{
ecma_value_t value = *iterator.current_value_p;
ecma_string_t *current_p = ecma_get_string_from_value (value);
if (ecma_compare_ecma_strings (current_p, string_p))
{
return true;
}
}
return false;
} /* ecma_has_string_value_in_collection*/
/**
* Common function to concatenate key-value pairs into an ecma-string.
*
* See also:
* ECMA-262 v5, 15.12.3
*
* Used by:
* - ecma_builtin_helper_json_create_formatted_json step 10.b.ii
* - ecma_builtin_helper_json_create_non_formatted_json step 10.a.i
*
* @return pointer to ecma-string
* Returned value must be freed with ecma_deref_ecma_string.
*/
ecma_string_t *
ecma_builtin_helper_json_create_separated_properties (ecma_collection_header_t *partial_p, /**< key-value pairs*/
ecma_string_t *separator_p) /**< separator*/
{
ecma_string_t *properties_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
ecma_string_t *tmp_str_p;
ecma_collection_iterator_t iterator;
ecma_collection_iterator_init (&iterator, partial_p);
uint32_t index = 0;
while (ecma_collection_iterator_next (&iterator))
{
ecma_value_t name_value = *iterator.current_value_p;
ecma_string_t *current_p = ecma_get_string_from_value (name_value);
if (index == 0)
{
index++;
tmp_str_p = ecma_concat_ecma_strings (properties_str_p, current_p);
ecma_deref_ecma_string (properties_str_p);
properties_str_p = tmp_str_p;
continue;
}
tmp_str_p = ecma_concat_ecma_strings (properties_str_p, separator_p);
ecma_deref_ecma_string (properties_str_p);
properties_str_p = tmp_str_p;
tmp_str_p = ecma_concat_ecma_strings (properties_str_p, current_p);
ecma_deref_ecma_string (properties_str_p);
properties_str_p = tmp_str_p;
}
return properties_str_p;
} /* ecma_builtin_helper_json_create_separated_properties */
/**
* Common function to create a formatted JSON string.
*
* See also:
* ECMA-262 v5, 15.12.3
*
* Used by:
* - ecma_builtin_json_object step 10.b
* - ecma_builtin_json_array step 10.b
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_helper_json_create_formatted_json (ecma_string_t *left_bracket_p, /**< left bracket*/
ecma_string_t *right_bracket_p, /**< right bracket*/
ecma_string_t *stepback_p, /**< stepback*/
ecma_collection_header_t *partial_p, /**< key-value pairs*/
ecma_json_stringify_context_t *context_p) /**< context*/
{
/* 10.b */
ecma_string_t *comma_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_COMMA_CHAR);
ecma_string_t *line_feed_p = ecma_get_magic_string (LIT_MAGIC_STRING_NEW_LINE_CHAR);
ecma_string_t *properties_str_p;
ecma_string_t *separator_p;
/* 10.b.i */
ecma_string_t *tmp_str_p = ecma_concat_ecma_strings (comma_str_p, line_feed_p);
ecma_deref_ecma_string (comma_str_p);
separator_p = tmp_str_p;
tmp_str_p = ecma_concat_ecma_strings (separator_p, context_p->indent_str_p);
ecma_deref_ecma_string (separator_p);
separator_p = tmp_str_p;
/* 10.b.ii */
properties_str_p = ecma_builtin_helper_json_create_separated_properties (partial_p, separator_p);
ecma_deref_ecma_string (separator_p);
/* 10.b.iii */
ecma_string_t *final_str_p;
tmp_str_p = ecma_concat_ecma_strings (left_bracket_p, line_feed_p);
final_str_p = tmp_str_p;
tmp_str_p = ecma_concat_ecma_strings (final_str_p, context_p->indent_str_p);
ecma_deref_ecma_string (final_str_p);
final_str_p = tmp_str_p;
tmp_str_p = ecma_concat_ecma_strings (final_str_p, properties_str_p);
ecma_deref_ecma_string (final_str_p);
ecma_deref_ecma_string (properties_str_p);
final_str_p = tmp_str_p;
tmp_str_p = ecma_concat_ecma_strings (final_str_p, line_feed_p);
ecma_deref_ecma_string (line_feed_p);
ecma_deref_ecma_string (final_str_p);
final_str_p = tmp_str_p;
tmp_str_p = ecma_concat_ecma_strings (final_str_p, stepback_p);
ecma_deref_ecma_string (final_str_p);
final_str_p = tmp_str_p;
tmp_str_p = ecma_concat_ecma_strings (final_str_p, right_bracket_p);
ecma_deref_ecma_string (final_str_p);
final_str_p = tmp_str_p;
return ecma_make_string_value (final_str_p);
} /* ecma_builtin_helper_json_create_formatted_json */
/**
* Common function to create a non-formatted JSON string.
*
* See also:
* ECMA-262 v5, 15.12.3
*
* Used by:
* - ecma_builtin_json_object step 10.a
* - ecma_builtin_json_array step 10.a
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_helper_json_create_non_formatted_json (ecma_string_t *left_bracket_p, /**< left bracket*/
ecma_string_t *right_bracket_p, /**< right bracket*/
ecma_collection_header_t *partial_p) /**< key-value pairs*/
{
/* 10.a */
ecma_string_t *comma_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_COMMA_CHAR);
ecma_string_t *properties_str_p;
ecma_string_t *tmp_str_p;
/* 10.a.i */
properties_str_p = ecma_builtin_helper_json_create_separated_properties (partial_p, comma_str_p);
ecma_deref_ecma_string (comma_str_p);
/* 10.a.ii */
tmp_str_p = ecma_concat_ecma_strings (left_bracket_p, properties_str_p);
ecma_deref_ecma_string (properties_str_p);
properties_str_p = tmp_str_p;
tmp_str_p = ecma_concat_ecma_strings (properties_str_p, right_bracket_p);
ecma_deref_ecma_string (properties_str_p);
properties_str_p = tmp_str_p;
return ecma_make_string_value (properties_str_p);
} /* ecma_builtin_helper_json_create_non_formatted_json */
/**
* Convert decimal value to 4 digit hexadecimal string value.
*
* See also:
* ECMA-262 v5, 15.12.3
*
* Used by:
* - ecma_builtin_json_quote step 2.c.iii
*
* @return pointer to ecma-string
* Returned value must be freed with ecma_deref_ecma_string.
*/
ecma_string_t *
ecma_builtin_helper_json_create_hex_digit_ecma_string (uint8_t value) /**< value in decimal*/
{
/* 2.c.iii */
ecma_string_t *hex_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
JMEM_DEFINE_LOCAL_ARRAY (hex_buff, 4, lit_utf8_byte_t);
for (uint32_t i = 0; i < 4; i++)
{
uint8_t remainder = value % 16;
lit_utf8_byte_t ch = ' ';
if (remainder < 10)
{
ch = (lit_utf8_byte_t) (LIT_CHAR_0 + remainder);
}
else
{
uint8_t a = (uint8_t) (remainder - 10);
ch = (lit_utf8_byte_t) (LIT_CHAR_LOWERCASE_A + a);
}
hex_buff[3 - i] = ch;
value = value / 16;
}
ecma_deref_ecma_string (hex_str_p);
hex_str_p = ecma_new_ecma_string_from_utf8 ((lit_utf8_byte_t *) hex_buff, 4);
JMEM_FINALIZE_LOCAL_ARRAY (hex_buff);
JERRY_ASSERT (ecma_string_get_length (hex_str_p));
return hex_str_p;
} /* ecma_builtin_helper_json_create_hex_digit_ecma_string */
/**
* @}
* @}
*/

View file

@ -0,0 +1,700 @@
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-builtin-helpers.h"
#include "ecma-alloc.h"
#include "ecma-array-object.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-function-object.h"
#include "ecma-exceptions.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#include "lit-magic-strings.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltinhelpers ECMA builtin helper operations
* @{
*/
/**
* Common implementation of the Object.prototype.toString routine
*
* See also:
* ECMA-262 v5, 15.2.4.2
*
* Used by:
* - The Object.prototype.toString routine.
* - The Array.prototype.toString routine as fallback.
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_helper_object_to_string (const ecma_value_t this_arg) /**< this argument */
{
lit_magic_string_id_t type_string;
if (ecma_is_value_undefined (this_arg))
{
type_string = LIT_MAGIC_STRING_UNDEFINED_UL;
}
else if (ecma_is_value_null (this_arg))
{
type_string = LIT_MAGIC_STRING_NULL_UL;
}
else
{
ecma_value_t obj_this = ecma_op_to_object (this_arg);
if (ECMA_IS_VALUE_ERROR (obj_this))
{
return obj_this;
}
JERRY_ASSERT (ecma_is_value_object (obj_this));
ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
type_string = ecma_object_get_class_name (obj_p);
ecma_free_value (obj_this);
}
ecma_string_t *ret_string_p;
/* Building string "[object #type#]" where type is 'Undefined',
'Null' or one of possible object's classes.
The string with null character is maximum 19 characters long. */
const lit_utf8_size_t buffer_size = 19;
JMEM_DEFINE_LOCAL_ARRAY (str_buffer, buffer_size, lit_utf8_byte_t);
lit_utf8_byte_t *buffer_ptr = str_buffer;
const lit_magic_string_id_t magic_string_ids[] =
{
LIT_MAGIC_STRING_LEFT_SQUARE_CHAR,
LIT_MAGIC_STRING_OBJECT,
LIT_MAGIC_STRING_SPACE_CHAR,
type_string,
LIT_MAGIC_STRING_RIGHT_SQUARE_CHAR
};
for (uint32_t i = 0; i < sizeof (magic_string_ids) / sizeof (lit_magic_string_id_t); ++i)
{
buffer_ptr = lit_copy_magic_string_to_buffer (magic_string_ids[i], buffer_ptr,
(lit_utf8_size_t) ((str_buffer + buffer_size) - buffer_ptr));
JERRY_ASSERT (buffer_ptr <= str_buffer + buffer_size);
}
ret_string_p = ecma_new_ecma_string_from_utf8 (str_buffer, (lit_utf8_size_t) (buffer_ptr - str_buffer));
JMEM_FINALIZE_LOCAL_ARRAY (str_buffer);
return ecma_make_string_value (ret_string_p);
} /* ecma_builtin_helper_object_to_string */
/**
* The Array.prototype's 'toLocaleString' single element operation routine
*
* See also:
* ECMA-262 v5, 15.4.4.3 steps 6-8 and 10.b-d
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, /**< this object */
uint32_t index) /**< array index */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
ECMA_TRY_CATCH (index_value,
ecma_op_object_get (obj_p, index_string_p),
ret_value);
if (ecma_is_value_undefined (index_value) || ecma_is_value_null (index_value))
{
ecma_string_t *return_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
ret_value = ecma_make_string_value (return_string_p);
}
else
{
ECMA_TRY_CATCH (index_obj_value,
ecma_op_to_object (index_value),
ret_value);
ecma_object_t *index_obj_p = ecma_get_object_from_value (index_obj_value);
ecma_string_t *locale_string_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_TO_LOCALE_STRING_UL);
ECMA_TRY_CATCH (to_locale_value,
ecma_op_object_get (index_obj_p, locale_string_magic_string_p),
ret_value);
if (ecma_op_is_callable (to_locale_value))
{
ecma_object_t *locale_func_obj_p = ecma_get_object_from_value (to_locale_value);
ECMA_TRY_CATCH (call_value,
ecma_op_function_call (locale_func_obj_p,
ecma_make_object_value (index_obj_p),
NULL,
0),
ret_value);
ret_value = ecma_op_to_string (call_value);
ECMA_FINALIZE (call_value);
}
else
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
ECMA_FINALIZE (to_locale_value);
ecma_deref_ecma_string (locale_string_magic_string_p);
ECMA_FINALIZE (index_obj_value);
}
ECMA_FINALIZE (index_value);
ecma_deref_ecma_string (index_string_p);
return ret_value;
} /* ecma_builtin_helper_get_to_locale_string_at_index */
/**
* The Object.keys and Object.getOwnPropertyNames routine's common part.
*
* See also:
* ECMA-262 v5, 15.2.3.4 steps 2-5
* ECMA-262 v5, 15.2.3.14 steps 3-6
*
* @return ecma value - Array of property names.
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /**< object */
bool only_enumerable_properties) /**< list enumerable properties? */
{
JERRY_ASSERT (obj_p != NULL);
ecma_value_t new_array = ecma_op_create_array_object (NULL, 0, false);
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
uint32_t index = 0;
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p,
false,
only_enumerable_properties,
false);
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
while (ecma_collection_iterator_next (&iter))
{
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t completion = ecma_builtin_helper_def_prop (new_array_p,
index_string_p,
*iter.current_value_p,
true, /* Writable */
true, /* Enumerable */
true, /* Configurable */
false); /* Failure handling */
JERRY_ASSERT (ecma_is_value_true (completion));
ecma_deref_ecma_string (index_string_p);
index++;
}
ecma_free_values_collection (props_p, true);
return new_array;
} /* ecma_builtin_helper_object_get_properties */
/**
* Helper function to normalizing an array index
*
* This function clamps the given index to the [0, length] range.
* If the index is negative, it is used as the offset from the end of the array,
* to compute normalized index.
* If the index is greater than the length of the array, the normalized index will be the length of the array.
*
* See also:
* ECMA-262 v5, 15.4.4.10 steps 5-6, 7 (part 2) and 8
* ECMA-262 v5, 15.4.4.12 steps 5-6
* ECMA-262 v5, 15.4.4.14 steps 5
* ECMA-262 v5, 15.5.4.13 steps 4, 5 (part 2) and 6-7
*
* Used by:
* - The Array.prototype.slice routine.
* - The Array.prototype.splice routine.
* - The Array.prototype.indexOf routine.
* - The String.prototype.slice routine.
*
* @return uint32_t - the normalized value of the index
*/
uint32_t
ecma_builtin_helper_array_index_normalize (ecma_number_t index, /**< index */
uint32_t length) /**< array's length */
{
uint32_t norm_index;
if (!ecma_number_is_nan (index))
{
if (ecma_number_is_zero (index))
{
norm_index = 0;
}
else if (ecma_number_is_infinity (index))
{
norm_index = ecma_number_is_negative (index) ? 0 : length;
}
else
{
if (ecma_number_is_negative (index))
{
ecma_number_t index_neg = ecma_number_negate (index);
if (index_neg > length)
{
norm_index = 0;
}
else
{
norm_index = length - ecma_number_to_uint32 (index_neg);
}
}
else
{
if (index > length)
{
norm_index = length;
}
else
{
norm_index = ecma_number_to_uint32 (index);
}
}
}
}
else
{
norm_index = 0;
}
return norm_index;
} /* ecma_builtin_helper_array_index_normalize */
/**
* Helper function for concatenating an ecma_value_t to an Array.
*
* See also:
* ECMA-262 v5, 15.4.4.4 steps 5.b - 5.c
*
* Used by:
* - The Array.prototype.concat routine.
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, /**< array */
uint32_t *length_p, /**< [in,out] array's length */
ecma_value_t value) /**< value to concat */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
/* 5.b */
if (ecma_is_value_object (value)
&& (ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_ARRAY_UL))
{
ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string ();
/* 5.b.ii */
ECMA_TRY_CATCH (arg_len_value,
ecma_op_object_get (ecma_get_object_from_value (value),
magic_string_length_p),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_len_number, arg_len_value, ret_value);
uint32_t arg_len = ecma_number_to_uint32 (arg_len_number);
/* 5.b.iii */
for (uint32_t array_index = 0;
array_index < arg_len && ecma_is_value_empty (ret_value);
array_index++)
{
ecma_string_t *array_index_string_p = ecma_new_ecma_string_from_uint32 (array_index);
/* 5.b.iii.2 */
ECMA_TRY_CATCH (get_value,
ecma_op_object_find (ecma_get_object_from_value (value),
array_index_string_p),
ret_value);
if (ecma_is_value_found (get_value))
{
/* 5.b.iii.3.a */
ecma_string_t *new_array_index_string_p = ecma_new_ecma_string_from_uint32 (*length_p + array_index);
/* 5.b.iii.3.b */
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
ecma_value_t put_comp = ecma_builtin_helper_def_prop (obj_p,
new_array_index_string_p,
get_value,
true, /* Writable */
true, /* Enumerable */
true, /* Configurable */
false); /* Failure handling */
JERRY_ASSERT (ecma_is_value_true (put_comp));
ecma_deref_ecma_string (new_array_index_string_p);
}
ECMA_FINALIZE (get_value);
ecma_deref_ecma_string (array_index_string_p);
}
*length_p += arg_len;
ECMA_OP_TO_NUMBER_FINALIZE (arg_len_number);
ECMA_FINALIZE (arg_len_value);
ecma_deref_ecma_string (magic_string_length_p);
}
else
{
ecma_string_t *new_array_index_string_p = ecma_new_ecma_string_from_uint32 ((*length_p)++);
/* 5.c.i */
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
ecma_value_t put_comp = ecma_builtin_helper_def_prop (obj_p,
new_array_index_string_p,
value,
true, /* Writable */
true, /* Enumerable */
true, /* Configurable */
false); /* Failure handling */
JERRY_ASSERT (ecma_is_value_true (put_comp));
ecma_deref_ecma_string (new_array_index_string_p);
}
if (ecma_is_value_empty (ret_value))
{
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
}
return ret_value;
} /* ecma_builtin_helper_array_concat_value */
/**
* Helper function to normalizing a string index
*
* This function clamps the given index to the [0, length] range.
* If the index is negative, 0 value is used.
* If the index is greater than the length of the string, the normalized index will be the length of the string.
* NaN is mapped to zero or length depending on the nan_to_zero parameter.
*
* See also:
* ECMA-262 v5, 15.5.4.15
*
* Used by:
* - The String.prototype.substring routine.
* - The ecma_builtin_helper_string_prototype_object_index_of helper routine.
*
* @return uint32_t - the normalized value of the index
*/
uint32_t
ecma_builtin_helper_string_index_normalize (ecma_number_t index, /**< index */
uint32_t length, /**< string's length */
bool nan_to_zero) /**< whether NaN is mapped to zero (t) or length (f) */
{
uint32_t norm_index = 0;
if (ecma_number_is_nan (index))
{
if (!nan_to_zero)
{
norm_index = length;
}
}
else if (!ecma_number_is_negative (index))
{
if (ecma_number_is_infinity (index))
{
norm_index = length;
}
else
{
norm_index = ecma_number_to_uint32 (index);
if (norm_index > length)
{
norm_index = length;
}
}
}
return norm_index;
} /* ecma_builtin_helper_string_index_normalize */
/**
* Helper function for string indexOf and lastIndexOf functions
*
* This function implements string indexOf and lastIndexOf with required checks and conversions.
*
* See also:
* ECMA-262 v5, 15.5.4.7
* ECMA-262 v5, 15.5.4.8
*
* Used by:
* - The String.prototype.indexOf routine.
* - The String.prototype.lastIndexOf routine.
*
* @return uint32_t - (last) index of search string
*/
ecma_value_t
ecma_builtin_helper_string_prototype_object_index_of (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg1, /**< routine's first argument */
ecma_value_t arg2, /**< routine's second argument */
bool first_index) /**< routine's third argument */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
/* 1 */
ECMA_TRY_CATCH (check_coercible_val,
ecma_op_check_object_coercible (this_arg),
ret_value);
/* 2 */
ECMA_TRY_CATCH (to_str_val,
ecma_op_to_string (this_arg),
ret_value);
/* 3 */
ECMA_TRY_CATCH (search_str_val,
ecma_op_to_string (arg1),
ret_value);
/* 4 */
ECMA_OP_TO_NUMBER_TRY_CATCH (pos_num,
arg2,
ret_value);
/* 5 (indexOf) -- 6 (lastIndexOf) */
ecma_string_t *original_str_p = ecma_get_string_from_value (to_str_val);
const ecma_length_t original_len = ecma_string_get_length (original_str_p);
/* 4b, 6 (indexOf) - 4b, 5, 7 (lastIndexOf) */
ecma_length_t start = ecma_builtin_helper_string_index_normalize (pos_num, original_len, first_index);
/* 7 (indexOf) -- 8 (lastIndexOf) */
ecma_string_t *search_str_p = ecma_get_string_from_value (search_str_val);
ecma_number_t ret_num = ECMA_NUMBER_MINUS_ONE;
/* 8 (indexOf) -- 9 (lastIndexOf) */
ecma_length_t index_of = 0;
if (ecma_builtin_helper_string_find_index (original_str_p, search_str_p, first_index, start, &index_of))
{
ret_num = ((ecma_number_t) index_of);
}
ret_value = ecma_make_number_value (ret_num);
ECMA_OP_TO_NUMBER_FINALIZE (pos_num);
ECMA_FINALIZE (search_str_val);
ECMA_FINALIZE (to_str_val);
ECMA_FINALIZE (check_coercible_val);
return ret_value;
} /* ecma_builtin_helper_string_prototype_object_index_of */
/**
* Helper function for finding index of a search string
*
* This function clamps the given index to the [0, length] range.
* If the index is negative, 0 value is used.
* If the index is greater than the length of the string, the normalized index will be the length of the string.
* NaN is mapped to zero or length depending on the nan_to_zero parameter.
*
* See also:
* ECMA-262 v5, 15.5.4.7,8,11
*
* Used by:
* - The ecma_builtin_helper_string_prototype_object_index_of helper routine.
* - The ecma_builtin_string_prototype_object_replace_match helper routine.
*
* @return uint32_t - the normalized value of the index
*/
bool
ecma_builtin_helper_string_find_index (ecma_string_t *original_str_p, /**< index */
ecma_string_t *search_str_p, /**< string's length */
bool first_index, /**< whether search for first (t) or last (f) index */
ecma_length_t start_pos, /**< start position */
ecma_length_t *ret_index_p) /**< position found in original string */
{
bool match_found = false;
const ecma_length_t original_len = ecma_string_get_length (original_str_p);
const ecma_length_t search_len = ecma_string_get_length (search_str_p);
if (search_len <= original_len)
{
if (!search_len)
{
match_found = true;
*ret_index_p = first_index ? 0 : original_len;
}
else
{
/* create utf8 string from original string and advance to position */
ECMA_STRING_TO_UTF8_STRING (original_str_p, original_str_utf8_p, original_str_size);
ecma_length_t index = start_pos;
const lit_utf8_byte_t *original_str_curr_p = original_str_utf8_p;
for (ecma_length_t idx = 0; idx < index; idx++)
{
lit_utf8_incr (&original_str_curr_p);
}
/* create utf8 string from search string */
ECMA_STRING_TO_UTF8_STRING (search_str_p, search_str_utf8_p, search_str_size);
const lit_utf8_byte_t *search_str_curr_p = search_str_utf8_p;
/* iterate original string and try to match at each position */
bool searching = true;
ecma_char_t first_char = lit_utf8_read_next (&search_str_curr_p);
while (searching)
{
/* match as long as possible */
ecma_length_t match_len = 0;
const lit_utf8_byte_t *stored_original_str_curr_p = original_str_curr_p;
if (match_len < search_len &&
index + match_len < original_len &&
lit_utf8_read_next (&original_str_curr_p) == first_char)
{
const lit_utf8_byte_t *nested_search_str_curr_p = search_str_curr_p;
match_len++;
while (match_len < search_len &&
index + match_len < original_len &&
lit_utf8_read_next (&original_str_curr_p) == lit_utf8_read_next (&nested_search_str_curr_p))
{
match_len++;
}
}
/* check for match */
if (match_len == search_len)
{
match_found = true;
*ret_index_p = index;
break;
}
else
{
/* inc/dec index and update iterators and search condition */
original_str_curr_p = stored_original_str_curr_p;
if (first_index)
{
if ((searching = (index <= original_len - search_len)))
{
lit_utf8_incr (&original_str_curr_p);
index++;
}
}
else
{
if ((searching = (index > 0)))
{
lit_utf8_decr (&original_str_curr_p);
index--;
}
}
}
}
ECMA_FINALIZE_UTF8_STRING (search_str_utf8_p, search_str_size);
ECMA_FINALIZE_UTF8_STRING (original_str_utf8_p, original_str_size);
}
}
return match_found;
} /* ecma_builtin_helper_string_find_index */
/**
* Helper function for using [[DefineOwnProperty]].
*
* See also:
* ECMA-262 v5, 8.12.9
* ECMA-262 v5, 15.4.5.1
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_helper_def_prop (ecma_object_t *obj_p, /**< object */
ecma_string_t *index_p, /**< index string */
ecma_value_t value, /**< value */
bool writable, /**< writable */
bool enumerable, /**< enumerable */
bool configurable, /**< configurable */
bool is_throw) /**< is_throw */
{
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
prop_desc.is_value_defined = true;
prop_desc.value = value;
prop_desc.is_writable_defined = true;
prop_desc.is_writable = writable;
prop_desc.is_enumerable_defined = true;
prop_desc.is_enumerable = enumerable;
prop_desc.is_configurable_defined = true;
prop_desc.is_configurable = configurable;
return ecma_op_object_define_own_property (obj_p,
index_p,
&prop_desc,
is_throw);
} /* ecma_builtin_helper_def_prop */
/**
* @}
* @}
*/

View file

@ -0,0 +1,179 @@
/* 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_BUILTIN_HELPERS_H
#define ECMA_BUILTIN_HELPERS_H
#include "ecma-globals.h"
#include "ecma-exceptions.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltinhelpers ECMA builtin helper operations
* @{
*/
extern ecma_value_t
ecma_builtin_helper_object_to_string (const ecma_value_t);
extern ecma_value_t
ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *, uint32_t);
extern ecma_value_t
ecma_builtin_helper_object_get_properties (ecma_object_t *, bool);
extern ecma_value_t
ecma_builtin_helper_array_concat_value (ecma_object_t *, uint32_t *, ecma_value_t);
extern uint32_t
ecma_builtin_helper_array_index_normalize (ecma_number_t, uint32_t);
extern uint32_t
ecma_builtin_helper_string_index_normalize (ecma_number_t, uint32_t, bool);
extern ecma_value_t
ecma_builtin_helper_string_prototype_object_index_of (ecma_value_t, ecma_value_t,
ecma_value_t, bool);
extern bool
ecma_builtin_helper_string_find_index (ecma_string_t *, ecma_string_t *, bool, ecma_length_t, ecma_length_t *);
extern ecma_value_t
ecma_builtin_helper_def_prop (ecma_object_t *, ecma_string_t *, ecma_value_t,
bool, bool, bool, bool);
#ifndef CONFIG_DISABLE_DATE_BUILTIN
/**
* Time range defines for helper functions.
*
* See also:
* ECMA-262 v5, 15.9.1.1, 15.9.1.10
*/
/** Hours in a day. */
#define ECMA_DATE_HOURS_PER_DAY ((ecma_number_t) 24)
/** Minutes in an hour. */
#define ECMA_DATE_MINUTES_PER_HOUR ((ecma_number_t) 60)
/** Seconds in a minute. */
#define ECMA_DATE_SECONDS_PER_MINUTE ((ecma_number_t) 60)
/** Milliseconds in a second. */
#define ECMA_DATE_MS_PER_SECOND ((ecma_number_t) 1000)
/** ECMA_DATE_MS_PER_MINUTE == 60000 */
#define ECMA_DATE_MS_PER_MINUTE (ECMA_DATE_MS_PER_SECOND * ECMA_DATE_SECONDS_PER_MINUTE)
/** ECMA_DATE_MS_PER_HOUR == 3600000 */
#define ECMA_DATE_MS_PER_HOUR (ECMA_DATE_MS_PER_MINUTE * ECMA_DATE_MINUTES_PER_HOUR)
/** ECMA_DATE_MS_PER_DAY == 86400000 */
#define ECMA_DATE_MS_PER_DAY (ECMA_DATE_MS_PER_HOUR * ECMA_DATE_HOURS_PER_DAY)
/**
* This gives a range of 8,640,000,000,000,000 milliseconds
* to either side of 01 January, 1970 UTC.
*/
#define ECMA_DATE_MAX_VALUE 8.64e15
/**
* Timezone type.
*/
typedef enum
{
ECMA_DATE_UTC, /**< date vaule is in UTC */
ECMA_DATE_LOCAL /**< date vaule is in local time */
} ecma_date_timezone_t;
/* ecma-builtin-helpers-date.c */
extern ecma_number_t ecma_date_day (ecma_number_t);
extern ecma_number_t ecma_date_time_within_day (ecma_number_t);
extern ecma_number_t ecma_date_days_in_year (ecma_number_t);
extern ecma_number_t ecma_date_day_from_year (ecma_number_t);
extern ecma_number_t ecma_date_time_from_year (ecma_number_t);
extern ecma_number_t ecma_date_year_from_time (ecma_number_t);
extern ecma_number_t ecma_date_in_leap_year (ecma_number_t);
extern ecma_number_t ecma_date_day_within_year (ecma_number_t);
extern ecma_number_t ecma_date_month_from_time (ecma_number_t);
extern ecma_number_t ecma_date_date_from_time (ecma_number_t);
extern ecma_number_t ecma_date_week_day (ecma_number_t);
extern ecma_number_t ecma_date_local_tza ();
extern ecma_number_t ecma_date_daylight_saving_ta (ecma_number_t);
extern ecma_number_t ecma_date_local_time (ecma_number_t);
extern ecma_number_t ecma_date_utc (ecma_number_t);
extern ecma_number_t ecma_date_hour_from_time (ecma_number_t);
extern ecma_number_t ecma_date_min_from_time (ecma_number_t);
extern ecma_number_t ecma_date_sec_from_time (ecma_number_t);
extern ecma_number_t ecma_date_ms_from_time (ecma_number_t);
extern ecma_number_t ecma_date_make_time (ecma_number_t, ecma_number_t, ecma_number_t, ecma_number_t);
extern ecma_number_t ecma_date_make_day (ecma_number_t, ecma_number_t, ecma_number_t);
extern ecma_number_t ecma_date_make_date (ecma_number_t, ecma_number_t);
extern ecma_number_t ecma_date_time_clip (ecma_number_t);
extern ecma_number_t ecma_date_timezone_offset (ecma_number_t);
extern ecma_value_t ecma_date_set_internal_property (ecma_value_t, ecma_number_t,
ecma_number_t, ecma_date_timezone_t);
extern ecma_value_t ecma_date_value_to_string (ecma_number_t);
extern ecma_value_t ecma_date_value_to_utc_string (ecma_number_t);
extern ecma_value_t ecma_date_value_to_iso_string (ecma_number_t);
extern ecma_value_t ecma_date_value_to_date_string (ecma_number_t);
extern ecma_value_t ecma_date_value_to_time_string (ecma_number_t);
extern ecma_value_t ecma_date_get_primitive_value (ecma_value_t);
#endif /* !CONFIG_DISABLE_DATE_BUILTIN */
/* ecma-builtin-helper-json.c */
/**
* Context for JSON.stringify()
*/
typedef struct
{
/** Collection for property keys. */
ecma_collection_header_t *property_list_p;
/** Collection for traversing objects. */
ecma_collection_header_t *occurence_stack_p;
/** The actual indentation text. */
ecma_string_t *indent_str_p;
/** The indentation text. */
ecma_string_t *gap_str_p;
/** The replacer function. */
ecma_object_t *replacer_function_p;
} ecma_json_stringify_context_t;
extern bool ecma_has_object_value_in_collection (ecma_collection_header_t *, ecma_value_t);
extern bool ecma_has_string_value_in_collection (ecma_collection_header_t *, ecma_value_t);
extern ecma_string_t *
ecma_builtin_helper_json_create_hex_digit_ecma_string (uint8_t);
extern ecma_string_t *
ecma_builtin_helper_json_create_separated_properties (ecma_collection_header_t *, ecma_string_t *);
extern ecma_value_t
ecma_builtin_helper_json_create_formatted_json (ecma_string_t *, ecma_string_t *, ecma_string_t *,
ecma_collection_header_t *, ecma_json_stringify_context_t *);
extern ecma_value_t
ecma_builtin_helper_json_create_non_formatted_json (ecma_string_t *, ecma_string_t *, ecma_collection_header_t *);
/* ecma-builtin-helper-error.c */
extern ecma_value_t
ecma_builtin_helper_error_dispatch_call (ecma_standard_error_t, const ecma_value_t *, ecma_length_t);
/**
* @}
* @}
*/
#endif /* !ECMA_BUILTIN_HELPERS_H */

View file

@ -0,0 +1,167 @@
/* 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.
*/
#ifndef BUILTIN_UNDERSCORED_ID
# error "Please, define BUILTIN_UNDERSCORED_ID"
#endif /* !BUILTIN_UNDERSCORED_ID */
#ifndef BUILTIN_INC_HEADER_NAME
# error "Please, define BUILTIN_INC_HEADER_NAME"
#endif /* !BUILTIN_INC_HEADER_NAME */
#include "ecma-objects.h"
#define PASTE__(x, y) x ## y
#define PASTE_(x, y) PASTE__ (x, y)
#define PASTE(x, y) PASTE_ (x, y)
#define PROPERTY_DESCRIPTOR_LIST_NAME \
PASTE (PASTE (ecma_builtin_, BUILTIN_UNDERSCORED_ID), _property_descriptor_list)
#define DISPATCH_ROUTINE_ROUTINE_NAME \
PASTE (PASTE (ecma_builtin_, BUILTIN_UNDERSCORED_ID), _dispatch_routine)
#define ROUTINE_ARG(n) , ecma_value_t arg ## n
#define ROUTINE_ARG_LIST_0 ecma_value_t this_arg
#define ROUTINE_ARG_LIST_1 ROUTINE_ARG_LIST_0 ROUTINE_ARG(1)
#define ROUTINE_ARG_LIST_2 ROUTINE_ARG_LIST_1 ROUTINE_ARG(2)
#define ROUTINE_ARG_LIST_3 ROUTINE_ARG_LIST_2 ROUTINE_ARG(3)
#define ROUTINE_ARG_LIST_NON_FIXED ROUTINE_ARG_LIST_0, \
const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len
#define ROUTINE(name, c_function_name, args_number, length_prop_value) \
static ecma_value_t c_function_name (ROUTINE_ARG_LIST_ ## args_number);
#include BUILTIN_INC_HEADER_NAME
#undef ROUTINE_ARG_LIST_NON_FIXED
#undef ROUTINE_ARG_LIST_3
#undef ROUTINE_ARG_LIST_2
#undef ROUTINE_ARG_LIST_1
#undef ROUTINE_ARG_LIST_0
#undef ROUTINE_ARG
enum
{
PASTE (ECMA_ROUTINE_START_, BUILTIN_UNDERSCORED_ID) = ECMA_BUILTIN_ID__COUNT - 1,
#define ROUTINE(name, c_function_name, args_number, length_prop_value) \
ECMA_ROUTINE_ ## name ## c_function_name,
#include BUILTIN_INC_HEADER_NAME
};
/**
* Built-in property list of the built-in object.
*/
const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] =
{
#define ROUTINE(name, c_function_name, args_number, length_prop_value) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_ROUTINE, \
ECMA_PROPERTY_CONFIGURABLE_WRITABLE, \
ECMA_ROUTINE_VALUE (ECMA_ROUTINE_ ## name ## c_function_name, length_prop_value) \
},
#define OBJECT_VALUE(name, obj_builtin_id, prop_attributes) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_OBJECT, \
prop_attributes, \
obj_builtin_id \
},
#define SIMPLE_VALUE(name, simple_value, prop_attributes) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_SIMPLE, \
prop_attributes, \
simple_value \
},
#define NUMBER_VALUE(name, number_value, prop_attributes) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_NUMBER, \
prop_attributes, \
number_value \
},
#define STRING_VALUE(name, magic_string_id, prop_attributes) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_STRING, \
prop_attributes, \
magic_string_id \
},
#include BUILTIN_INC_HEADER_NAME
{
LIT_MAGIC_STRING__COUNT,
ECMA_BUILTIN_PROPERTY_END,
0,
0
}
};
/**
* Dispatcher of the built-in's routines
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
DISPATCH_ROUTINE_ROUTINE_NAME (uint16_t builtin_routine_id, /**< built-in wide routine
identifier */
ecma_value_t this_arg_value, /**< 'this' argument
value */
const ecma_value_t arguments_list[], /**< list of arguments
passed to routine */
ecma_length_t arguments_number) /**< length of
arguments' list */
{
/* the arguments may be unused for some built-ins */
JERRY_UNUSED (this_arg_value);
JERRY_UNUSED (arguments_list);
JERRY_UNUSED (arguments_number);
switch (builtin_routine_id)
{
#define ROUTINE_ARG(n) (arguments_number >= n ? arguments_list[n - 1] \
: ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED))
#define ROUTINE_ARG_LIST_0
#define ROUTINE_ARG_LIST_1 , ROUTINE_ARG(1)
#define ROUTINE_ARG_LIST_2 ROUTINE_ARG_LIST_1, ROUTINE_ARG(2)
#define ROUTINE_ARG_LIST_3 ROUTINE_ARG_LIST_2, ROUTINE_ARG(3)
#define ROUTINE_ARG_LIST_NON_FIXED , arguments_list, arguments_number
#define ROUTINE(name, c_function_name, args_number, length_prop_value) \
case ECMA_ROUTINE_ ## name ## c_function_name: \
{ \
return c_function_name (this_arg_value ROUTINE_ARG_LIST_ ## args_number); \
}
#include BUILTIN_INC_HEADER_NAME
#undef ROUTINE_ARG
#undef ROUTINE_ARG_LIST_0
#undef ROUTINE_ARG_LIST_1
#undef ROUTINE_ARG_LIST_2
#undef ROUTINE_ARG_LIST_3
#undef ROUTINE_ARG_LIST_NON_FIXED
default:
{
JERRY_UNREACHABLE ();
}
}
} /* DISPATCH_ROUTINE_ROUTINE_NAME */
#undef PASTE__
#undef PASTE_
#undef PASTE
#undef PROPERTY_DESCRIPTOR_LIST_NAME
#undef DISPATCH_ROUTINE_ROUTINE_NAME
#undef BUILTIN_UNDERSCORED_ID
#undef BUILTIN_INC_HEADER_NAME
#undef ECMA_BUILTIN_PROPERTY_NAME_INDEX

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,54 @@
/* Copyright 2015 Samsung Electronics Co., Ltd.
* Copyright 2015 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.
*/
/*
* JSON built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef SIMPLE_VALUE
# define SIMPLE_VALUE(name, simple_value, prop_attributes)
#endif /* !SIMPLE_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_JSON)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_PARSE, ecma_builtin_json_parse, 2, 2)
ROUTINE (LIT_MAGIC_STRING_STRINGIFY, ecma_builtin_json_stringify, 3, 3)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,667 @@
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <math.h>
#include "ecma-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.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"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#include "jrt-libc-includes.h"
#ifndef CONFIG_DISABLE_MATH_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-math.inc.h"
#define BUILTIN_UNDERSCORED_ID math
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup object ECMA Object object built-in
* @{
*/
/**
* The Math object's 'abs' routine
*
* See also:
* ECMA-262 v5, 15.8.2.1
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_abs (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ret_value = ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (fabs (arg_num)));
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_abs */
/**
* The Math object's 'acos' routine
*
* See also:
* ECMA-262 v5, 15.8.2.2
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_acos (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ret_value = ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (acos (arg_num)));
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_acos */
/**
* The Math object's 'asin' routine
*
* See also:
* ECMA-262 v5, 15.8.2.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_asin (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ret_value = ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (asin (arg_num)));
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_asin */
/**
* The Math object's 'atan' routine
*
* See also:
* ECMA-262 v5, 15.8.2.4
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_atan (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ret_value = ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (atan (arg_num)));
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_atan */
/**
* The Math object's 'atan2' routine
*
* See also:
* ECMA-262 v5, 15.8.2.5
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_atan2 (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg1, /**< first routine's argument */
ecma_value_t arg2) /**< second routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (x, arg1, ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (y, arg2, ret_value);
ret_value = ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (atan2 (x, y)));
ECMA_OP_TO_NUMBER_FINALIZE (y);
ECMA_OP_TO_NUMBER_FINALIZE (x);
return ret_value;
} /* ecma_builtin_math_object_atan2 */
/**
* The Math object's 'ceil' routine
*
* See also:
* ECMA-262 v5, 15.8.2.6
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_ceil (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ret_value = ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (ceil (arg_num)));
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_ceil */
/**
* The Math object's 'cos' routine
*
* See also:
* ECMA-262 v5, 15.8.2.7
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_cos (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ret_value = ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (cos (arg_num)));
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_cos */
/**
* The Math object's 'exp' routine
*
* See also:
* ECMA-262 v5, 15.8.2.8
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_exp (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ret_value = ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (exp (arg_num)));
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_exp */
/**
* The Math object's 'floor' routine
*
* See also:
* ECMA-262 v5, 15.8.2.9
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_floor (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ret_value = ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (floor (arg_num)));
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_floor */
/**
* The Math object's 'log' routine
*
* See also:
* ECMA-262 v5, 15.8.2.10
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_log (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ret_value = ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (log (arg_num)));
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_log */
/**
* The Math object's 'max' routine
*
* See also:
* ECMA-262 v5, 15.8.2.11
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_max (ecma_value_t this_arg, /**< 'this' argument */
const ecma_value_t args[], /**< arguments list */
ecma_length_t args_number) /**< number of arguments */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_number_t ret_num = ecma_number_make_infinity (true);
bool is_NaN = false;
for (ecma_length_t arg_index = 0;
arg_index < args_number && ecma_is_value_empty (ret_value);
arg_index++)
{
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, args[arg_index], ret_value);
if (!is_NaN)
{
if (unlikely (ecma_number_is_nan (arg_num)))
{
ret_num = arg_num;
is_NaN = true;
}
else if (ecma_number_is_zero (arg_num) /* both numbers are zeroes */
&& ecma_number_is_zero (ret_num))
{
if (!ecma_number_is_negative (arg_num))
{
ret_num = arg_num;
}
}
else if (ecma_number_is_infinity (arg_num))
{
if (!ecma_number_is_negative (arg_num))
{
ret_num = arg_num;
}
}
else if (ecma_number_is_infinity (ret_num))
{
if (ecma_number_is_negative (ret_num))
{
ret_num = arg_num;
}
}
else
{
JERRY_ASSERT (!ecma_number_is_nan (arg_num)
&& !ecma_number_is_infinity (arg_num));
JERRY_ASSERT (!ecma_number_is_nan (ret_num)
&& !ecma_number_is_infinity (ret_num));
if (arg_num > ret_num)
{
ret_num = arg_num;
}
}
}
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
}
if (ecma_is_value_empty (ret_value))
{
ret_value = ecma_make_number_value (ret_num);
}
return ret_value;
} /* ecma_builtin_math_object_max */
/**
* The Math object's 'min' routine
*
* See also:
* ECMA-262 v5, 15.8.2.12
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_min (ecma_value_t this_arg, /**< 'this' argument */
const ecma_value_t args[], /**< arguments list */
ecma_length_t args_number) /**< number of arguments */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_number_t ret_num = ecma_number_make_infinity (false);
bool is_NaN = false;
for (ecma_length_t arg_index = 0;
arg_index < args_number && ecma_is_value_empty (ret_value);
arg_index++)
{
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, args[arg_index], ret_value);
if (!is_NaN)
{
if (unlikely (ecma_number_is_nan (arg_num)))
{
ret_num = arg_num;
is_NaN = true;
}
else if (ecma_number_is_zero (arg_num) /* both numbers are zeroes */
&& ecma_number_is_zero (ret_num))
{
if (ecma_number_is_negative (arg_num))
{
ret_num = arg_num;
}
}
else if (ecma_number_is_infinity (arg_num))
{
if (ecma_number_is_negative (arg_num))
{
ret_num = arg_num;
}
}
else if (ecma_number_is_infinity (ret_num))
{
if (!ecma_number_is_negative (ret_num))
{
ret_num = arg_num;
}
}
else
{
JERRY_ASSERT (!ecma_number_is_nan (arg_num)
&& !ecma_number_is_infinity (arg_num));
JERRY_ASSERT (!ecma_number_is_nan (ret_num)
&& !ecma_number_is_infinity (ret_num));
if (arg_num < ret_num)
{
ret_num = arg_num;
}
}
}
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
}
if (ecma_is_value_empty (ret_value))
{
ret_value = ecma_make_number_value (ret_num);
}
return ret_value;
} /* ecma_builtin_math_object_min */
/**
* The Math object's 'pow' routine
*
* See also:
* ECMA-262 v5, 15.8.2.13
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_pow (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg1, /**< first routine's argument */
ecma_value_t arg2) /**< second routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (x, arg1, ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (y, arg2, ret_value);
if (ecma_number_is_nan (y) ||
(ecma_number_is_infinity (y) && (x == 1.0 || x == -1.0)))
{
/* Handle differences between ES5.1 and ISO C standards for pow. */
ret_value = ecma_make_number_value (ecma_number_make_nan ());
}
else
{
ret_value = ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (pow (x, y)));
}
ECMA_OP_TO_NUMBER_FINALIZE (y);
ECMA_OP_TO_NUMBER_FINALIZE (x);
return ret_value;
} /* ecma_builtin_math_object_pow */
/**
* The Math object's 'random' routine
*
* See also:
* ECMA-262 v5, 15.8.2.14
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_random (ecma_value_t this_arg) /**< 'this' argument */
{
JERRY_UNUSED (this_arg);
uint32_t rnd = 1;
uint32_t reps_count;
#if RAND_MAX < 0x100
reps_count = 4;
#elif RAND_MAX < 0x10000
reps_count = 2;
#else /* RAND_MAX >= 0x10000 */
reps_count = 1;
#endif /* RAND_MAX < 0x100 */
for (uint32_t i = 0; i < reps_count; i++)
{
uint32_t next_rand = (uint32_t) rand ();
rnd *= next_rand;
}
const uint32_t max_uint32 = (uint32_t) -1;
ecma_number_t rand = (ecma_number_t) rnd;
rand /= (ecma_number_t) max_uint32;
rand *= (ecma_number_t) (max_uint32 - 1) / (ecma_number_t) max_uint32;
return ecma_make_number_value (rand);
} /* ecma_builtin_math_object_random */
/**
* The Math object's 'round' routine
*
* See also:
* ECMA-262 v5, 15.8.2.15
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_round (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ecma_number_t num = ECMA_NUMBER_ZERO;
if (ecma_number_is_nan (arg_num)
|| ecma_number_is_zero (arg_num)
|| ecma_number_is_infinity (arg_num))
{
num = arg_num;
}
else if (ecma_number_is_negative (arg_num)
&& arg_num >= -ECMA_NUMBER_HALF)
{
num = ecma_number_negate (ECMA_NUMBER_ZERO);
}
else
{
const ecma_number_t up_half = arg_num + ECMA_NUMBER_HALF;
const ecma_number_t down_half = arg_num - ECMA_NUMBER_HALF;
const ecma_number_t up_rounded = up_half - ecma_op_number_remainder (up_half, ECMA_NUMBER_ONE);
const ecma_number_t down_rounded = down_half - ecma_op_number_remainder (down_half, ECMA_NUMBER_ONE);
if (up_rounded - arg_num <= arg_num - down_rounded)
{
num = up_rounded;
}
else
{
num = down_rounded;
}
}
ret_value = ecma_make_number_value (num);
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_round */
/**
* The Math object's 'sin' routine
*
* See also:
* ECMA-262 v5, 15.8.2.16
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_sin (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ret_value = ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (sin (arg_num)));
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_sin */
/**
* The Math object's 'sqrt' routine
*
* See also:
* ECMA-262 v5, 15.8.2.17
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_sqrt (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ret_value = ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (sqrt (arg_num)));
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_sqrt */
/**
* The Math object's 'tan' routine
*
* See also:
* ECMA-262 v5, 15.8.2.18
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_tan (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ret_value = ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (tan (arg_num)));
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_tan */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_MATH_BUILTIN */

View file

@ -0,0 +1,112 @@
/* Copyright 2014 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.
*/
/*
* Math built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef SIMPLE_VALUE
# define SIMPLE_VALUE(name, simple_value, prop_attributes)
#endif /* !SIMPLE_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_MATH)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
// ECMA-262 v5, 15.8.1.1
NUMBER_VALUE (LIT_MAGIC_STRING_E_U,
ECMA_BUILTIN_NUMBER_E,
ECMA_PROPERTY_FIXED)
// ECMA-262 v5, 15.8.1.2
NUMBER_VALUE (LIT_MAGIC_STRING_LN10_U,
ECMA_BUILTIN_NUMBER_LN10,
ECMA_PROPERTY_FIXED)
// ECMA-262 v5, 15.8.1.3
NUMBER_VALUE (LIT_MAGIC_STRING_LN2_U,
ECMA_BUILTIN_NUMBER_LN2,
ECMA_PROPERTY_FIXED)
// ECMA-262 v5, 15.8.1.4
NUMBER_VALUE (LIT_MAGIC_STRING_LOG2E_U,
ECMA_BUILTIN_NUMBER_LOG2E,
ECMA_PROPERTY_FIXED)
// ECMA-262 v5, 15.8.1.5
NUMBER_VALUE (LIT_MAGIC_STRING_LOG10E_U,
ECMA_BUILTIN_NUMBER_LOG10E,
ECMA_PROPERTY_FIXED)
// ECMA-262 v5, 15.8.1.6
NUMBER_VALUE (LIT_MAGIC_STRING_PI_U,
ECMA_BUILTIN_NUMBER_PI,
ECMA_PROPERTY_FIXED)
// ECMA-262 v5, 15.8.1.7
NUMBER_VALUE (LIT_MAGIC_STRING_SQRT1_2_U,
ECMA_BUILTIN_NUMBER_SQRT_1_2,
ECMA_PROPERTY_FIXED)
// ECMA-262 v5, 15.8.1.8
NUMBER_VALUE (LIT_MAGIC_STRING_SQRT2_U,
ECMA_BUILTIN_NUMBER_SQRT2,
ECMA_PROPERTY_FIXED)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_ABS, ecma_builtin_math_object_abs, 1, 1)
ROUTINE (LIT_MAGIC_STRING_ACOS, ecma_builtin_math_object_acos, 1, 1)
ROUTINE (LIT_MAGIC_STRING_ASIN, ecma_builtin_math_object_asin, 1, 1)
ROUTINE (LIT_MAGIC_STRING_ATAN, ecma_builtin_math_object_atan, 1, 1)
ROUTINE (LIT_MAGIC_STRING_ATAN2, ecma_builtin_math_object_atan2, 2, 2)
ROUTINE (LIT_MAGIC_STRING_CEIL, ecma_builtin_math_object_ceil, 1, 1)
ROUTINE (LIT_MAGIC_STRING_COS, ecma_builtin_math_object_cos, 1, 1)
ROUTINE (LIT_MAGIC_STRING_EXP, ecma_builtin_math_object_exp, 1, 1)
ROUTINE (LIT_MAGIC_STRING_FLOOR, ecma_builtin_math_object_floor, 1, 1)
ROUTINE (LIT_MAGIC_STRING_LOG, ecma_builtin_math_object_log, 1, 1)
ROUTINE (LIT_MAGIC_STRING_MAX, ecma_builtin_math_object_max, NON_FIXED, 2)
ROUTINE (LIT_MAGIC_STRING_MIN, ecma_builtin_math_object_min, NON_FIXED, 2)
ROUTINE (LIT_MAGIC_STRING_POW, ecma_builtin_math_object_pow, 2, 2)
ROUTINE (LIT_MAGIC_STRING_RANDOM, ecma_builtin_math_object_random, 0, 0)
ROUTINE (LIT_MAGIC_STRING_ROUND, ecma_builtin_math_object_round, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SIN, ecma_builtin_math_object_sin, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SQRT, ecma_builtin_math_object_sqrt, 1, 1)
ROUTINE (LIT_MAGIC_STRING_TAN, ecma_builtin_math_object_tan, 1, 1)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,933 @@
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <math.h>
#include "ecma-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#include "jrt-libc-includes.h"
#ifndef CONFIG_DISABLE_NUMBER_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-number-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID number_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup numberprototype ECMA Number.prototype object built-in
* @{
*/
/**
* Helper for stringifying numbers
*
* @return the length of the generated string representation
*/
static lit_utf8_size_t
ecma_builtin_number_prototype_helper_to_string (lit_utf8_byte_t *digits_p, /**< number as string in decimal form */
lit_utf8_size_t num_digits, /**< length of the string representation */
int32_t exponent, /**< decimal exponent */
lit_utf8_byte_t *to_digits_p, /**< [out] buffer to write */
lit_utf8_size_t to_num_digits) /**< requested number of digits */
{
lit_utf8_byte_t *p = to_digits_p;
if (exponent <= 0)
{
/* Add zero to the integer part. */
*p++ = '0';
to_num_digits--;
if (to_num_digits > 0)
{
*p++ = '.';
/* Add leading zeros to the fraction part. */
for (int i = 0; i < -exponent && to_num_digits > 0; i++)
{
*p++ = '0';
to_num_digits--;
}
}
}
else
{
/* Add significant digits of the integer part. */
lit_utf8_size_t to_copy = JERRY_MIN (num_digits, to_num_digits);
to_copy = JERRY_MIN (to_copy, (lit_utf8_size_t) exponent);
memmove (p, digits_p, (size_t) to_copy);
p += to_copy;
to_num_digits -= to_copy;
digits_p += to_copy;
num_digits -= to_copy;
exponent -= (int32_t) to_copy;
/* Add zeros before decimal point. */
while (exponent > 0 && to_num_digits > 0)
{
JERRY_ASSERT (num_digits == 0);
*p++ = '0';
to_num_digits--;
exponent--;
}
if (to_num_digits > 0)
{
*p++ = '.';
}
}
if (to_num_digits > 0)
{
/* Add significant digits of the fraction part. */
lit_utf8_size_t to_copy = JERRY_MIN (num_digits, to_num_digits);
memmove (p, digits_p, (size_t) to_copy);
p += to_copy;
to_num_digits -= to_copy;
/* Add trailing zeros. */
while (to_num_digits > 0)
{
*p++ = '0';
to_num_digits--;
}
}
return (lit_utf8_size_t) (p - to_digits_p);
} /* ecma_builtin_number_prototype_helper_to_string */
/**
* Helper for rounding numbers
*
* @return rounded number
*/
static inline lit_utf8_size_t __attr_always_inline___
ecma_builtin_number_prototype_helper_round (lit_utf8_byte_t *digits_p, /**< [in,out] number as a string in decimal
* form */
lit_utf8_size_t num_digits, /**< length of the string representation */
int32_t round_num, /**< number of digits to keep */
int32_t *exponent_p) /**< [in, out] decimal exponent */
{
if (round_num < 1)
{
return 0;
}
if ((lit_utf8_size_t) round_num >= num_digits)
{
return num_digits;
}
if (digits_p[round_num] >= '5')
{
digits_p[round_num] = '0';
int i = 1;
/* Handle curry number. */
for (; i < (int) num_digits; i++)
{
if (++digits_p[round_num - i] <= '9')
{
break;
}
digits_p[round_num - i] = '0';
}
/* Prepend highest digit */
if (i >= (int) num_digits)
{
memmove (digits_p + 1, digits_p, num_digits);
digits_p[0] = '1';
*exponent_p += 1;
}
}
return (lit_utf8_size_t) round_num;
} /* ecma_builtin_number_prototype_helper_round */
/**
* The Number.prototype object's 'toString' routine
*
* See also:
* ECMA-262 v5, 15.7.4.2
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_number_prototype_object_to_string (ecma_value_t this_arg, /**< this argument */
const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_TRY_CATCH (this_value, ecma_builtin_number_prototype_object_value_of (this_arg), ret_value);
ecma_number_t this_arg_number = ecma_get_number_from_value (this_value);
if (arguments_list_len == 0
|| ecma_number_is_nan (this_arg_number)
|| ecma_number_is_infinity (this_arg_number)
|| ecma_number_is_zero (this_arg_number)
|| (arguments_list_len > 0 && ecma_is_value_undefined (arguments_list_p[0])))
{
ecma_string_t *ret_str_p = ecma_new_ecma_string_from_number (this_arg_number);
ret_value = ecma_make_string_value (ret_str_p);
}
else
{
static const lit_utf8_byte_t digit_chars[36] =
{
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'
};
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arguments_list_p[0], ret_value);
uint32_t radix = ecma_number_to_uint32 (arg_num);
if (radix < 2 || radix > 36)
{
ret_value = ecma_raise_range_error (ECMA_ERR_MSG (""));
}
else if (radix == 10)
{
ecma_string_t *ret_str_p = ecma_new_ecma_string_from_number (this_arg_number);
ret_value = ecma_make_string_value (ret_str_p);
}
else
{
bool is_negative = false;
if (ecma_number_is_negative (this_arg_number))
{
this_arg_number = -this_arg_number;
is_negative = true;
}
lit_utf8_byte_t digits[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
int32_t exponent;
lit_utf8_size_t num_digits = ecma_number_to_decimal (this_arg_number, digits, &exponent);
exponent = exponent - (int32_t) num_digits;
/* Calculate the scale of the number in the specified radix. */
int scale = (int) -floor ((log (10) / log (radix)) * exponent);
bool is_scale_negative = false;
if (scale < 0)
{
is_scale_negative = true;
scale = -scale;
}
int buff_size;
if (is_scale_negative)
{
buff_size = (int) floor (log (this_arg_number) / log (radix)) + 1;
}
else
{
buff_size = scale + ECMA_NUMBER_FRACTION_WIDTH + 2;
}
if (is_negative)
{
buff_size++;
}
/* Normalize the number, so that it is as close to 0 exponent as possible. */
if (is_scale_negative)
{
for (int i = 0; i < scale; i++)
{
this_arg_number /= (ecma_number_t) radix;
}
}
else
{
for (int i = 0; i < scale; i++)
{
this_arg_number *= (ecma_number_t) radix;
}
}
uint64_t whole = (uint64_t) this_arg_number;
ecma_number_t fraction = this_arg_number - (ecma_number_t) whole;
bool should_round = false;
if (!ecma_number_is_zero (fraction) && is_scale_negative)
{
/* Add one extra digit for rounding. */
buff_size++;
should_round = true;
}
JMEM_DEFINE_LOCAL_ARRAY (buff, buff_size, lit_utf8_byte_t);
int buff_index = 0;
/* Calculate digits for whole part. */
while (whole > 0)
{
buff[buff_index++] = (lit_utf8_byte_t) (whole % radix);
whole /= radix;
}
/* Calculate where we have to put the radix point. */
int point = is_scale_negative ? buff_index + scale : buff_index - scale;
/* Reverse the digits, since they are backwards. */
for (int i = 0; i < buff_index / 2; i++)
{
lit_utf8_byte_t swap = buff[i];
buff[i] = buff[buff_index - i - 1];
buff[buff_index - i - 1] = swap;
}
int required_digits = buff_size;
if (is_negative)
{
required_digits--;
}
if (!is_scale_negative)
{
/* Leave space for leading zeros / radix point. */
required_digits -= scale + 1;
}
/* Calculate digits for fractional part. */
while (buff_index < required_digits && (fraction != 0 || is_scale_negative))
{
fraction *= (ecma_number_t) radix;
lit_utf8_byte_t digit = (lit_utf8_byte_t) floor (fraction);
buff[buff_index++] = digit;
fraction -= (ecma_number_t) floor (fraction);
}
if (should_round)
{
/* Round off last digit. */
if (buff[buff_index - 1] > radix / 2)
{
buff[buff_index - 2]++;
}
buff_index--;
/* Propagate carry. */
for (int i = buff_index - 1; i > 0 && buff[i] >= radix; i--)
{
buff[i] = (lit_utf8_byte_t) (buff[i] - radix);
buff[i - 1]++;
}
/* Carry propagated over the whole number, need to add a leading digit. */
if (buff[0] >= radix)
{
memmove (buff + 1, buff, (size_t) buff_index);
buff_index++;
buff[0] = 1;
}
}
/* Remove trailing zeros from fraction. */
while (buff_index - 1 > point && buff[buff_index - 1] == 0)
{
buff_index--;
}
/* Add leading zeros in case place of radix point is negative. */
if (point <= 0)
{
memmove (buff - point + 1, buff, (size_t) buff_index);
buff_index += -point + 1;
for (int i = 0; i < -point + 1; i++)
{
buff[i] = 0;
}
point = 1;
}
/* Convert digits to characters. */
for (int i = 0; i < buff_index; i++)
{
buff[i] = digit_chars[buff[i]];
}
/* Place radix point to the required position. */
if (point < buff_index)
{
memmove (buff + point + 1, buff + point, (size_t) buff_index);
buff[point] = '.';
buff_index++;
}
/* Add negative sign if necessary. */
if (is_negative)
{
memmove (buff + 1, buff, (size_t) buff_index);
buff_index++;
buff[0] = '-';
}
JERRY_ASSERT (buff_index <= buff_size);
ecma_string_t *str_p = ecma_new_ecma_string_from_utf8 (buff, (lit_utf8_size_t) buff_index);
ret_value = ecma_make_string_value (str_p);
JMEM_FINALIZE_LOCAL_ARRAY (buff);
}
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
}
ECMA_FINALIZE (this_value);
return ret_value;
} /* ecma_builtin_number_prototype_object_to_string */
/**
* The Number.prototype object's 'toLocaleString' routine
*
* See also:
* ECMA-262 v5, 15.7.4.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_number_prototype_object_to_locale_string (ecma_value_t this_arg) /**< this argument */
{
return ecma_builtin_number_prototype_object_to_string (this_arg, NULL, 0);
} /* ecma_builtin_number_prototype_object_to_locale_string */
/**
* The Number.prototype object's 'valueOf' routine
*
* See also:
* ECMA-262 v5, 15.7.4.4
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_number_prototype_object_value_of (ecma_value_t this_arg) /**< this argument */
{
if (ecma_is_value_number (this_arg))
{
return ecma_copy_value (this_arg);
}
else if (ecma_is_value_object (this_arg))
{
ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_NUMBER_UL)
{
ecma_value_t *prim_value_p = ecma_get_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
JERRY_ASSERT (ecma_is_value_number (*prim_value_p));
return ecma_copy_value (*prim_value_p);
}
}
return ecma_raise_type_error (ECMA_ERR_MSG (""));
} /* ecma_builtin_number_prototype_object_value_of */
/**
* The Number.prototype object's 'toFixed' routine
*
* See also:
* ECMA-262 v5, 15.7.4.5
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_number_prototype_object_to_fixed (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg) /**< routine's argument */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_TRY_CATCH (this_value, ecma_builtin_number_prototype_object_value_of (this_arg), ret_value);
ecma_number_t this_num = ecma_get_number_from_value (this_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
/* 2. */
if (arg_num <= -1 || arg_num >= 21)
{
ret_value = ecma_raise_range_error (ECMA_ERR_MSG (""));
}
else
{
/* 4. */
if (ecma_number_is_nan (this_num))
{
ecma_string_t *nan_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_NAN);
ret_value = ecma_make_string_value (nan_str_p);
}
else
{
/* 6. */
bool is_negative = false;
if (ecma_number_is_negative (this_num))
{
is_negative = true;
this_num *= -1;
}
/* We handle infinities separately. */
if (ecma_number_is_infinity (this_num))
{
ecma_string_t *infinity_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INFINITY_UL);
if (is_negative)
{
ecma_string_t *neg_str_p = ecma_new_ecma_string_from_utf8 ((const lit_utf8_byte_t *) "-", 1);
ecma_string_t *neg_inf_str_p = ecma_concat_ecma_strings (neg_str_p, infinity_str_p);
ecma_deref_ecma_string (infinity_str_p);
ecma_deref_ecma_string (neg_str_p);
ret_value = ecma_make_string_value (neg_inf_str_p);
}
else
{
ret_value = ecma_make_string_value (infinity_str_p);
}
}
else
{
/* Get the parameters of the number if non-zero. */
lit_utf8_byte_t digits[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
lit_utf8_size_t num_digits;
int32_t exponent;
if (!ecma_number_is_zero (this_num))
{
num_digits = ecma_number_to_decimal (this_num, digits, &exponent);
}
else
{
digits[0] = '0';
num_digits = 1;
exponent = 1;
}
/* 7. */
if (exponent > 21)
{
ret_value = ecma_builtin_number_prototype_object_to_string (this_arg, NULL, 0);
}
/* 8. */
else
{
/* 1. */
int32_t frac_digits = ecma_number_to_int32 (arg_num);
num_digits = ecma_builtin_number_prototype_helper_round (digits,
num_digits,
exponent + frac_digits,
&exponent);
/* Buffer that is used to construct the string. */
int buffer_size = (exponent > 0) ? exponent + frac_digits + 2 : frac_digits + 3;
if (is_negative)
{
buffer_size++;
}
JERRY_ASSERT (buffer_size > 0);
JMEM_DEFINE_LOCAL_ARRAY (buff, buffer_size, lit_utf8_byte_t);
lit_utf8_byte_t *p = buff;
if (is_negative)
{
*p++ = '-';
}
lit_utf8_size_t to_num_digits = ((exponent > 0) ? (lit_utf8_size_t) (exponent + frac_digits)
: (lit_utf8_size_t) (frac_digits + 1));
p += ecma_builtin_number_prototype_helper_to_string (digits,
num_digits,
exponent,
p,
to_num_digits);
JERRY_ASSERT (p - buff < buffer_size);
/* String terminator. */
*p = 0;
ecma_string_t *str = ecma_new_ecma_string_from_utf8 (buff, (lit_utf8_size_t) (p - buff));
ret_value = ecma_make_string_value (str);
JMEM_FINALIZE_LOCAL_ARRAY (buff);
}
}
}
}
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
ECMA_FINALIZE (this_value);
return ret_value;
} /* ecma_builtin_number_prototype_object_to_fixed */
/**
* The Number.prototype object's 'toExponential' routine
*
* See also:
* ECMA-262 v5, 15.7.4.6
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_number_prototype_object_to_exponential (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg) /**< routine's argument */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
/* 1. */
ECMA_TRY_CATCH (this_value, ecma_builtin_number_prototype_object_value_of (this_arg), ret_value);
ecma_number_t this_num = ecma_get_number_from_value (this_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
/* 7. */
if (arg_num <= -1.0 || arg_num >= 21.0)
{
ret_value = ecma_raise_range_error (ECMA_ERR_MSG (""));
}
else
{
/* 3. */
if (ecma_number_is_nan (this_num))
{
ecma_string_t *nan_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_NAN);
ret_value = ecma_make_string_value (nan_str_p);
}
else
{
/* 5. */
bool is_negative = false;
if (ecma_number_is_negative (this_num) && !ecma_number_is_zero (this_num))
{
is_negative = true;
this_num *= -1;
}
/* 6. */
if (ecma_number_is_infinity (this_num))
{
ecma_string_t *infinity_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INFINITY_UL);
if (is_negative)
{
ecma_string_t *neg_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_MINUS_CHAR);
ecma_string_t *neg_inf_str_p = ecma_concat_ecma_strings (neg_str_p, infinity_str_p);
ecma_deref_ecma_string (infinity_str_p);
ecma_deref_ecma_string (neg_str_p);
ret_value = ecma_make_string_value (neg_inf_str_p);
}
else
{
ret_value = ecma_make_string_value (infinity_str_p);
}
}
else
{
/* Get the parameters of the number if non zero. */
lit_utf8_byte_t digits[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
lit_utf8_size_t num_digits;
int32_t exponent;
if (!ecma_number_is_zero (this_num))
{
num_digits = ecma_number_to_decimal (this_num, digits, &exponent);
}
else
{
digits[0] = '0';
num_digits = 1;
exponent = 1;
}
int32_t frac_digits;
if (ecma_is_value_undefined (arg))
{
frac_digits = (int32_t) num_digits - 1;
}
else
{
frac_digits = ecma_number_to_int32 (arg_num);
}
num_digits = ecma_builtin_number_prototype_helper_round (digits, num_digits, frac_digits + 1, &exponent);
/* frac_digits + 2 characters for number, 5 characters for exponent, 1 for \0. */
int buffer_size = frac_digits + 2 + 5 + 1;
if (is_negative)
{
/* +1 character for sign. */
buffer_size++;
}
JMEM_DEFINE_LOCAL_ARRAY (buff, buffer_size, lit_utf8_byte_t);
lit_utf8_byte_t *actual_char_p = buff;
if (is_negative)
{
*actual_char_p++ = '-';
}
actual_char_p += ecma_builtin_number_prototype_helper_to_string (digits,
num_digits,
1,
actual_char_p,
(lit_utf8_size_t) (frac_digits + 1));
*actual_char_p++ = 'e';
exponent--;
if (exponent < 0)
{
exponent *= -1;
*actual_char_p++ = '-';
}
else
{
*actual_char_p++ = '+';
}
/* Add exponent digits. */
actual_char_p += ecma_uint32_to_utf8_string ((uint32_t) exponent, actual_char_p, 3);
JERRY_ASSERT (actual_char_p - buff < buffer_size);
*actual_char_p = '\0';
ecma_string_t *str = ecma_new_ecma_string_from_utf8 (buff, (lit_utf8_size_t) (actual_char_p - buff));
ret_value = ecma_make_string_value (str);
JMEM_FINALIZE_LOCAL_ARRAY (buff);
}
}
}
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
ECMA_FINALIZE (this_value);
return ret_value;
} /* ecma_builtin_number_prototype_object_to_exponential */
/**
* The Number.prototype object's 'toPrecision' routine
*
* See also:
* ECMA-262 v5, 15.7.4.7
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_number_prototype_object_to_precision (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg) /**< routine's argument */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
/* 1. */
ECMA_TRY_CATCH (this_value, ecma_builtin_number_prototype_object_value_of (this_arg), ret_value);
ecma_number_t this_num = ecma_get_number_from_value (this_value);
/* 2. */
if (ecma_is_value_undefined (arg))
{
ret_value = ecma_builtin_number_prototype_object_to_string (this_arg, NULL, 0);
}
else
{
/* 3. */
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
/* 4. */
if (ecma_number_is_nan (this_num))
{
ecma_string_t *nan_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_NAN);
ret_value = ecma_make_string_value (nan_str_p);
}
else
{
/* 6. */
bool is_negative = false;
if (ecma_number_is_negative (this_num) && !ecma_number_is_zero (this_num))
{
is_negative = true;
this_num *= -1;
}
/* 7. */
if (ecma_number_is_infinity (this_num))
{
ecma_string_t *infinity_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INFINITY_UL);
if (is_negative)
{
ecma_string_t *neg_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_MINUS_CHAR);
ecma_string_t *neg_inf_str_p = ecma_concat_ecma_strings (neg_str_p, infinity_str_p);
ecma_deref_ecma_string (infinity_str_p);
ecma_deref_ecma_string (neg_str_p);
ret_value = ecma_make_string_value (neg_inf_str_p);
}
else
{
ret_value = ecma_make_string_value (infinity_str_p);
}
}
/* 8. */
else if (arg_num < 1.0 || arg_num >= 22.0)
{
ret_value = ecma_raise_range_error (ECMA_ERR_MSG (""));
}
else
{
/* Get the parameters of the number if non-zero. */
lit_utf8_byte_t digits[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
lit_utf8_size_t num_digits;
int32_t exponent;
if (!ecma_number_is_zero (this_num))
{
num_digits = ecma_number_to_decimal (this_num, digits, &exponent);
}
else
{
digits[0] = '0';
num_digits = 1;
exponent = 1;
}
int32_t precision = ecma_number_to_int32 (arg_num);
num_digits = ecma_builtin_number_prototype_helper_round (digits, num_digits, precision, &exponent);
int buffer_size;
if (exponent < -5 || exponent > precision)
{
/* Exponential notation, precision + 1 digits for number, 5 for exponent, 1 for \0 */
buffer_size = precision + 1 + 5 + 1;
}
else if (exponent <= 0)
{
/* Fixed notation, -exponent + 2 digits for leading zeros, precision digits, 1 for \0 */
buffer_size = -exponent + 2 + precision + 1;
}
else
{
/* Fixed notation, precision + 1 digits for number, 1 for \0 */
buffer_size = precision + 1 + 1;
}
if (is_negative)
{
buffer_size++;
}
JMEM_DEFINE_LOCAL_ARRAY (buff, buffer_size, lit_utf8_byte_t);
lit_utf8_byte_t *actual_char_p = buff;
if (is_negative)
{
*actual_char_p++ = '-';
}
/* 10.c, Exponential notation.*/
if (exponent < -5 || exponent > precision)
{
actual_char_p += ecma_builtin_number_prototype_helper_to_string (digits,
num_digits,
1,
actual_char_p,
(lit_utf8_size_t) precision);
*actual_char_p++ = 'e';
exponent--;
if (exponent < 0)
{
exponent *= -1;
*actual_char_p++ = '-';
}
else
{
*actual_char_p++ = '+';
}
/* Add exponent digits. */
actual_char_p += ecma_uint32_to_utf8_string ((uint32_t) exponent, actual_char_p, 3);
}
/* Fixed notation. */
else
{
lit_utf8_size_t to_num_digits = ((exponent <= 0) ? (lit_utf8_size_t) (1 - exponent + precision)
: (lit_utf8_size_t) precision);
actual_char_p += ecma_builtin_number_prototype_helper_to_string (digits,
num_digits,
exponent,
actual_char_p,
to_num_digits);
}
JERRY_ASSERT (actual_char_p - buff < buffer_size);
*actual_char_p = '\0';
ecma_string_t *str_p = ecma_new_ecma_string_from_utf8 (buff, (lit_utf8_size_t) (actual_char_p - buff));
ret_value = ecma_make_string_value (str_p);
JMEM_FINALIZE_LOCAL_ARRAY (buff);
}
}
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
}
ECMA_FINALIZE (this_value);
return ret_value;
} /* ecma_builtin_number_prototype_object_to_precision */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_NUMBER_BUILTIN */

View file

@ -0,0 +1,57 @@
/* 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.
*/
/*
* Number.prototype built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_NUMBER_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
// 15.7.4.1
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_NUMBER,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_number_prototype_object_to_string, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_VALUE_OF_UL, ecma_builtin_number_prototype_object_value_of, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_STRING_UL, ecma_builtin_number_prototype_object_to_locale_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_FIXED_UL, ecma_builtin_number_prototype_object_to_fixed, 1, 1)
ROUTINE (LIT_MAGIC_STRING_TO_EXPONENTIAL_UL, ecma_builtin_number_prototype_object_to_exponential, 1, 1)
ROUTINE (LIT_MAGIC_STRING_TO_PRECISION_UL, ecma_builtin_number_prototype_object_to_precision, 1, 1)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,100 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.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-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_NUMBER_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-number.inc.h"
#define BUILTIN_UNDERSCORED_ID number
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup number ECMA Number object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in Number object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_number_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (arguments_list_len == 0)
{
ret_value = ecma_make_integer_value (0);
}
else
{
ret_value = ecma_op_to_number (arguments_list_p[0]);
}
return ret_value;
} /* ecma_builtin_number_dispatch_call */
/**
* Handle calling [[Construct]] of built-in Number object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_number_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
if (arguments_list_len == 0)
{
ecma_value_t completion = ecma_op_create_number_object (ecma_make_integer_value (0));
return completion;
}
else
{
return ecma_op_create_number_object (arguments_list_p[0]);
}
} /* ecma_builtin_number_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_NUMBER_BUILTIN */

View file

@ -0,0 +1,81 @@
/* 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.
*/
/*
* Number built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_NUMBER)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
// 15.7.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
// 15.7.3.4
NUMBER_VALUE (LIT_MAGIC_STRING_NAN,
ECMA_BUILTIN_NUMBER_NAN,
ECMA_PROPERTY_FIXED)
// 15.7.3.2
NUMBER_VALUE (LIT_MAGIC_STRING_MAX_VALUE_U,
ECMA_BUILTIN_NUMBER_MAX,
ECMA_PROPERTY_FIXED)
// 15.7.3.3
NUMBER_VALUE (LIT_MAGIC_STRING_MIN_VALUE_U,
ECMA_BUILTIN_NUMBER_MIN,
ECMA_PROPERTY_FIXED)
// 15.7.3.5
NUMBER_VALUE (LIT_MAGIC_STRING_POSITIVE_INFINITY_U,
ECMA_BUILTIN_NUMBER_POSITIVE_INFINITY,
ECMA_PROPERTY_FIXED)
// 15.7.3.6
NUMBER_VALUE (LIT_MAGIC_STRING_NEGATIVE_INFINITY_U,
ECMA_BUILTIN_NUMBER_NEGATIVE_INFINITY,
ECMA_PROPERTY_FIXED)
/* Object properties:
* (property name, object pointer getter) */
// 15.7.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_NUMBER_PROTOTYPE,
ECMA_PROPERTY_FIXED)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,273 @@
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-alloc.h"
#include "ecma-builtin-helpers.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-function-object.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-object-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID object_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup objectprototype ECMA Object.prototype object built-in
* @{
*/
/**
* The Object.prototype object's 'toString' routine
*
* See also:
* ECMA-262 v5, 15.2.4.2
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */
{
return ecma_builtin_helper_object_to_string (this_arg);
} /* ecma_builtin_object_prototype_object_to_string */
/**
* The Object.prototype object's 'valueOf' routine
*
* See also:
* ECMA-262 v5, 15.2.4.4
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_prototype_object_value_of (ecma_value_t this_arg) /**< this argument */
{
return ecma_op_to_object (this_arg);
} /* ecma_builtin_object_prototype_object_value_of */
/**
* The Object.prototype object's 'toLocaleString' routine
*
* See also:
* ECMA-262 v5, 15.2.4.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_prototype_object_to_locale_string (ecma_value_t this_arg) /**< this argument */
{
ecma_value_t return_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
/* 1. */
ECMA_TRY_CATCH (obj_val,
ecma_op_to_object (this_arg),
return_value);
ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
ecma_string_t *to_string_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_TO_STRING_UL);
/* 2. */
ECMA_TRY_CATCH (to_string_val,
ecma_op_object_get (obj_p, to_string_magic_string_p),
return_value);
/* 3. */
if (!ecma_op_is_callable (to_string_val))
{
return_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
/* 4. */
ecma_object_t *to_string_func_obj_p = ecma_get_object_from_value (to_string_val);
return_value = ecma_op_function_call (to_string_func_obj_p, this_arg, NULL, 0);
}
ECMA_FINALIZE (to_string_val);
ecma_deref_ecma_string (to_string_magic_string_p);
ECMA_FINALIZE (obj_val);
return return_value;
} /* ecma_builtin_object_prototype_object_to_locale_string */
/**
* The Object.prototype object's 'hasOwnProperty' routine
*
* See also:
* ECMA-262 v5, 15.2.4.5
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_prototype_object_has_own_property (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg) /**< first argument */
{
ecma_value_t return_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
/* 1. */
ECMA_TRY_CATCH (to_string_val,
ecma_op_to_string (arg),
return_value);
/* 2. */
ECMA_TRY_CATCH (obj_val,
ecma_op_to_object (this_arg),
return_value);
ecma_string_t *property_name_string_p = ecma_get_string_from_value (to_string_val);
ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
/* 3. */
if (ecma_op_object_has_own_property (obj_p, property_name_string_p))
{
return_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
}
else
{
return_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
}
ECMA_FINALIZE (obj_val);
ECMA_FINALIZE (to_string_val);
return return_value;
} /* ecma_builtin_object_prototype_object_has_own_property */
/**
* The Object.prototype object's 'isPrototypeOf' routine
*
* See also:
* ECMA-262 v5, 15.2.4.6
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_prototype_object_is_prototype_of (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg) /**< routine's first argument */
{
/* 1. Is the argument an object? */
if (!ecma_is_value_object (arg))
{
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
}
ecma_value_t return_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
/* 2. ToObject(this) */
ECMA_TRY_CATCH (obj_value,
ecma_op_to_object (this_arg),
return_value);
ecma_object_t *obj_p = ecma_get_object_from_value (obj_value);
/* 3. Compare prototype to object */
ECMA_TRY_CATCH (v_obj_value,
ecma_op_to_object (arg),
return_value);
ecma_object_t *v_obj_p = ecma_get_object_from_value (v_obj_value);
bool is_prototype_of = ecma_op_object_is_prototype_of (obj_p, v_obj_p);
return_value = ecma_make_simple_value (is_prototype_of ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE);
ECMA_FINALIZE (v_obj_value);
ECMA_FINALIZE (obj_value);
return return_value;
} /* ecma_builtin_object_prototype_object_is_prototype_of */
/**
* The Object.prototype object's 'propertyIsEnumerable' routine
*
* See also:
* ECMA-262 v5, 15.2.4.7
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_prototype_object_property_is_enumerable (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg) /**< routine's first argument */
{
ecma_value_t return_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
/* 1. */
ECMA_TRY_CATCH (to_string_val,
ecma_op_to_string (arg),
return_value);
/* 2. */
ECMA_TRY_CATCH (obj_val,
ecma_op_to_object (this_arg),
return_value);
ecma_string_t *property_name_string_p = ecma_get_string_from_value (to_string_val);
ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
/* 3. */
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
property_name_string_p,
NULL,
ECMA_PROPERTY_GET_NO_OPTIONS);
/* 4. */
if (property != ECMA_PROPERTY_TYPE_NOT_FOUND)
{
bool is_enumerable = ecma_is_property_enumerable (property);
return_value = ecma_make_boolean_value (is_enumerable);
}
else
{
return_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
}
ECMA_FINALIZE (obj_val);
ECMA_FINALIZE (to_string_val);
return return_value;
} /* ecma_builtin_object_prototype_object_property_is_enumerable */
/**
* @}
* @}
* @}
*/

View file

@ -0,0 +1,57 @@
/* 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.
*/
/*
* Object.prototype built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
// 15.2.4.1
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_OBJECT,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_object_prototype_object_to_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_VALUE_OF_UL, ecma_builtin_object_prototype_object_value_of, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_STRING_UL, ecma_builtin_object_prototype_object_to_locale_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_HAS_OWN_PROPERTY_UL, ecma_builtin_object_prototype_object_has_own_property, 1, 1)
ROUTINE (LIT_MAGIC_STRING_IS_PROTOTYPE_OF_UL, ecma_builtin_object_prototype_object_is_prototype_of, 1, 1)
ROUTINE (LIT_MAGIC_STRING_PROPERTY_IS_ENUMERABLE_UL, ecma_builtin_object_prototype_object_property_is_enumerable, 1, 1)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,848 @@
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-alloc.h"
#include "ecma-array-object.h"
#include "ecma-builtin-helpers.h"
#include "ecma-builtins.h"
#include "ecma-conversion.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-try-catch-macro.h"
#include "jrt.h"
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-object.inc.h"
#define BUILTIN_UNDERSCORED_ID object
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup object ECMA Object object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in Object object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_object_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (arguments_list_len == 0
|| ecma_is_value_undefined (arguments_list_p[0])
|| ecma_is_value_null (arguments_list_p[0]))
{
ret_value = ecma_builtin_object_dispatch_construct (arguments_list_p, arguments_list_len);
}
else
{
ret_value = ecma_op_to_object (arguments_list_p[0]);
}
return ret_value;
} /* ecma_builtin_object_dispatch_call */
/**
* Handle calling [[Construct]] of built-in Object object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_object_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
if (arguments_list_len == 0)
{
ecma_object_t *obj_p = ecma_op_create_object_object_noarg ();
return ecma_make_object_value (obj_p);
}
else
{
return ecma_op_create_object_object_arg (arguments_list_p[0]);
}
} /* ecma_builtin_object_dispatch_construct */
/**
* The Object object's 'getPrototypeOf' routine
*
* See also:
* ECMA-262 v5, 15.2.3.2
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_object_get_prototype_of (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
/* 1. */
if (!ecma_is_value_object (arg))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
/* 2. */
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
ecma_object_t *prototype_p = ecma_get_object_prototype (obj_p);
if (prototype_p)
{
ret_value = ecma_make_object_value (prototype_p);
ecma_ref_object (prototype_p);
}
else
{
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_NULL);
}
}
return ret_value;
} /* ecma_builtin_object_object_get_prototype_of */
/**
* The Object object's 'getOwnPropertyNames' routine
*
* See also:
* ECMA-262 v5, 15.2.3.4
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_object_get_own_property_names (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (!ecma_is_value_object (arg))
{
/* 1. */
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
/* 2-5. */
ret_value = ecma_builtin_helper_object_get_properties (obj_p, false);
}
return ret_value;
} /* ecma_builtin_object_object_get_own_property_names */
/**
* The Object object's 'seal' routine
*
* See also:
* ECMA-262 v5, 15.2.3.8
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_object_seal (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
// 1.
if (!ecma_is_value_object (arg))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
// 2.
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, false, false);
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
while (ecma_collection_iterator_next (&iter)
&& ecma_is_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
// 2.a
ecma_property_descriptor_t prop_desc;
if (!ecma_op_object_get_own_property_descriptor (obj_p, property_name_p, &prop_desc))
{
continue;
}
// 2.b
prop_desc.is_configurable = false;
// 2.c
ECMA_TRY_CATCH (define_own_prop_ret,
ecma_op_object_define_own_property (obj_p,
property_name_p,
&prop_desc,
true),
ret_value);
ECMA_FINALIZE (define_own_prop_ret);
ecma_free_property_descriptor (&prop_desc);
}
ecma_free_values_collection (props_p, true);
if (ecma_is_value_empty (ret_value))
{
// 3.
ecma_set_object_extensible (obj_p, false);
// 4.
ret_value = ecma_copy_value (arg);
}
}
return ret_value;
} /* ecma_builtin_object_object_seal */
/**
* The Object object's 'freeze' routine
*
* See also:
* ECMA-262 v5, 15.2.3.9
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_object_freeze (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
// 1.
if (!ecma_is_value_object (arg))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
// 2.
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, false, false);
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
while (ecma_collection_iterator_next (&iter)
&& ecma_is_value_empty (ret_value))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
// 2.a
ecma_property_descriptor_t prop_desc;
if (!ecma_op_object_get_own_property_descriptor (obj_p, property_name_p, &prop_desc))
{
continue;
}
// 2.b
if (prop_desc.is_writable_defined && prop_desc.is_writable)
{
prop_desc.is_writable = false;
}
// 2.c
prop_desc.is_configurable = false;
// 2.d
ECMA_TRY_CATCH (define_own_prop_ret,
ecma_op_object_define_own_property (obj_p,
property_name_p,
&prop_desc,
true),
ret_value);
ECMA_FINALIZE (define_own_prop_ret);
ecma_free_property_descriptor (&prop_desc);
}
ecma_free_values_collection (props_p, true);
if (ecma_is_value_empty (ret_value))
{
// 3.
ecma_set_object_extensible (obj_p, false);
// 4.
ret_value = ecma_copy_value (arg);
}
}
return ret_value;
} /* ecma_builtin_object_object_freeze */
/**
* The Object object's 'preventExtensions' routine
*
* See also:
* ECMA-262 v5, 15.2.3.10
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_object_prevent_extensions (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (!ecma_is_value_object (arg))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
ecma_set_object_extensible (obj_p, false);
ret_value = ecma_copy_value (arg);
}
return ret_value;
} /* ecma_builtin_object_object_prevent_extensions */
/**
* The Object object's 'isSealed' routine
*
* See also:
* ECMA-262 v5, 15.2.3.11
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_object_is_sealed (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
// 1.
if (!ecma_is_value_object (arg))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
bool is_sealed;
// 3.
if (ecma_get_object_extensible (obj_p))
{
is_sealed = false;
}
else
{
/* the value can be updated in the loop below */
is_sealed = true;
// 2.
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, false, false);
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
while (ecma_collection_iterator_next (&iter))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
// 2.a
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
property_name_p,
NULL,
ECMA_PROPERTY_GET_NO_OPTIONS);
// 2.b
if (ecma_is_property_configurable (property))
{
is_sealed = false;
break;
}
}
ecma_free_values_collection (props_p, true);
}
// 4.
ret_value = ecma_make_simple_value (is_sealed ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE);
}
return ret_value;
} /* ecma_builtin_object_object_is_sealed */
/**
* The Object object's 'isFrozen' routine
*
* See also:
* ECMA-262 v5, 15.2.3.12
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_object_is_frozen (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
// 1.
if (!ecma_is_value_object (arg))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
bool is_frozen;
// 3.
if (ecma_get_object_extensible (obj_p))
{
is_frozen = false;
}
else
{
is_frozen = true;
// 2.
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, false, false);
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, props_p);
while (ecma_collection_iterator_next (&iter))
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
// 2.a
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
property_name_p,
NULL,
ECMA_PROPERTY_GET_NO_OPTIONS);
// 2.b
if (ECMA_PROPERTY_GET_TYPE (property) != ECMA_PROPERTY_TYPE_NAMEDACCESSOR
&& ecma_is_property_writable (property))
{
is_frozen = false;
break;
}
// 2.c
if (ecma_is_property_configurable (property))
{
is_frozen = false;
break;
}
}
ecma_free_values_collection (props_p, true);
}
// 4.
ret_value = ecma_make_simple_value (is_frozen ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE);
}
return ret_value;
} /* ecma_builtin_object_object_is_frozen */
/**
* The Object object's 'isExtensible' routine
*
* See also:
* ECMA-262 v5, 15.2.3.13
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_object_is_extensible (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (!ecma_is_value_object (arg))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
bool extensible = ecma_get_object_extensible (obj_p);
ret_value = ecma_make_simple_value (extensible ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE);
}
return ret_value;
} /* ecma_builtin_object_object_is_extensible */
/**
* The Object object's 'keys' routine
*
* See also:
* ECMA-262 v5, 15.2.3.14
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_object_keys (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (!ecma_is_value_object (arg))
{
/* 1. */
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
/* 3-6. */
ret_value = ecma_builtin_helper_object_get_properties (obj_p, true);
}
return ret_value;
} /* ecma_builtin_object_object_keys */
/**
* The Object object's 'getOwnPropertyDescriptor' routine
*
* See also:
* ECMA-262 v5, 15.2.3.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_object_get_own_property_descriptor (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg1, /**< routine's first argument */
ecma_value_t arg2) /**< routine's second argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
// 1.
if (!ecma_is_value_object (arg1))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
return ret_value;
}
ecma_object_t *obj_p = ecma_get_object_from_value (arg1);
// 2.
ECMA_TRY_CATCH (name_str_value,
ecma_op_to_string (arg2),
ret_value);
ecma_string_t *name_str_p = ecma_get_string_from_value (name_str_value);
// 3.
ecma_property_descriptor_t prop_desc;
if (ecma_op_object_get_own_property_descriptor (obj_p, name_str_p, &prop_desc))
{
// 4.
ecma_object_t *desc_obj_p = ecma_op_from_property_descriptor (&prop_desc);
ecma_free_property_descriptor (&prop_desc);
ret_value = ecma_make_object_value (desc_obj_p);
}
else
{
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
}
ECMA_FINALIZE (name_str_value);
return ret_value;
} /* ecma_builtin_object_object_get_own_property_descriptor */
/**
* The Object object's 'create' routine
*
* See also:
* ECMA-262 v5, 15.2.3.5
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_object_create (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg1, /**< routine's first argument */
ecma_value_t arg2) /**< routine's second argument */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
// 1.
if (!ecma_is_value_object (arg1) && !ecma_is_value_null (arg1))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_object_t *obj_p = NULL;
if (!ecma_is_value_null (arg1))
{
obj_p = ecma_get_object_from_value (arg1);
}
// 2-3.
ecma_object_t *result_obj_p = ecma_op_create_object_object_noarg_and_set_prototype (obj_p);
// 4.
if (!ecma_is_value_undefined (arg2))
{
ECMA_TRY_CATCH (obj,
ecma_builtin_object_object_define_properties (this_arg,
ecma_make_object_value (result_obj_p),
arg2),
ret_value);
ECMA_FINALIZE (obj);
}
// 5.
if (ecma_is_value_empty (ret_value))
{
ret_value = ecma_copy_value (ecma_make_object_value (result_obj_p));
}
ecma_deref_object (result_obj_p);
}
return ret_value;
} /* ecma_builtin_object_object_create */
/**
* The Object object's 'defineProperties' routine
*
* See also:
* ECMA-262 v5, 15.2.3.7
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_object_define_properties (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg1, /**< routine's first argument */
ecma_value_t arg2) /**< routine's second argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
// 1.
if (!ecma_is_value_object (arg1))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_object_t *obj_p = ecma_get_object_from_value (arg1);
// 2.
ECMA_TRY_CATCH (props,
ecma_op_to_object (arg2),
ret_value);
ecma_object_t *props_p = ecma_get_object_from_value (props);
// 3.
ecma_collection_header_t *prop_names_p = ecma_op_object_get_property_names (props_p, false, true, false);
uint32_t property_number = prop_names_p->unit_number;
ecma_collection_iterator_t iter;
ecma_collection_iterator_init (&iter, prop_names_p);
// 4.
JMEM_DEFINE_LOCAL_ARRAY (property_descriptors, property_number, ecma_property_descriptor_t);
uint32_t property_descriptor_number = 0;
while (ecma_collection_iterator_next (&iter)
&& ecma_is_value_empty (ret_value))
{
// 5.a
ECMA_TRY_CATCH (desc_obj,
ecma_op_object_get (props_p, ecma_get_string_from_value (*iter.current_value_p)),
ret_value);
// 5.b
ECMA_TRY_CATCH (conv_result,
ecma_op_to_property_descriptor (desc_obj,
&property_descriptors[property_descriptor_number]),
ret_value);
property_descriptor_number++;
ECMA_FINALIZE (conv_result);
ECMA_FINALIZE (desc_obj);
}
// 6.
ecma_collection_iterator_init (&iter, prop_names_p);
for (uint32_t index = 0;
index < property_number && ecma_is_value_empty (ret_value);
index++)
{
bool is_next = ecma_collection_iterator_next (&iter);
JERRY_ASSERT (is_next);
ECMA_TRY_CATCH (define_own_prop_ret,
ecma_op_object_define_own_property (obj_p,
ecma_get_string_from_value (*iter.current_value_p),
&property_descriptors[index],
true),
ret_value);
ECMA_FINALIZE (define_own_prop_ret);
}
// Clean up
for (uint32_t index = 0;
index < property_descriptor_number;
index++)
{
ecma_free_property_descriptor (&property_descriptors[index]);
}
JMEM_FINALIZE_LOCAL_ARRAY (property_descriptors);
ecma_free_values_collection (prop_names_p, true);
// 7.
if (ecma_is_value_empty (ret_value))
{
ret_value = ecma_copy_value (arg1);
}
ECMA_FINALIZE (props);
}
return ret_value;
} /* ecma_builtin_object_object_define_properties */
/**
* The Object object's 'defineProperty' routine
*
* See also:
* ECMA-262 v5, 15.2.3.6
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_object_object_define_property (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg1, /**< routine's first argument */
ecma_value_t arg2, /**< routine's second argument */
ecma_value_t arg3) /**< routine's third argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (!ecma_is_value_object (arg1))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_object_t *obj_p = ecma_get_object_from_value (arg1);
ECMA_TRY_CATCH (name_str_value,
ecma_op_to_string (arg2),
ret_value);
ecma_string_t *name_str_p = ecma_get_string_from_value (name_str_value);
ecma_property_descriptor_t prop_desc;
ECMA_TRY_CATCH (conv_result,
ecma_op_to_property_descriptor (arg3, &prop_desc),
ret_value);
ECMA_TRY_CATCH (define_own_prop_ret,
ecma_op_object_define_own_property (obj_p,
name_str_p,
&prop_desc,
true),
ret_value);
ret_value = ecma_copy_value (arg1);
ECMA_FINALIZE (define_own_prop_ret);
ecma_free_property_descriptor (&prop_desc);
ECMA_FINALIZE (conv_result);
ECMA_FINALIZE (name_str_value);
}
return ret_value;
} /* ecma_builtin_object_object_define_property */
/**
* @}
* @}
* @}
*/

View file

@ -0,0 +1,76 @@
/* 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.
*/
/*
* Object built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_OBJECT)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
// 15.2.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
/* Object properties:
* (property name, object pointer getter) */
// 15.2.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
ECMA_PROPERTY_FIXED)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_GET_PROTOTYPE_OF_UL, ecma_builtin_object_object_get_prototype_of, 1, 1)
ROUTINE (LIT_MAGIC_STRING_GET_OWN_PROPERTY_NAMES_UL, ecma_builtin_object_object_get_own_property_names, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SEAL, ecma_builtin_object_object_seal, 1, 1)
ROUTINE (LIT_MAGIC_STRING_FREEZE, ecma_builtin_object_object_freeze, 1, 1)
ROUTINE (LIT_MAGIC_STRING_PREVENT_EXTENSIONS_UL, ecma_builtin_object_object_prevent_extensions, 1, 1)
ROUTINE (LIT_MAGIC_STRING_IS_SEALED_UL, ecma_builtin_object_object_is_sealed, 1, 1)
ROUTINE (LIT_MAGIC_STRING_IS_FROZEN_UL, ecma_builtin_object_object_is_frozen, 1, 1)
ROUTINE (LIT_MAGIC_STRING_IS_EXTENSIBLE, ecma_builtin_object_object_is_extensible, 1, 1)
ROUTINE (LIT_MAGIC_STRING_KEYS, ecma_builtin_object_object_keys, 1, 1)
ROUTINE (LIT_MAGIC_STRING_GET_OWN_PROPERTY_DESCRIPTOR_UL, ecma_builtin_object_object_get_own_property_descriptor, 2, 2)
ROUTINE (LIT_MAGIC_STRING_CREATE, ecma_builtin_object_object_create, 2, 2)
ROUTINE (LIT_MAGIC_STRING_DEFINE_PROPERTIES_UL, ecma_builtin_object_object_define_properties, 2, 2)
ROUTINE (LIT_MAGIC_STRING_DEFINE_PROPERTY_UL, ecma_builtin_object_object_define_property, 3, 3)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,37 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-rangeerror-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID range_error_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */

View file

@ -0,0 +1,58 @@
/* 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.
*/
/*
* RangeError.prototype built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_RANGE_ERROR_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
// 15.11.7.8
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_RANGE_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// 15.11.7.9
STRING_VALUE (LIT_MAGIC_STRING_NAME,
LIT_MAGIC_STRING_RANGE_ERROR_UL,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// 15.11.7.10
STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
LIT_MAGIC_STRING__EMPTY,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,77 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-builtin-helpers.h"
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-rangeerror.inc.h"
#define BUILTIN_UNDERSCORED_ID range_error
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup rangeerror ECMA RangeError object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in RangeError object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_range_error_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_helper_error_dispatch_call (ECMA_ERROR_RANGE, arguments_list_p, arguments_list_len);
} /* ecma_builtin_range_error_dispatch_call */
/**
* Handle calling [[Construct]] of built-in RangeError object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_range_error_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_range_error_dispatch_call (arguments_list_p, arguments_list_len);
} /* ecma_builtin_range_error_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */

View file

@ -0,0 +1,60 @@
/* 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.
*/
/*
* RangeError built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_RANGE_ERROR)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
// 15.11.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
/* Object properties:
* (property name, object pointer getter) */
// 15.11.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_RANGE_ERROR_PROTOTYPE,
ECMA_PROPERTY_FIXED)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,37 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-referenceerror-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID reference_error_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */

View file

@ -0,0 +1,58 @@
/* 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.
*/
/*
* ReferenceError.prototype built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_REFERENCE_ERROR_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
// 15.11.7.8
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_REFERENCE_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// 15.11.7.9
STRING_VALUE (LIT_MAGIC_STRING_NAME,
LIT_MAGIC_STRING_REFERENCE_ERROR_UL,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// 15.11.7.10
STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
LIT_MAGIC_STRING__EMPTY,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,77 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-builtin-helpers.h"
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-referenceerror.inc.h"
#define BUILTIN_UNDERSCORED_ID reference_error
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup referenceerror ECMA ReferenceError object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in ReferenceError object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_reference_error_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_helper_error_dispatch_call (ECMA_ERROR_REFERENCE, arguments_list_p, arguments_list_len);
} /* ecma_builtin_reference_error_dispatch_call */
/**
* Handle calling [[Construct]] of built-in ReferenceError object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_reference_error_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_reference_error_dispatch_call (arguments_list_p, arguments_list_len);
} /* ecma_builtin_reference_error_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */

View file

@ -0,0 +1,60 @@
/* 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.
*/
/*
* ReferenceError built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_REFERENCE_ERROR)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
// 15.11.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
/* Object properties:
* (property name, object pointer getter) */
// 15.11.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_REFERENCE_ERROR_PROTOTYPE,
ECMA_PROPERTY_FIXED)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,451 @@
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-alloc.h"
#include "ecma-array-object.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#ifndef CONFIG_DISABLE_REGEXP_BUILTIN
#include "ecma-regexp-object.h"
#include "re-compiler.h"
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-regexp-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID regexp_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup regexpprototype ECMA RegExp.prototype object built-in
* @{
*/
#ifndef CONFIG_DISABLE_ANNEXB_BUILTIN
/**
* The RegExp.prototype object's 'compile' routine
*
* See also:
* ECMA-262 v5, B.2.5.1
*
* @return undefined - if compiled successfully
* error ecma value - otherwise
*
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument */
ecma_value_t pattern_arg, /**< pattern or RegExp object */
ecma_value_t flags_arg) /**< flags */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (!ecma_is_value_object (this_arg)
|| ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_REGEXP_UL)
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Incomplete RegExp type"));
}
else
{
uint16_t flags = 0;
if (ecma_is_value_object (pattern_arg)
&& ecma_object_get_class_name (ecma_get_object_from_value (pattern_arg)) == LIT_MAGIC_STRING_REGEXP_UL)
{
if (!ecma_is_value_undefined (flags_arg))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument of RegExp compile."));
}
else
{
/* Compile from existing RegExp pbject. */
ecma_object_t *target_p = ecma_get_object_from_value (pattern_arg);
/* Get source. */
ecma_string_t *magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SOURCE);
ecma_value_t source_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
ecma_deref_ecma_string (magic_string_p);
ecma_string_t *pattern_string_p = ecma_get_string_from_value (source_value);
/* Get flags. */
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GLOBAL);
ecma_value_t global_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
ecma_deref_ecma_string (magic_string_p);
JERRY_ASSERT (ecma_is_value_boolean (global_value));
if (ecma_is_value_true (global_value))
{
flags |= RE_FLAG_GLOBAL;
}
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_IGNORECASE_UL);
ecma_value_t ignore_case_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
ecma_deref_ecma_string (magic_string_p);
JERRY_ASSERT (ecma_is_value_boolean (ignore_case_value));
if (ecma_is_value_true (ignore_case_value))
{
flags |= RE_FLAG_IGNORE_CASE;
}
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MULTILINE);
ecma_value_t multiline_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
ecma_deref_ecma_string (magic_string_p);
JERRY_ASSERT (ecma_is_value_boolean (multiline_value));
if (ecma_is_value_true (multiline_value))
{
flags |= RE_FLAG_MULTILINE;
}
ECMA_TRY_CATCH (obj_this, ecma_op_to_object (this_arg), ret_value);
ecma_object_t *this_obj_p = ecma_get_object_from_value (obj_this);
/* Get bytecode property. */
ecma_value_t *bc_prop_p = ecma_get_internal_property (this_obj_p,
ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE);
/* TODO: We currently have to re-compile the bytecode, because
* we can't copy it without knowing its length. */
const re_compiled_code_t *new_bc_p = NULL;
ecma_value_t bc_comp = re_compile_bytecode (&new_bc_p, pattern_string_p, flags);
/* Should always succeed, since we're compiling from a source that has been compiled previously. */
JERRY_ASSERT (ecma_is_value_empty (bc_comp));
ecma_deref_ecma_string (pattern_string_p);
re_compiled_code_t *old_bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t, *bc_prop_p);
if (old_bc_p != NULL)
{
/* Free the old bytecode */
ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p);
}
ECMA_SET_INTERNAL_VALUE_POINTER (*bc_prop_p, new_bc_p);
re_initialize_props (this_obj_p, pattern_string_p, flags);
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
ECMA_FINALIZE (obj_this);
}
}
else
{
ecma_string_t *pattern_string_p = NULL;
/* Get source string. */
if (!ecma_is_value_undefined (pattern_arg))
{
ECMA_TRY_CATCH (regexp_str_value,
ecma_op_to_string (pattern_arg),
ret_value);
if (ecma_string_is_empty (ecma_get_string_from_value (regexp_str_value)))
{
pattern_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP);
}
else
{
pattern_string_p = ecma_get_string_from_value (regexp_str_value);
ecma_ref_ecma_string (pattern_string_p);
}
ECMA_FINALIZE (regexp_str_value);
}
else
{
pattern_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP);
}
/* Parse flags. */
if (ecma_is_value_empty (ret_value) && !ecma_is_value_undefined (flags_arg))
{
ECMA_TRY_CATCH (flags_str_value,
ecma_op_to_string (flags_arg),
ret_value);
ECMA_TRY_CATCH (flags_dummy,
re_parse_regexp_flags (ecma_get_string_from_value (flags_str_value), &flags),
ret_value);
ECMA_FINALIZE (flags_dummy);
ECMA_FINALIZE (flags_str_value);
}
if (ecma_is_value_empty (ret_value))
{
ECMA_TRY_CATCH (obj_this, ecma_op_to_object (this_arg), ret_value);
ecma_object_t *this_obj_p = ecma_get_object_from_value (obj_this);
ecma_value_t *bc_prop_p = ecma_get_internal_property (this_obj_p,
ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE);
/* Try to compile bytecode from new source. */
const re_compiled_code_t *new_bc_p = NULL;
ECMA_TRY_CATCH (bc_dummy,
re_compile_bytecode (&new_bc_p, pattern_string_p, flags),
ret_value);
re_compiled_code_t *old_bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t, *bc_prop_p);
if (old_bc_p != NULL)
{
/* Free the old bytecode */
ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p);
}
ECMA_SET_INTERNAL_VALUE_POINTER (*bc_prop_p, new_bc_p);
re_initialize_props (this_obj_p, pattern_string_p, flags);
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
ECMA_FINALIZE (bc_dummy);
ECMA_FINALIZE (obj_this);
}
if (pattern_string_p != NULL)
{
ecma_deref_ecma_string (pattern_string_p);
}
}
}
return ret_value;
} /* ecma_builtin_regexp_prototype_compile */
#endif /* !CONFIG_DISABLE_ANNEXB_BUILTIN */
/**
* The RegExp.prototype object's 'exec' routine
*
* See also:
* ECMA-262 v5, 15.10.6.2
*
* @return array object containing the results - if the matched
* null - otherwise
*
* May raise error, so returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_regexp_prototype_exec (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg) /**< routine's argument */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (!ecma_is_value_object (this_arg)
|| ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_REGEXP_UL)
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Incomplete RegExp type"));
}
else
{
ECMA_TRY_CATCH (obj_this, ecma_op_to_object (this_arg), ret_value);
ECMA_TRY_CATCH (input_str_value,
ecma_op_to_string (arg),
ret_value);
ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
ecma_value_t *bytecode_prop_p = ecma_get_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE);
void *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (void, *bytecode_prop_p);
if (bytecode_p == NULL)
{
/* Missing bytecode means empty RegExp: '/(?:)/', so always return empty string. */
ecma_string_t *capture_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
ecma_value_t arguments_list[1];
arguments_list[0] = ecma_make_string_value (capture_str_p);
ret_value = ecma_op_create_array_object (arguments_list, 1, false);
ecma_deref_ecma_string (capture_str_p);
re_set_result_array_properties (ecma_get_object_from_value (ret_value),
ecma_get_string_from_value (input_str_value),
1,
0);
}
else
{
ret_value = ecma_regexp_exec_helper (obj_this, input_str_value, false);
}
ECMA_FINALIZE (input_str_value);
ECMA_FINALIZE (obj_this);
}
return ret_value;
} /* ecma_builtin_regexp_prototype_exec */
/**
* The RegExp.prototype object's 'test' routine
*
* See also:
* ECMA-262 v5, 15.10.6.3
*
* @return true - if match is not null
* false - otherwise
*
* May raise error, so returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_regexp_prototype_test (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg) /**< routine's argument */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_TRY_CATCH (match_value,
ecma_builtin_regexp_prototype_exec (this_arg, arg),
ret_value);
if (ecma_is_value_null (match_value))
{
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
}
else
{
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
}
ECMA_FINALIZE (match_value);
return ret_value;
} /* ecma_builtin_regexp_prototype_test */
/**
* The RegExp.prototype object's 'toString' routine
*
* See also:
* ECMA-262 v5, 15.10.6.4
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_regexp_prototype_to_string (ecma_value_t this_arg) /**< this argument */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (!ecma_is_value_object (this_arg)
|| ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_REGEXP_UL)
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Incomplete RegExp type"));
}
else
{
ECMA_TRY_CATCH (obj_this,
ecma_op_to_object (this_arg),
ret_value);
ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
/* Get RegExp source from the source property */
ecma_string_t *magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SOURCE);
ecma_value_t source_value = ecma_op_object_get_own_data_prop (obj_p, magic_string_p);
ecma_deref_ecma_string (magic_string_p);
ecma_string_t *src_sep_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_SLASH_CHAR);
ecma_string_t *source_str_p = ecma_get_string_from_value (source_value);
ecma_string_t *output_str_p = ecma_concat_ecma_strings (src_sep_str_p, source_str_p);
ecma_deref_ecma_string (source_str_p);
ecma_string_t *concat_p = ecma_concat_ecma_strings (output_str_p, src_sep_str_p);
ecma_deref_ecma_string (src_sep_str_p);
ecma_deref_ecma_string (output_str_p);
output_str_p = concat_p;
/* Check the global flag */
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GLOBAL);
ecma_value_t global_value = ecma_op_object_get_own_data_prop (obj_p, magic_string_p);
ecma_deref_ecma_string (magic_string_p);
JERRY_ASSERT (ecma_is_value_boolean (global_value));
if (ecma_is_value_true (global_value))
{
ecma_string_t *g_flag_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_G_CHAR);
concat_p = ecma_concat_ecma_strings (output_str_p, g_flag_str_p);
ecma_deref_ecma_string (output_str_p);
ecma_deref_ecma_string (g_flag_str_p);
output_str_p = concat_p;
}
/* Check the ignoreCase flag */
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_IGNORECASE_UL);
ecma_value_t ignore_case_value = ecma_op_object_get_own_data_prop (obj_p, magic_string_p);
ecma_deref_ecma_string (magic_string_p);
JERRY_ASSERT (ecma_is_value_boolean (ignore_case_value));
if (ecma_is_value_true (ignore_case_value))
{
ecma_string_t *ic_flag_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_I_CHAR);
concat_p = ecma_concat_ecma_strings (output_str_p, ic_flag_str_p);
ecma_deref_ecma_string (output_str_p);
ecma_deref_ecma_string (ic_flag_str_p);
output_str_p = concat_p;
}
/* Check the multiline flag */
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MULTILINE);
ecma_value_t multiline_value = ecma_op_object_get_own_data_prop (obj_p, magic_string_p);
ecma_deref_ecma_string (magic_string_p);
JERRY_ASSERT (ecma_is_value_boolean (multiline_value));
if (ecma_is_value_true (multiline_value))
{
ecma_string_t *m_flag_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_M_CHAR);
concat_p = ecma_concat_ecma_strings (output_str_p, m_flag_str_p);
ecma_deref_ecma_string (output_str_p);
ecma_deref_ecma_string (m_flag_str_p);
output_str_p = concat_p;
}
ret_value = ecma_make_string_value (output_str_p);
ECMA_FINALIZE (obj_this);
}
return ret_value;
} /* ecma_builtin_regexp_prototype_to_string */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */

View file

@ -0,0 +1,90 @@
/* 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.
*/
/*
* RegExp.prototype built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef SIMPLE_VALUE
# define SIMPLE_VALUE(name, simple_value, prop_attributes)
#endif /* !SIMPLE_VALUE */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE)
// ECMA-262 v5, 15.10.6.1
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_REGEXP,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// ECMA-262 v5, 15.10.7.1
STRING_VALUE (LIT_MAGIC_STRING_SOURCE,
LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP,
ECMA_PROPERTY_FIXED)
// ECMA-262 v5, 15.10.7.2
SIMPLE_VALUE (LIT_MAGIC_STRING_GLOBAL,
ECMA_SIMPLE_VALUE_FALSE,
ECMA_PROPERTY_FIXED)
// ECMA-262 v5, 15.10.7.3
SIMPLE_VALUE (LIT_MAGIC_STRING_IGNORECASE_UL,
ECMA_SIMPLE_VALUE_FALSE,
ECMA_PROPERTY_FIXED)
// ECMA-262 v5, 15.10.7.4
SIMPLE_VALUE (LIT_MAGIC_STRING_MULTILINE,
ECMA_SIMPLE_VALUE_FALSE,
ECMA_PROPERTY_FIXED)
// ECMA-262 v5, 15.10.7.5
NUMBER_VALUE (LIT_MAGIC_STRING_LASTINDEX_UL,
0,
ECMA_PROPERTY_FLAG_WRITABLE)
#ifndef CONFIG_DISABLE_ANNEXB_BUILTIN
ROUTINE (LIT_MAGIC_STRING_COMPILE, ecma_builtin_regexp_prototype_compile, 2, 1)
#endif /* !CONFIG_DISABLE_ANNEXB_BUILTIN */
ROUTINE (LIT_MAGIC_STRING_EXEC, ecma_builtin_regexp_prototype_exec, 1, 1)
ROUTINE (LIT_MAGIC_STRING_TEST, ecma_builtin_regexp_prototype_test, 1, 1)
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_regexp_prototype_to_string, 0, 0)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,160 @@
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-regexp-object.h"
#include "ecma-try-catch-macro.h"
#ifndef CONFIG_DISABLE_REGEXP_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-regexp.inc.h"
#define BUILTIN_UNDERSCORED_ID regexp
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup regexp ECMA RegExp object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in RegExp object
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_regexp_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_regexp_dispatch_construct (arguments_list_p, arguments_list_len);
} /* ecma_builtin_regexp_dispatch_call */
/**
* Handle calling [[Construct]] of built-in RegExp object
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_regexp_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_value_t pattern_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
ecma_value_t flags_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
if (arguments_list_len > 0)
{
/* pattern string or RegExp object */
pattern_value = arguments_list_p[0];
if (arguments_list_len > 1)
{
flags_value = arguments_list_p[1];
}
}
if (ecma_is_value_object (pattern_value)
&& ecma_object_get_class_name (ecma_get_object_from_value (pattern_value)) == LIT_MAGIC_STRING_REGEXP_UL)
{
if (ecma_is_value_undefined (flags_value))
{
ret_value = ecma_copy_value (pattern_value);
}
else
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument of RegExp call."));
}
}
else
{
ecma_string_t *pattern_string_p = NULL;
ecma_string_t *flags_string_p = NULL;
if (!ecma_is_value_undefined (pattern_value))
{
ECMA_TRY_CATCH (regexp_str_value,
ecma_op_to_string (pattern_value),
ret_value);
if (ecma_string_is_empty (ecma_get_string_from_value (regexp_str_value)))
{
pattern_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP);
}
else
{
pattern_string_p = ecma_get_string_from_value (regexp_str_value);
ecma_ref_ecma_string (pattern_string_p);
}
ECMA_FINALIZE (regexp_str_value);
}
else
{
pattern_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP);
}
if (ecma_is_value_empty (ret_value) && !ecma_is_value_undefined (flags_value))
{
ECMA_TRY_CATCH (flags_str_value,
ecma_op_to_string (flags_value),
ret_value);
flags_string_p = ecma_get_string_from_value (flags_str_value);
ecma_ref_ecma_string (flags_string_p);
ECMA_FINALIZE (flags_str_value);
}
if (ecma_is_value_empty (ret_value))
{
ret_value = ecma_op_create_regexp_object (pattern_string_p, flags_string_p);
}
if (pattern_string_p != NULL)
{
ecma_deref_ecma_string (pattern_string_p);
}
if (flags_string_p != NULL)
{
ecma_deref_ecma_string (flags_string_p);
}
}
return ret_value;
} /* ecma_builtin_regexp_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */

View file

@ -0,0 +1,51 @@
/* Copyright 2015 Samsung Electronics Co., Ltd.
* Copyright 2015 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.
*/
/*
* RegExp built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_REGEXP)
// ECMA-262 v5, 15.10.5
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
2,
ECMA_PROPERTY_FIXED)
// ECMA-262 v5, 15.10.5.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_REGEXP_PROTOTYPE,
ECMA_PROPERTY_FIXED)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,90 @@
/* 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.
*/
/*
* String.prototype built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_STRING_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
// 15.5.4.1
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_STRING,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
/* Number properties:
* (property name, number value) */
// 15.5.4 (String.prototype is itself a String object whose value is an empty String), 15.5.5.1
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
0,
ECMA_PROPERTY_FIXED)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_string_prototype_object_to_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_VALUE_OF_UL, ecma_builtin_string_prototype_object_value_of, 0, 0)
ROUTINE (LIT_MAGIC_STRING_CONCAT, ecma_builtin_string_prototype_object_concat, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_SLICE, ecma_builtin_string_prototype_object_slice, 2, 2)
ROUTINE (LIT_MAGIC_STRING_INDEX_OF_UL, ecma_builtin_string_prototype_object_index_of, 2, 1)
ROUTINE (LIT_MAGIC_STRING_LAST_INDEX_OF_UL, ecma_builtin_string_prototype_object_last_index_of, 2, 1)
ROUTINE (LIT_MAGIC_STRING_CHAR_AT_UL, ecma_builtin_string_prototype_object_char_at, 1, 1)
ROUTINE (LIT_MAGIC_STRING_CHAR_CODE_AT_UL, ecma_builtin_string_prototype_object_char_code_at, 1, 1)
ROUTINE (LIT_MAGIC_STRING_LOCALE_COMPARE_UL, ecma_builtin_string_prototype_object_locale_compare, 1, 1)
#ifndef CONFIG_DISABLE_REGEXP_BUILTIN
ROUTINE (LIT_MAGIC_STRING_MATCH, ecma_builtin_string_prototype_object_match, 1, 1)
ROUTINE (LIT_MAGIC_STRING_REPLACE, ecma_builtin_string_prototype_object_replace, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SEARCH, ecma_builtin_string_prototype_object_search, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SPLIT, ecma_builtin_string_prototype_object_split, 2, 2)
#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
ROUTINE (LIT_MAGIC_STRING_SUBSTRING, ecma_builtin_string_prototype_object_substring, 2, 2)
ROUTINE (LIT_MAGIC_STRING_TO_LOWER_CASE_UL, ecma_builtin_string_prototype_object_to_lower_case, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_LOWER_CASE_UL, ecma_builtin_string_prototype_object_to_locale_lower_case, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_UPPER_CASE_UL, ecma_builtin_string_prototype_object_to_upper_case, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_UPPER_CASE_UL, ecma_builtin_string_prototype_object_to_locale_upper_case, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TRIM, ecma_builtin_string_prototype_object_trim, 0, 0)
#ifndef CONFIG_DISABLE_ANNEXB_BUILTIN
ROUTINE (LIT_MAGIC_STRING_SUBSTR, ecma_builtin_string_prototype_object_substr, 2, 2)
#endif /* !CONFIG_DISABLE_ANNEXB_BUILTIN */
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,159 @@
/* 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-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_STRING_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-string.inc.h"
#define BUILTIN_UNDERSCORED_ID string
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup string ECMA String object built-in
* @{
*/
/**
* The String object's 'fromCharCode' routine
*
* See also:
* ECMA-262 v5, 15.5.3.2
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_string_object_from_char_code (ecma_value_t this_arg, /**< 'this' argument */
const ecma_value_t args[], /**< arguments list */
ecma_length_t args_number) /**< number of arguments */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_string_t *ret_string_p = NULL;
if (args_number == 0)
{
ret_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
}
else
{
lit_utf8_size_t utf8_buf_size = args_number * LIT_CESU8_MAX_BYTES_IN_CODE_UNIT;
JMEM_DEFINE_LOCAL_ARRAY (utf8_buf_p,
utf8_buf_size,
lit_utf8_byte_t);
lit_utf8_size_t utf8_buf_used = 0;
for (ecma_length_t arg_index = 0;
arg_index < args_number && ecma_is_value_empty (ret_value);
arg_index++)
{
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, args[arg_index], ret_value);
uint32_t uint32_char_code = ecma_number_to_uint32 (arg_num);
ecma_char_t code_unit = (uint16_t) uint32_char_code;
JERRY_ASSERT (utf8_buf_used <= utf8_buf_size - LIT_UTF8_MAX_BYTES_IN_CODE_UNIT);
utf8_buf_used += lit_code_unit_to_utf8 (code_unit, utf8_buf_p + utf8_buf_used);
JERRY_ASSERT (utf8_buf_used <= utf8_buf_size);
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
}
if (ecma_is_value_empty (ret_value))
{
ret_string_p = ecma_new_ecma_string_from_utf8 (utf8_buf_p, utf8_buf_used);
}
JMEM_FINALIZE_LOCAL_ARRAY (utf8_buf_p);
}
if (ecma_is_value_empty (ret_value))
{
ret_value = ecma_make_string_value (ret_string_p);
}
return ret_value;
} /* ecma_builtin_string_object_from_char_code */
/**
* Handle calling [[Call]] of built-in String object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_string_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (arguments_list_len == 0)
{
ecma_string_t *str_p = ecma_new_ecma_string_from_magic_string_id (LIT_MAGIC_STRING__EMPTY);
ecma_value_t str_value = ecma_make_string_value (str_p);
ret_value = str_value;
}
else
{
ret_value = ecma_op_to_string (arguments_list_p[0]);
}
return ret_value;
} /* ecma_builtin_string_dispatch_call */
/**
* Handle calling [[Construct]] of built-in String object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_string_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
return ecma_op_create_string_object (arguments_list_p, arguments_list_len);
} /* ecma_builtin_string_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_STRING_BUILTIN */

View file

@ -0,0 +1,64 @@
/* 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.
*/
/*
* String built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_STRING)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
// 15.5.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
/* Object properties:
* (property name, object pointer getter) */
// 15.7.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_STRING_PROTOTYPE,
ECMA_PROPERTY_FIXED)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_FROM_CHAR_CODE_UL, ecma_builtin_string_object_from_char_code, NON_FIXED, 1)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,37 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-syntaxerror-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID syntax_error_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */

View file

@ -0,0 +1,58 @@
/* 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.
*/
/*
* SyntaxError.prototype built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_SYNTAX_ERROR_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
// 15.11.7.8
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_SYNTAX_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// 15.11.7.9
STRING_VALUE (LIT_MAGIC_STRING_NAME,
LIT_MAGIC_STRING_SYNTAX_ERROR_UL,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// 15.11.7.10
STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
LIT_MAGIC_STRING__EMPTY,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,77 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-builtin-helpers.h"
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-syntaxerror.inc.h"
#define BUILTIN_UNDERSCORED_ID syntax_error
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup syntaxerror ECMA SyntaxError object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in SyntaxError object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_syntax_error_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_helper_error_dispatch_call (ECMA_ERROR_SYNTAX, arguments_list_p, arguments_list_len);
} /* ecma_builtin_syntax_error_dispatch_call */
/**
* Handle calling [[Construct]] of built-in SyntaxError object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_syntax_error_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_syntax_error_dispatch_call (arguments_list_p, arguments_list_len);
} /* ecma_builtin_syntax_error_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */

View file

@ -0,0 +1,60 @@
/* 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.
*/
/*
* SyntaxError built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_SYNTAX_ERROR)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
// 15.11.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
/* Object properties:
* (property name, object pointer getter) */
// 15.11.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_SYNTAX_ERROR_PROTOTYPE,
ECMA_PROPERTY_FIXED)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,84 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-type-error-thrower.inc.h"
#define BUILTIN_UNDERSCORED_ID type_error_thrower
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup type_error_thrower ECMA [[ThrowTypeError]] object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in [[ThrowTypeError]] object
*
* See also:
* ECMA-262 v5, 13.2.3
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_type_error_thrower_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
/* The object should throw TypeError */
return ecma_raise_type_error (ECMA_ERR_MSG (""));
} /* ecma_builtin_type_error_thrower_dispatch_call */
/**
* Handle calling [[Construct]] of built-in [[ThrowTypeError]] object
*
* See also:
* ECMA-262 v5, 13.2.3
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_type_error_thrower_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
/* The object is not a constructor */
return ecma_raise_type_error (ECMA_ERR_MSG (""));
} /* ecma_builtin_type_error_thrower_dispatch_construct */
/**
* @}
* @}
* @}
*/

View file

@ -0,0 +1,45 @@
/* Copyright 2014 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.
*/
/*
* [[ThrowTypeError]] description
*
* See also: ECMA-262 v5, 13.2.3
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
0,
ECMA_PROPERTY_FIXED)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,37 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-typeerror-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID type_error_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */

View file

@ -0,0 +1,58 @@
/* 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.
*/
/*
* TypeError.prototype built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_TYPE_ERROR_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
// 15.11.7.8
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_TYPE_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// 15.11.7.9
STRING_VALUE (LIT_MAGIC_STRING_NAME,
LIT_MAGIC_STRING_TYPE_ERROR_UL,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// 15.11.7.10
STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
LIT_MAGIC_STRING__EMPTY,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,77 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-builtin-helpers.h"
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-typeerror.inc.h"
#define BUILTIN_UNDERSCORED_ID type_error
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup typeerror ECMA TypeError object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in TypeError object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_type_error_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_helper_error_dispatch_call (ECMA_ERROR_TYPE, arguments_list_p, arguments_list_len);
} /* ecma_builtin_type_error_dispatch_call */
/**
* Handle calling [[Construct]] of built-in TypeError object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_type_error_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_type_error_dispatch_call (arguments_list_p, arguments_list_len);
} /* ecma_builtin_type_error_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */

View file

@ -0,0 +1,60 @@
/* 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.
*/
/*
* TypeError built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_TYPE_ERROR)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
// 15.11.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
/* Object properties:
* (property name, object pointer getter) */
// 15.11.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_TYPE_ERROR_PROTOTYPE,
ECMA_PROPERTY_FIXED)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,37 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-urierror-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID uri_error_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */

View file

@ -0,0 +1,58 @@
/* 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.
*/
/*
* UriError.prototype built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
// 15.11.7.8
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_URI_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// 15.11.7.9
STRING_VALUE (LIT_MAGIC_STRING_NAME,
LIT_MAGIC_STRING_URI_ERROR_UL,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
// 15.11.7.10
STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
LIT_MAGIC_STRING__EMPTY,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,77 @@
/* 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-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-builtin-helpers.h"
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-urierror.inc.h"
#define BUILTIN_UNDERSCORED_ID uri_error
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup urierror ECMA UriError object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in UriError object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_uri_error_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_helper_error_dispatch_call (ECMA_ERROR_URI, arguments_list_p, arguments_list_len);
} /* ecma_builtin_uri_error_dispatch_call */
/**
* Handle calling [[Construct]] of built-in UriError object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_uri_error_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_uri_error_dispatch_call (arguments_list_p, arguments_list_len);
} /* ecma_builtin_uri_error_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */

View file

@ -0,0 +1,60 @@
/* 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.
*/
/*
* UriError built-in description
*/
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_URI_ERROR)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
// 15.11.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
/* Object properties:
* (property name, object pointer getter) */
// 15.11.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE,
ECMA_PROPERTY_FIXED)
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

View file

@ -0,0 +1,91 @@
/* 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_BUILTINS_INTERNAL_H
#define ECMA_BUILTINS_INTERNAL_H
#ifndef ECMA_BUILTINS_INTERNAL
# error "!ECMA_BUILTINS_INTERNAL"
#endif /* !ECMA_BUILTINS_INTERNAL */
#include "ecma-builtins.h"
#include "ecma-globals.h"
/**
* Type of built-in properties.
*/
typedef enum
{
ECMA_BUILTIN_PROPERTY_SIMPLE, /**< simple value property */
ECMA_BUILTIN_PROPERTY_NUMBER, /**< number value property */
ECMA_BUILTIN_PROPERTY_STRING, /**< string value property */
ECMA_BUILTIN_PROPERTY_OBJECT, /**< builtin object property */
ECMA_BUILTIN_PROPERTY_ROUTINE, /**< routine property */
ECMA_BUILTIN_PROPERTY_END, /**< last property */
} ecma_builtin_property_type_t;
/**
* Type of symbolic built-in number types (starting from 256).
*/
typedef enum
{
ECMA_BUILTIN_NUMBER_MAX = 256, /**< value of ECMA_NUMBER_MAX_VALUE */
ECMA_BUILTIN_NUMBER_MIN, /**< value of ECMA_NUMBER_MIN_VALUE */
ECMA_BUILTIN_NUMBER_E, /**< value of ECMA_NUMBER_E */
ECMA_BUILTIN_NUMBER_PI, /**< value of ECMA_NUMBER_PI */
ECMA_BUILTIN_NUMBER_LN10, /**< value of ECMA_NUMBER_LN10 */
ECMA_BUILTIN_NUMBER_LN2, /**< value of ECMA_NUMBER_LN2 */
ECMA_BUILTIN_NUMBER_LOG2E, /**< value of ECMA_NUMBER_LOG2E */
ECMA_BUILTIN_NUMBER_LOG10E, /**< value of ECMA_NUMBER_LOG10E */
ECMA_BUILTIN_NUMBER_SQRT2, /**< value of ECMA_NUMBER_SQRT2 */
ECMA_BUILTIN_NUMBER_SQRT_1_2, /**< value of ECMA_NUMBER_SQRT_1_2 */
ECMA_BUILTIN_NUMBER_NAN, /**< result of ecma_number_make_nan () */
ECMA_BUILTIN_NUMBER_POSITIVE_INFINITY, /**< result of ecma_number_make_infinity (false) */
ECMA_BUILTIN_NUMBER_NEGATIVE_INFINITY, /**< result of ecma_number_make_infinity (true) */
} ecma_builtin_number_type_t;
/**
* Description of built-in properties.
*/
typedef struct
{
uint16_t magic_string_id; /**< name of the property */
uint8_t type; /**< type of the property */
uint8_t attributes; /**< attributes of the property */
uint16_t value; /**< value of the property */
} ecma_builtin_property_descriptor_t;
#define BUILTIN(builtin_id, \
object_type, \
object_prototype_builtin_id, \
is_extensible, \
is_static, \
lowercase_name) \
extern const ecma_builtin_property_descriptor_t \
ecma_builtin_ ## lowercase_name ## _property_descriptor_list[]; \
extern ecma_value_t \
ecma_builtin_ ## lowercase_name ## _dispatch_call (const ecma_value_t *, \
ecma_length_t); \
extern ecma_value_t \
ecma_builtin_ ## lowercase_name ## _dispatch_construct (const ecma_value_t *, \
ecma_length_t); \
extern ecma_value_t \
ecma_builtin_ ## lowercase_name ## _dispatch_routine (uint16_t builtin_routine_id, \
ecma_value_t this_arg_value, \
const ecma_value_t [], \
ecma_length_t);
#include "ecma-builtins.inc.h"
#endif /* !ECMA_BUILTINS_INTERNAL_H */

View file

@ -0,0 +1,811 @@
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-alloc.h"
#include "ecma-builtins.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "jcontext.h"
#include "jrt-bit-fields.h"
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*/
static void ecma_instantiate_builtin (ecma_builtin_id_t id);
/**
* Check if passed object is the instance of specified built-in.
*/
bool
ecma_builtin_is (ecma_object_t *obj_p, /**< pointer to an object */
ecma_builtin_id_t builtin_id) /**< id of built-in to check on */
{
JERRY_ASSERT (obj_p != NULL && !ecma_is_lexical_environment (obj_p));
JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT);
if (JERRY_CONTEXT (ecma_builtin_objects)[builtin_id] == NULL)
{
/* If a built-in object is not instantiated,
* the specified object cannot be the built-in object */
return false;
}
else
{
return (obj_p == JERRY_CONTEXT (ecma_builtin_objects)[builtin_id]);
}
} /* ecma_builtin_is */
/**
* Get reference to specified built-in object
*
* @return pointer to the object's instance
*/
ecma_object_t *
ecma_builtin_get (ecma_builtin_id_t builtin_id) /**< id of built-in to check on */
{
JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT);
if (unlikely (JERRY_CONTEXT (ecma_builtin_objects)[builtin_id] == NULL))
{
ecma_instantiate_builtin (builtin_id);
}
ecma_ref_object (JERRY_CONTEXT (ecma_builtin_objects)[builtin_id]);
return JERRY_CONTEXT (ecma_builtin_objects)[builtin_id];
} /* ecma_builtin_get */
/**
* Checks whether the given function is a built-in routine
*
* @return true if the function object is a built-in routine
* false otherwise
*/
inline bool __attr_always_inline___
ecma_builtin_function_is_routine (ecma_object_t *func_obj_p) /**< function object */
{
JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
JERRY_ASSERT (ecma_get_object_is_builtin (func_obj_p));
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
return (ext_func_obj_p->u.built_in.routine_id >= ECMA_BUILTIN_ID__COUNT);
} /* ecma_builtin_function_is_routine */
/**
* Initialize specified built-in object.
*
* @return pointer to the object
*/
static ecma_object_t *
ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
ecma_object_t *prototype_obj_p, /**< prototype object */
ecma_object_type_t obj_type, /**< object's type */
bool is_extensible) /**< value of object's [[Extensible]] property */
{
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, true, is_extensible, obj_type);
/*
* [[Class]] property of built-in object is not stored explicitly.
*
* See also: ecma_object_get_class_name
*/
ecma_set_object_is_builtin (obj_p);
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
ext_obj_p->u.built_in.id = obj_builtin_id;
ext_obj_p->u.built_in.routine_id = obj_builtin_id;
ext_obj_p->u.built_in.instantiated_bitset = 0;
/** Initializing [[PrimitiveValue]] properties of built-in prototype objects */
switch (obj_builtin_id)
{
#ifndef CONFIG_DISABLE_ARRAY_BUILTIN
case ECMA_BUILTIN_ID_ARRAY_PROTOTYPE:
{
ecma_string_t *length_str_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_str_p,
ECMA_PROPERTY_FLAG_WRITABLE,
NULL);
length_prop_value_p->value = ecma_make_integer_value (0);
ecma_deref_ecma_string (length_str_p);
break;
}
#endif /* !CONFIG_DISABLE_ARRAY_BUILTIN */
#ifndef CONFIG_DISABLE_STRING_BUILTIN
case ECMA_BUILTIN_ID_STRING_PROTOTYPE:
{
ecma_string_t *prim_prop_str_value_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
*prim_value_p = ecma_make_string_value (prim_prop_str_value_p);
break;
}
#endif /* !CONFIG_DISABLE_STRING_BUILTIN */
#ifndef CONFIG_DISABLE_NUMBER_BUILTIN
case ECMA_BUILTIN_ID_NUMBER_PROTOTYPE:
{
ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
*prim_value_p = ecma_make_integer_value (0);
break;
}
#endif /* !CONFIG_DISABLE_NUMBER_BUILTIN */
#ifndef CONFIG_DISABLE_BOOLEAN_BUILTIN
case ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE:
{
ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
*prim_value_p = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
break;
}
#endif /* !CONFIG_DISABLE_BOOLEAN_BUILTIN */
#ifndef CONFIG_DISABLE_DATE_BUILTIN
case ECMA_BUILTIN_ID_DATE_PROTOTYPE:
{
ecma_number_t *prim_prop_num_value_p = ecma_alloc_number ();
*prim_prop_num_value_p = ecma_number_make_nan ();
ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_DATE_FLOAT);
ECMA_SET_INTERNAL_VALUE_POINTER (*prim_value_p, prim_prop_num_value_p);
break;
}
#endif /* !CONFIG_DISABLE_DATE_BUILTIN */
#ifndef CONFIG_DISABLE_REGEXP_BUILTIN
case ECMA_BUILTIN_ID_REGEXP_PROTOTYPE:
{
ecma_value_t *bytecode_prop_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE);
*bytecode_prop_p = ECMA_NULL_POINTER;
break;
}
#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
default:
{
break;
}
}
return obj_p;
} /* ecma_builtin_init_object */
/**
* Instantiate specified ECMA built-in object
*/
static void
ecma_instantiate_builtin (ecma_builtin_id_t id) /**< built-in id */
{
switch (id)
{
#define BUILTIN(builtin_id, \
object_type, \
object_prototype_builtin_id, \
is_extensible, \
is_static, \
lowercase_name) \
case builtin_id: \
{ \
JERRY_ASSERT (JERRY_CONTEXT (ecma_builtin_objects)[builtin_id] == NULL); \
\
ecma_object_t *prototype_obj_p; \
if (object_prototype_builtin_id == ECMA_BUILTIN_ID__COUNT) \
{ \
prototype_obj_p = NULL; \
} \
else \
{ \
if (JERRY_CONTEXT (ecma_builtin_objects)[object_prototype_builtin_id] == NULL) \
{ \
ecma_instantiate_builtin (object_prototype_builtin_id); \
} \
prototype_obj_p = JERRY_CONTEXT (ecma_builtin_objects)[object_prototype_builtin_id]; \
JERRY_ASSERT (prototype_obj_p != NULL); \
} \
\
ecma_object_t *builtin_obj_p = ecma_builtin_init_object (builtin_id, \
prototype_obj_p, \
object_type, \
is_extensible); \
JERRY_CONTEXT (ecma_builtin_objects)[builtin_id] = builtin_obj_p; \
\
break; \
}
#include "ecma-builtins.inc.h"
default:
{
JERRY_ASSERT (id < ECMA_BUILTIN_ID__COUNT);
JERRY_UNREACHABLE (); /* The built-in is not implemented. */
}
}
} /* ecma_instantiate_builtin */
/**
* Finalize ECMA built-in objects
*/
void
ecma_finalize_builtins (void)
{
for (ecma_builtin_id_t id = (ecma_builtin_id_t) 0;
id < ECMA_BUILTIN_ID__COUNT;
id = (ecma_builtin_id_t) (id + 1))
{
if (JERRY_CONTEXT (ecma_builtin_objects)[id] != NULL)
{
ecma_deref_object (JERRY_CONTEXT (ecma_builtin_objects)[id]);
JERRY_CONTEXT (ecma_builtin_objects)[id] = NULL;
}
}
} /* ecma_finalize_builtins */
/**
* Construct a Function object for specified built-in routine
*
* See also: ECMA-262 v5, 15
*
* @return pointer to constructed Function object
*/
static ecma_object_t *
ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t builtin_id, /**< identifier of built-in object */
uint16_t routine_id, /**< builtin-wide identifier of the built-in
* object's routine property */
uint8_t length_prop_value) /**< value of 'length' property */
{
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
ecma_object_t *func_obj_p = ecma_create_object (prototype_obj_p, true, true, ECMA_OBJECT_TYPE_FUNCTION);
ecma_deref_object (prototype_obj_p);
ecma_set_object_is_builtin (func_obj_p);
JERRY_ASSERT (routine_id >= ECMA_BUILTIN_ID__COUNT);
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
ext_func_obj_p->u.built_in.id = builtin_id;
ext_func_obj_p->u.built_in.length = length_prop_value;
ext_func_obj_p->u.built_in.routine_id = routine_id;
ext_func_obj_p->u.built_in.instantiated_bitset = 0;
return func_obj_p;
} /* ecma_builtin_make_function_object_for_routine */
typedef const ecma_builtin_property_descriptor_t *ecma_builtin_property_list_reference_t;
static const ecma_builtin_property_list_reference_t ecma_builtin_property_list_references[] =
{
#define BUILTIN(builtin_id, \
object_type, \
object_prototype_builtin_id, \
is_extensible, \
is_static, \
lowercase_name) \
ecma_builtin_ ## lowercase_name ## _property_descriptor_list,
#include "ecma-builtins.inc.h"
};
/**
* If the property's name is one of built-in properties of the object
* that is not instantiated yet, instantiate the property and
* return pointer to the instantiated property.
*
* @return pointer property, if one was instantiated,
* NULL - otherwise.
*/
ecma_property_t *
ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object */
ecma_string_t *string_p) /**< property's name */
{
JERRY_ASSERT (ecma_get_object_is_builtin (object_p));
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION
&& ecma_builtin_function_is_routine (object_p))
{
if (ecma_string_is_length (string_p))
{
/*
* Lazy instantiation of 'length' property
*
* Note:
* We don't need to mark that the property was already lazy instantiated,
* as it is non-configurable and so can't be deleted
*/
ecma_property_t *len_prop_p;
ecma_property_value_t *len_prop_value_p = ecma_create_named_data_property (object_p,
string_p,
ECMA_PROPERTY_FIXED,
&len_prop_p);
len_prop_value_p->value = ecma_make_integer_value (ext_obj_p->u.built_in.length);
return len_prop_p;
}
return NULL;
}
lit_magic_string_id_t magic_string_id;
if (!ecma_is_string_magic (string_p, &magic_string_id))
{
return NULL;
}
ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ext_obj_p->u.built_in.id;
JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT);
JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id));
const ecma_builtin_property_descriptor_t *property_list_p = ecma_builtin_property_list_references[builtin_id];
const ecma_builtin_property_descriptor_t *curr_property_p = property_list_p;
while (curr_property_p->magic_string_id != magic_string_id)
{
if (curr_property_p->magic_string_id == LIT_MAGIC_STRING__COUNT)
{
return NULL;
}
curr_property_p++;
}
uint32_t index = (uint32_t) (curr_property_p - property_list_p);
JERRY_ASSERT (index < 64);
if (likely (index < 32))
{
uint32_t bit_for_index = (uint32_t) 1u << index;
if (ext_obj_p->u.built_in.instantiated_bitset & bit_for_index)
{
/* This property was instantiated before. */
return NULL;
}
ext_obj_p->u.built_in.instantiated_bitset |= bit_for_index;
}
else
{
uint32_t bit_for_index = (uint32_t) 1u << (index - 32);
ecma_value_t *mask_prop_p = ecma_find_internal_property (object_p,
ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63);
uint32_t instantiated_bitset;
if (mask_prop_p == NULL)
{
mask_prop_p = ecma_create_internal_property (object_p, ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63);
instantiated_bitset = 0;
}
else
{
instantiated_bitset = *mask_prop_p;
if (instantiated_bitset & bit_for_index)
{
/* This property was instantiated before. */
return NULL;
}
}
*mask_prop_p = (instantiated_bitset | bit_for_index);
}
ecma_value_t value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
switch (curr_property_p->type)
{
case ECMA_BUILTIN_PROPERTY_SIMPLE:
{
value = ecma_make_simple_value (curr_property_p->value);
break;
}
case ECMA_BUILTIN_PROPERTY_NUMBER:
{
ecma_number_t num = 0.0;
if (curr_property_p->value < ECMA_BUILTIN_NUMBER_MAX)
{
num = curr_property_p->value;
}
else if (curr_property_p->value < ECMA_BUILTIN_NUMBER_NAN)
{
static const ecma_number_t builtin_number_list[] =
{
ECMA_NUMBER_MAX_VALUE,
ECMA_NUMBER_MIN_VALUE,
ECMA_NUMBER_E,
ECMA_NUMBER_PI,
ECMA_NUMBER_LN10,
ECMA_NUMBER_LN2,
ECMA_NUMBER_LOG2E,
ECMA_NUMBER_LOG10E,
ECMA_NUMBER_SQRT2,
ECMA_NUMBER_SQRT_1_2
};
num = builtin_number_list[curr_property_p->value - ECMA_BUILTIN_NUMBER_MAX];
}
else
{
switch (curr_property_p->value)
{
case ECMA_BUILTIN_NUMBER_NAN:
{
num = ecma_number_make_nan ();
break;
}
case ECMA_BUILTIN_NUMBER_POSITIVE_INFINITY:
{
num = ecma_number_make_infinity (false);
break;
}
case ECMA_BUILTIN_NUMBER_NEGATIVE_INFINITY:
{
num = ecma_number_make_infinity (true);
break;
}
default:
{
JERRY_UNREACHABLE ();
break;
}
}
}
value = ecma_make_number_value (num);
break;
}
case ECMA_BUILTIN_PROPERTY_STRING:
{
value = ecma_make_string_value (ecma_get_magic_string (curr_property_p->value));
break;
}
case ECMA_BUILTIN_PROPERTY_OBJECT:
{
value = ecma_make_object_value (ecma_builtin_get (curr_property_p->value));
break;
}
case ECMA_BUILTIN_PROPERTY_ROUTINE:
{
ecma_object_t *func_obj_p;
func_obj_p = ecma_builtin_make_function_object_for_routine (builtin_id,
ECMA_GET_ROUTINE_ID (curr_property_p->value),
ECMA_GET_ROUTINE_LENGTH (curr_property_p->value));
value = ecma_make_object_value (func_obj_p);
break;
}
default:
{
JERRY_UNREACHABLE ();
return NULL;
}
}
ecma_property_t *prop_p;
ecma_property_value_t *prop_value_p = ecma_create_named_data_property (object_p,
string_p,
curr_property_p->attributes,
&prop_p);
prop_value_p->value = value;
/* Reference count of objects must be decreased. */
if (ecma_is_value_object (value))
{
ecma_free_value (value);
}
return prop_p;
} /* ecma_builtin_try_to_instantiate_property */
/**
* List names of a built-in object's lazy instantiated properties
*
* See also:
* ecma_builtin_try_to_instantiate_property
*/
void
ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in 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_is_builtin (object_p));
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION
&& ecma_builtin_function_is_routine (object_p))
{
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;
/* 'length' property is non-enumerable (ECMA-262 v5, 15) */
ecma_string_t *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);
}
else
{
ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ext_obj_p->u.built_in.id;
JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT);
JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id));
const ecma_builtin_property_descriptor_t *curr_property_p = ecma_builtin_property_list_references[builtin_id];
ecma_length_t index = 0;
uint32_t instantiated_bitset = ext_obj_p->u.built_in.instantiated_bitset;
ecma_collection_header_t *for_non_enumerable_p = (separate_enumerable ? non_enum_collection_p
: main_collection_p);
while (curr_property_p->magic_string_id != LIT_MAGIC_STRING__COUNT)
{
JERRY_ASSERT (index < 64);
if (index == 32)
{
ecma_value_t *mask_prop_p = ecma_find_internal_property (object_p,
ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63);
if (mask_prop_p == NULL)
{
instantiated_bitset = 0;
}
else
{
instantiated_bitset = *mask_prop_p;
}
}
uint32_t bit_for_index;
if (index >= 32)
{
bit_for_index = (uint32_t) 1u << (index - 32);
}
else
{
bit_for_index = (uint32_t) 1u << index;
}
bool was_instantiated = false;
if (instantiated_bitset & bit_for_index)
{
was_instantiated = true;
}
ecma_string_t *name_p = ecma_get_magic_string (curr_property_p->magic_string_id);
if (!was_instantiated || ecma_op_object_has_own_property (object_p, name_p))
{
ecma_append_to_values_collection (for_non_enumerable_p,
ecma_make_string_value (name_p),
true);
}
ecma_deref_ecma_string (name_p);
curr_property_p++;
index++;
}
}
} /* ecma_builtin_list_lazy_property_names */
/**
* Dispatcher of built-in routines
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_dispatch_routine (ecma_builtin_id_t builtin_object_id, /**< built-in object' identifier */
uint16_t builtin_routine_id, /**< builtin-wide identifier
* of the built-in object's
* routine property */
ecma_value_t this_arg_value, /**< 'this' argument value */
const ecma_value_t arguments_list[], /**< list of arguments passed to routine */
ecma_length_t arguments_number) /**< length of arguments' list */
{
switch (builtin_object_id)
{
#define BUILTIN(builtin_id, \
object_type, \
object_prototype_builtin_id, \
is_extensible, \
is_static, \
lowercase_name) \
case builtin_id: \
{ \
return ecma_builtin_ ## lowercase_name ## _dispatch_routine (builtin_routine_id, \
this_arg_value, \
arguments_list, \
arguments_number); \
}
#include "ecma-builtins.inc.h"
case ECMA_BUILTIN_ID__COUNT:
{
JERRY_UNREACHABLE ();
}
default:
{
JERRY_UNREACHABLE (); /* The built-in is not implemented. */
}
}
JERRY_UNREACHABLE ();
} /* ecma_builtin_dispatch_routine */
/**
* Handle calling [[Call]] of built-in object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */
ecma_value_t this_arg_value, /**< 'this' argument value */
const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< arguments list length */
{
JERRY_ASSERT (ecma_get_object_is_builtin (obj_p));
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
if (ecma_builtin_function_is_routine (obj_p))
{
ret_value = ecma_builtin_dispatch_routine (ext_obj_p->u.built_in.id,
ext_obj_p->u.built_in.routine_id,
this_arg_value,
arguments_list_p,
arguments_list_len);
}
else
{
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
switch ((ecma_builtin_id_t) ext_obj_p->u.built_in.id)
{
#define BUILTIN(builtin_id, \
object_type, \
object_prototype_builtin_id, \
is_extensible, \
is_static, \
lowercase_name) \
case builtin_id: \
{ \
if (object_type == ECMA_OBJECT_TYPE_FUNCTION) \
{ \
ret_value = ecma_builtin_ ## lowercase_name ## _dispatch_call (arguments_list_p, \
arguments_list_len); \
} \
break; \
}
#include "ecma-builtins.inc.h"
case ECMA_BUILTIN_ID__COUNT:
{
JERRY_UNREACHABLE ();
}
default:
{
JERRY_UNREACHABLE (); /* The built-in is not implemented. */
}
}
}
JERRY_ASSERT (!ecma_is_value_empty (ret_value));
return ret_value;
} /* ecma_builtin_dispatch_call */
/**
* Handle calling [[Construct]] of built-in object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */
const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< arguments list length */
{
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
JERRY_ASSERT (ecma_get_object_is_builtin (obj_p));
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
switch (ext_obj_p->u.built_in.id)
{
#define BUILTIN(builtin_id, \
object_type, \
object_prototype_builtin_id, \
is_extensible, \
is_static, \
lowercase_name) \
case builtin_id: \
{ \
if (object_type == ECMA_OBJECT_TYPE_FUNCTION) \
{ \
ret_value = ecma_builtin_ ## lowercase_name ## _dispatch_construct (arguments_list_p, \
arguments_list_len); \
} \
break; \
}
#include "ecma-builtins.inc.h"
case ECMA_BUILTIN_ID__COUNT:
{
JERRY_UNREACHABLE ();
}
default:
{
JERRY_UNREACHABLE (); /* The built-in is not implemented. */
}
}
JERRY_ASSERT (!ecma_is_value_empty (ret_value));
return ret_value;
} /* ecma_builtin_dispatch_construct */
/**
* @}
* @}
*/

View file

@ -0,0 +1,75 @@
/* 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_BUILTINS_H
#define ECMA_BUILTINS_H
#include "ecma-globals.h"
/**
* A built-in object's identifier
*/
typedef enum
{
#define BUILTIN(builtin_id, \
object_type, \
object_prototype_builtin_id, \
is_extensible, \
is_static, \
lowercase_name) \
builtin_id,
#include "ecma-builtins.inc.h"
ECMA_BUILTIN_ID__COUNT /**< number of built-in objects */
} ecma_builtin_id_t;
/**
* Construct a routine value
*/
#define ECMA_ROUTINE_VALUE(id, length) (((id) << 4) | length)
/**
* Get routine length
*/
#define ECMA_GET_ROUTINE_LENGTH(value) ((uint8_t) ((value) & 0xf))
/**
* Get routine ID
*/
#define ECMA_GET_ROUTINE_ID(value) ((uint16_t) ((value) >> 4))
/* ecma-builtins.c */
extern void ecma_finalize_builtins (void);
extern ecma_value_t
ecma_builtin_dispatch_call (ecma_object_t *, ecma_value_t,
const ecma_value_t *, ecma_length_t);
extern ecma_value_t
ecma_builtin_dispatch_construct (ecma_object_t *,
const ecma_value_t *, ecma_length_t);
extern ecma_property_t *
ecma_builtin_try_to_instantiate_property (ecma_object_t *, ecma_string_t *);
extern void
ecma_builtin_list_lazy_property_names (ecma_object_t *,
bool,
ecma_collection_header_t *,
ecma_collection_header_t *);
extern bool
ecma_builtin_is (ecma_object_t *, ecma_builtin_id_t);
extern ecma_object_t *
ecma_builtin_get (ecma_builtin_id_t);
extern bool
ecma_builtin_function_is_routine (ecma_object_t *);
#endif /* !ECMA_BUILTINS_H */

Some files were not shown because too many files have changed in this diff Show more