Create extended objects instead of internal properties.

Several internal properties are removed and directly stored as
part of the object. Faster built-in and JS function processing.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2016-06-21 06:12:17 -07:00
parent 7f153c799a
commit 1726bba184
22 changed files with 273 additions and 280 deletions
+25 -3
View File
@@ -30,6 +30,8 @@ JERRY_STATIC_ASSERT (sizeof (ecma_property_pair_t) == sizeof (uint64_t) * 2,
JERRY_STATIC_ASSERT (sizeof (ecma_object_t) <= sizeof (uint64_t), JERRY_STATIC_ASSERT (sizeof (ecma_object_t) <= sizeof (uint64_t),
size_of_ecma_object_t_must_be_less_than_or_equal_to_8_bytes); size_of_ecma_object_t_must_be_less_than_or_equal_to_8_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_extended_object_t) <= sizeof (uint64_t) * 2,
size_of_ecma_extended_object_t_must_be_less_than_or_equal_to_16_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_collection_header_t) == sizeof (uint64_t), JERRY_STATIC_ASSERT (sizeof (ecma_collection_header_t) == sizeof (uint64_t),
size_of_ecma_collection_header_t_must_be_less_than_or_equal_to_8_bytes); size_of_ecma_collection_header_t_must_be_less_than_or_equal_to_8_bytes);
@@ -96,21 +98,41 @@ DECLARE_ROUTINES_FOR (string)
DECLARE_ROUTINES_FOR (getter_setter_pointers) DECLARE_ROUTINES_FOR (getter_setter_pointers)
DECLARE_ROUTINES_FOR (external_pointer) 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 * Allocate memory for ecma-property pair
* *
* @return pointer to allocated memory * @return pointer to allocated memory
*/ */
ecma_property_pair_t * inline ecma_property_pair_t * __attr_always_inline___
ecma_alloc_property_pair (void) ecma_alloc_property_pair (void)
{ {
return jmem_heap_alloc_block (sizeof (ecma_property_pair_t)); return jmem_heap_alloc_block (sizeof (ecma_property_pair_t));
} /* ecma_alloc_property_pair */ } /* ecma_alloc_property_pair */
/** /**
* Dealloc memory from an ecma-property * Dealloc memory of an ecma-property
*/ */
extern void inline void __attr_always_inline___
ecma_dealloc_property_pair (ecma_property_pair_t *property_pair_p) /**< property pair to be freed */ 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)); jmem_heap_free_block (property_pair_p, sizeof (ecma_property_pair_t));
+12
View File
@@ -109,6 +109,18 @@ extern ecma_external_pointer_t *ecma_alloc_external_pointer (void);
*/ */
extern void ecma_dealloc_external_pointer (ecma_external_pointer_t *); 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 * Allocate memory for ecma-property pair
* *
+34 -6
View File
@@ -245,15 +245,10 @@ ecma_gc_mark_property (ecma_property_t *property_p) /**< property */
case ECMA_INTERNAL_PROPERTY_ECMA_VALUE: /* an ecma_value_t except object */ 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_DATE_FLOAT: /* pointer to a ecma_number_t */
case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */ case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */
case ECMA_INTERNAL_PROPERTY_CODE_BYTECODE: /* pointer to a bytecode array */
case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE: /* pointer to a regexp bytecode array */ case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE: /* pointer to a regexp bytecode array */
case ECMA_INTERNAL_PROPERTY_NATIVE_CODE: /* an external pointer */
case ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE: /* an external pointer */ 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_FREE_CALLBACK: /* an object's native free callback */
case ECMA_INTERNAL_PROPERTY_BUILT_IN_ID: /* an integer */ case ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63: /* an integer (bit-mask) */
case ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC: /* an integer */
case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31: /* an integer (bit-mask) */
case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63: /* an integer (bit-mask) */
{ {
break; break;
} }
@@ -355,6 +350,17 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
{ {
ecma_gc_set_object_visited (proto_p, true); 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) if (traverse_properties)
@@ -470,6 +476,28 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
JERRY_ASSERT (ecma_gc_objects_number > 0); JERRY_ASSERT (ecma_gc_objects_number > 0);
ecma_gc_objects_number--; 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_dealloc_object (object_p);
} /* ecma_gc_sweep */ } /* ecma_gc_sweep */
+46 -22
View File
@@ -178,6 +178,11 @@ typedef int32_t ecma_integer_value_t;
#define ECMA_IS_VALUE_ERROR(value) \ #define ECMA_IS_VALUE_ERROR(value) \
(unlikely ((value & ECMA_VALUE_ERROR_FLAG) != 0)) (unlikely ((value & ECMA_VALUE_ERROR_FLAG) != 0))
/**
* Representation for native external pointer
*/
typedef uintptr_t ecma_external_pointer_t;
/** /**
* Internal properties' identifiers. * Internal properties' identifiers.
*/ */
@@ -186,10 +191,8 @@ typedef enum
ECMA_INTERNAL_PROPERTY_CLASS, /**< [[Class]] */ ECMA_INTERNAL_PROPERTY_CLASS, /**< [[Class]] */
ECMA_INTERNAL_PROPERTY_SCOPE, /**< [[Scope]] */ ECMA_INTERNAL_PROPERTY_SCOPE, /**< [[Scope]] */
ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP, /**< [[ParametersMap]] */ ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP, /**< [[ParametersMap]] */
ECMA_INTERNAL_PROPERTY_CODE_BYTECODE, /**< pointer to compact bytecode array */
ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE, /**< pointer to RegExp bytecode array */ ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE, /**< pointer to RegExp bytecode array */
ECMA_INTERNAL_PROPERTY_NATIVE_CODE, /**< native handler location descriptor */
ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE, /**< native handle associated with an object */ ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE, /**< native handle associated with an object */
ECMA_INTERNAL_PROPERTY_FREE_CALLBACK, /**< object's native free callback */ ECMA_INTERNAL_PROPERTY_FREE_CALLBACK, /**< object's native free callback */
ECMA_INTERNAL_PROPERTY_ECMA_VALUE, /**< [[Primitive value]] for String, Number, and Boolean */ ECMA_INTERNAL_PROPERTY_ECMA_VALUE, /**< [[Primitive value]] for String, Number, and Boolean */
@@ -200,20 +203,8 @@ typedef enum
ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_THIS, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_THIS,
ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS,
ECMA_INTERNAL_PROPERTY_BUILT_IN_ID, /**< Implementation-defined identifier of built-in object */ ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63, /**< Bit-mask of non-instantiated
* built-in's properties (bits 32-63) */
ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC, /**< Implementation-defined identifier of built-in routine
* that corresponds to a built-in function object
* ([[Built-in routine's description]])
*/
ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31, /**< Bit-mask of non-instantiated
* built-in's properties (bits 0-31)
*/
ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63, /**< Bit-mask of non-instantiated
* built-in's properties (bits 32-63)
*/
ECMA_INTERNAL_PROPERTY__COUNT /**< Number of internal properties' types */ ECMA_INTERNAL_PROPERTY__COUNT /**< Number of internal properties' types */
} ecma_internal_property_id_t; } ecma_internal_property_id_t;
@@ -526,6 +517,44 @@ typedef struct ecma_object_t
jmem_cpointer_t prototype_or_outer_reference_cp; jmem_cpointer_t prototype_or_outer_reference_cp;
} ecma_object_t; } ecma_object_t;
/**
* Description of extended ECMA-object.
*
* The extended object is an object with extra fields.
*/
typedef struct
{
ecma_object_t object; /**< object header */
/*
* Description of extra fields. These extra fields depends on the object type.
*/
union
{
/*
* Description of built-in objects.
*/
struct
{
uint8_t id; /**< built-in id */
uint8_t length; /**< length for built-in functions */
uint16_t routine_id; /**< routine id for built-in functions */
uint32_t instantiated_bitset; /**< bit set for instantiated properties */
} built_in;
/*
* Description of function objects.
*/
struct
{
ecma_value_t scope_cp; /**< function scope */
ecma_value_t bytecode_cp; /**< function byte code */
} function;
ecma_external_pointer_t external_function; /**< external function */
} u;
} ecma_extended_object_t;
/** /**
* Description of ECMA property descriptor * Description of ECMA property descriptor
* *
@@ -870,14 +899,9 @@ typedef struct ecma_string_t
} u; } u;
} ecma_string_t; } ecma_string_t;
/**
* Representation for native external pointer
*/
typedef uintptr_t ecma_external_pointer_t;
/** /**
* Compiled byte code data. * Compiled byte code data.
*/ */
typedef struct typedef struct
{ {
uint16_t size; /**< real size >> JMEM_ALIGNMENT_LOG */ uint16_t size; /**< real size >> JMEM_ALIGNMENT_LOG */
@@ -30,7 +30,6 @@
* *
* Note: * Note:
* property identifier should be one of the following: * property identifier should be one of the following:
* - ECMA_INTERNAL_PROPERTY_NATIVE_CODE;
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE; * - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE;
* - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK. * - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK.
* *
@@ -43,8 +42,7 @@ ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to crea
* property to create */ * property to create */
ecma_external_pointer_t ptr_value) /**< value to store in the property */ ecma_external_pointer_t ptr_value) /**< value to store in the property */
{ {
JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_CODE JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
|| id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
|| id == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK); || id == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK);
bool is_new; bool is_new;
@@ -96,7 +94,6 @@ ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to crea
* *
* Note: * Note:
* property identifier should be one of the following: * property identifier should be one of the following:
* - ECMA_INTERNAL_PROPERTY_NATIVE_CODE;
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE; * - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE;
* - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK. * - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK.
* *
@@ -109,8 +106,7 @@ ecma_get_external_pointer_value (ecma_object_t *obj_p, /**< object to get proper
* to get value from */ * to get value from */
ecma_external_pointer_t *out_pointer_p) /**< [out] value of the external pointer */ ecma_external_pointer_t *out_pointer_p) /**< [out] value of the external pointer */
{ {
JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_CODE JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
|| id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
|| id == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK); || id == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK);
ecma_property_t *prop_p = ecma_find_internal_property (obj_p, id); ecma_property_t *prop_p = ecma_find_internal_property (obj_p, id);
@@ -142,15 +138,13 @@ ecma_get_external_pointer_value (ecma_object_t *obj_p, /**< object to get proper
* *
* Note: * Note:
* property identifier should be one of the following: * property identifier should be one of the following:
* - ECMA_INTERNAL_PROPERTY_NATIVE_CODE;
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE; * - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE;
* - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK. * - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK.
*/ */
void void
ecma_free_external_pointer_in_property (ecma_property_t *prop_p) /**< internal property */ 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_CODE 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_NATIVE_HANDLE
|| ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_p) == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK); || ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_p) == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK);
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY #ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
+4 -12
View File
@@ -90,10 +90,12 @@ JERRY_STATIC_ASSERT ((ECMA_OBJECT_MAX_REF | (ECMA_OBJECT_REF_ONE - 1)) == UINT16
*/ */
ecma_object_t * ecma_object_t *
ecma_create_object (ecma_object_t *prototype_object_p, /**< pointer to prototybe of the object (or NULL) */ ecma_create_object (ecma_object_t *prototype_object_p, /**< pointer to prototybe of the object (or NULL) */
bool is_extended, /**< extended object */
bool is_extensible, /**< value of extensible attribute */ bool is_extensible, /**< value of extensible attribute */
ecma_object_type_t type) /**< object type */ ecma_object_type_t type) /**< object type */
{ {
ecma_object_t *new_object_p = ecma_alloc_object (); ecma_object_t *new_object_p = (is_extended ? ((ecma_object_t *) ecma_alloc_extended_object ())
: ecma_alloc_object ());
uint16_t type_flags = (uint16_t) type; uint16_t type_flags = (uint16_t) type;
@@ -805,7 +807,6 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
break; break;
} }
case ECMA_INTERNAL_PROPERTY_NATIVE_CODE: /* an external pointer */
case ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE: /* an external pointer */ case ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE: /* an external pointer */
case ECMA_INTERNAL_PROPERTY_FREE_CALLBACK: /* an external pointer */ case ECMA_INTERNAL_PROPERTY_FREE_CALLBACK: /* an external pointer */
{ {
@@ -817,10 +818,7 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */ case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */
case ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP: /* an object */ case ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP: /* an object */
case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */ case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */
case ECMA_INTERNAL_PROPERTY_BUILT_IN_ID: /* an integer */ case ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63: /* an integer (bit-mask) */
case ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC: /* an integer */
case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31: /* an integer (bit-mask) */
case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63: /* an integer (bit-mask) */
case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION: case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION:
{ {
break; break;
@@ -850,12 +848,6 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
break; break;
} }
case ECMA_INTERNAL_PROPERTY_CODE_BYTECODE: /* compressed pointer to a bytecode array */
{
ecma_bytecode_deref (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, property_value));
break;
}
case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE: /* compressed pointer to a regexp bytecode array */ case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE: /* compressed pointer to a regexp bytecode array */
{ {
ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, property_value); ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, property_value);
+1 -1
View File
@@ -246,7 +246,7 @@ extern bool
ecma_collection_iterator_next (ecma_collection_iterator_t *); ecma_collection_iterator_next (ecma_collection_iterator_t *);
/* ecma-helpers.c */ /* ecma-helpers.c */
extern ecma_object_t *ecma_create_object (ecma_object_t *, bool, ecma_object_type_t); 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_decl_lex_env (ecma_object_t *);
extern ecma_object_t *ecma_create_object_lex_env (ecma_object_t *, ecma_object_t *, bool); 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_is_lexical_environment (const ecma_object_t *) __attr_pure___;
@@ -481,6 +481,7 @@ ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**<
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_DATE_PROTOTYPE); 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, ecma_object_t *obj_p = ecma_create_object (prototype_obj_p,
false,
true, true,
ECMA_OBJECT_TYPE_GENERAL); ECMA_OBJECT_TYPE_GENERAL);
ecma_deref_object (prototype_obj_p); ecma_deref_object (prototype_obj_p);
@@ -237,7 +237,10 @@ ecma_builtin_function_prototype_object_bind (ecma_value_t this_arg, /**< this ar
{ {
/* 4. 11. 18. */ /* 4. 11. 18. */
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE); 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, true, ECMA_OBJECT_TYPE_BOUND_FUNCTION); ecma_object_t *function_p = ecma_create_object (prototype_obj_p,
false,
true,
ECMA_OBJECT_TYPE_BOUND_FUNCTION);
ecma_deref_object (prototype_obj_p); ecma_deref_object (prototype_obj_p);
@@ -23,44 +23,6 @@
#include "ecma-builtins.h" #include "ecma-builtins.h"
#include "ecma-globals.h" #include "ecma-globals.h"
/**
* Position of built-in object's id field in [[Built-in routine's description]] internal property
*/
#define ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_POS (0)
/**
* Width of built-in object's id field in [[Built-in routine's description]] internal property
*/
#define ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_WIDTH (8)
/**
* Position of built-in routine's id field in [[Built-in routine's description]] internal property
*/
#define ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_POS \
(ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_POS + \
ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_WIDTH)
/**
* Width of built-in routine's id field in [[Built-in routine's description]] internal property
*/
#define ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_WIDTH (16)
/**
* Position of built-in routine's length field in [[Built-in routine's description]] internal property
*/
#define ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_POS \
(ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_POS + \
ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_WIDTH)
/**
* Width of built-in routine's id field in [[Built-in routine's description]] internal property
*/
#define ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_WIDTH (8)
/* ecma-builtins.c */
extern ecma_object_t *
ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t, uint16_t, uint8_t);
/** /**
* Type of built-in properties. * Type of built-in properties.
*/ */
+104 -146
View File
@@ -101,7 +101,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
ecma_object_type_t obj_type, /**< object's type */ ecma_object_type_t obj_type, /**< object's type */
bool is_extensible) /**< value of object's [[Extensible]] property */ bool is_extensible) /**< value of object's [[Extensible]] property */
{ {
ecma_object_t *object_obj_p = ecma_create_object (prototype_obj_p, is_extensible, obj_type); 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. * [[Class]] property of built-in object is not stored explicitly.
@@ -109,11 +109,11 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
* See also: ecma_object_get_class_name * See also: ecma_object_get_class_name
*/ */
ecma_property_t *built_in_id_prop_p = ecma_create_internal_property (object_obj_p, ecma_set_object_is_builtin (obj_p);
ECMA_INTERNAL_PROPERTY_BUILT_IN_ID);
ecma_set_internal_property_value (built_in_id_prop_p, obj_builtin_id);
ecma_set_object_is_builtin (object_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.instantiated_bitset = 0;
/** Initializing [[PrimitiveValue]] properties of built-in prototype objects */ /** Initializing [[PrimitiveValue]] properties of built-in prototype objects */
switch (obj_builtin_id) switch (obj_builtin_id)
@@ -124,7 +124,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
ecma_string_t *prim_prop_str_value_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); ecma_string_t *prim_prop_str_value_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
ecma_property_t *prim_value_prop_p; ecma_property_t *prim_value_prop_p;
prim_value_prop_p = ecma_create_internal_property (object_obj_p, prim_value_prop_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_ECMA_VALUE); ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
ecma_set_internal_property_value (prim_value_prop_p, ecma_make_string_value (prim_prop_str_value_p)); ecma_set_internal_property_value (prim_value_prop_p, ecma_make_string_value (prim_prop_str_value_p));
break; break;
@@ -135,7 +135,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
case ECMA_BUILTIN_ID_NUMBER_PROTOTYPE: case ECMA_BUILTIN_ID_NUMBER_PROTOTYPE:
{ {
ecma_property_t *prim_value_prop_p; ecma_property_t *prim_value_prop_p;
prim_value_prop_p = ecma_create_internal_property (object_obj_p, prim_value_prop_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_ECMA_VALUE); ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
ecma_set_internal_property_value (prim_value_prop_p, ecma_make_integer_value (0)); ecma_set_internal_property_value (prim_value_prop_p, ecma_make_integer_value (0));
break; break;
@@ -146,7 +146,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
case ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE: case ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE:
{ {
ecma_property_t *prim_value_prop_p; ecma_property_t *prim_value_prop_p;
prim_value_prop_p = ecma_create_internal_property (object_obj_p, prim_value_prop_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_ECMA_VALUE); ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
ecma_set_internal_property_value (prim_value_prop_p, ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE)); ecma_set_internal_property_value (prim_value_prop_p, ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE));
break; break;
@@ -160,7 +160,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
*prim_prop_num_value_p = ecma_number_make_nan (); *prim_prop_num_value_p = ecma_number_make_nan ();
ecma_property_t *prim_value_prop_p; ecma_property_t *prim_value_prop_p;
prim_value_prop_p = ecma_create_internal_property (object_obj_p, prim_value_prop_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_DATE_FLOAT); ECMA_INTERNAL_PROPERTY_DATE_FLOAT);
ECMA_SET_INTERNAL_VALUE_POINTER (ECMA_PROPERTY_VALUE_PTR (prim_value_prop_p)->value, prim_prop_num_value_p); ECMA_SET_INTERNAL_VALUE_POINTER (ECMA_PROPERTY_VALUE_PTR (prim_value_prop_p)->value, prim_prop_num_value_p);
break; break;
@@ -171,7 +171,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
case ECMA_BUILTIN_ID_REGEXP_PROTOTYPE: case ECMA_BUILTIN_ID_REGEXP_PROTOTYPE:
{ {
ecma_property_t *bytecode_prop_p; ecma_property_t *bytecode_prop_p;
bytecode_prop_p = ecma_create_internal_property (object_obj_p, bytecode_prop_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE);
ecma_set_internal_property_value (bytecode_prop_p, ECMA_NULL_POINTER); ecma_set_internal_property_value (bytecode_prop_p, ECMA_NULL_POINTER);
break; break;
@@ -183,7 +183,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
} }
} }
return object_obj_p; return obj_p;
} /* ecma_builtin_init_object */ } /* ecma_builtin_init_object */
/** /**
@@ -270,6 +270,36 @@ ecma_finalize_builtins (void)
} }
} /* ecma_finalize_builtins */ } /* 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_BUILT_IN_FUNCTION);
ecma_deref_object (prototype_obj_p);
ecma_set_object_is_builtin (func_obj_p);
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; 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[] = static const ecma_builtin_property_list_reference_t ecma_builtin_property_list_references[] =
@@ -318,21 +348,14 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
* as it is non-configurable and so can't be deleted * as it is non-configurable and so can't be deleted
*/ */
ecma_property_t *desc_prop_p = ecma_get_internal_property (object_p, ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC);
uint64_t builtin_routine_desc = ecma_get_internal_property_value (desc_prop_p);
JERRY_STATIC_ASSERT (sizeof (uint8_t) * JERRY_BITSINBYTE == ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_WIDTH,
bits_in_uint8_t_must_be_equal_to_ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_WIDTH);
uint8_t length_prop_value = (uint8_t) JRT_EXTRACT_BIT_FIELD (uint64_t, builtin_routine_desc,
ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_POS,
ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_WIDTH);
ecma_property_t *len_prop_p = ecma_create_named_data_property (object_p, ecma_property_t *len_prop_p = ecma_create_named_data_property (object_p,
string_p, string_p,
ECMA_PROPERTY_FIXED); ECMA_PROPERTY_FIXED);
ecma_set_named_data_property_value (len_prop_p, ecma_make_integer_value (length_prop_value)); ecma_set_named_data_property_value (len_prop_p,
ecma_make_integer_value (ext_obj_p->u.built_in.length));
JERRY_ASSERT (!ecma_is_property_configurable (len_prop_p)); JERRY_ASSERT (!ecma_is_property_configurable (len_prop_p));
return len_prop_p; return len_prop_p;
@@ -348,10 +371,9 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
return NULL; return NULL;
} }
ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (object_p, ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
ECMA_INTERNAL_PROPERTY_BUILT_IN_ID);
ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ecma_get_internal_property_value (built_in_id_prop_p); 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 (builtin_id < ECMA_BUILTIN_ID__COUNT);
JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id)); JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id));
@@ -373,42 +395,46 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
JERRY_ASSERT (index < 64); JERRY_ASSERT (index < 64);
uint32_t bit_for_index;
ecma_internal_property_id_t mask_prop_id;
if (likely (index < 32)) if (likely (index < 32))
{ {
mask_prop_id = ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31; uint32_t bit_for_index = (uint32_t) 1u << index;
bit_for_index = (uint32_t) 1u << index;
}
else
{
mask_prop_id = ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63;
bit_for_index = (uint32_t) 1u << (index - 32);
}
ecma_property_t *mask_prop_p = ecma_find_internal_property (object_p, mask_prop_id); if (ext_obj_p->u.built_in.instantiated_bitset & bit_for_index)
uint32_t instantiated_bitset;
if (mask_prop_p == NULL)
{
mask_prop_p = ecma_create_internal_property (object_p, mask_prop_id);
instantiated_bitset = 0;
}
else
{
instantiated_bitset = ecma_get_internal_property_value (mask_prop_p);
if (instantiated_bitset & bit_for_index)
{ {
/* This property was instantiated before. */ /* This property was instantiated before. */
return NULL; 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_property_t *mask_prop_p = ecma_find_internal_property (object_p,
ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63);
instantiated_bitset |= bit_for_index; uint32_t instantiated_bitset;
ecma_set_internal_property_value (mask_prop_p, 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 = ecma_get_internal_property_value (mask_prop_p);
if (instantiated_bitset & bit_for_index)
{
/* This property was instantiated before. */
return NULL;
}
}
instantiated_bitset |= bit_for_index;
ecma_set_internal_property_value (mask_prop_p, instantiated_bitset);
}
ecma_value_t value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); ecma_value_t value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
@@ -549,9 +575,9 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
} }
else else
{ {
ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (object_p, ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
ECMA_INTERNAL_PROPERTY_BUILT_IN_ID);
ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ecma_get_internal_property_value (built_in_id_prop_p); 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 (builtin_id < ECMA_BUILTIN_ID__COUNT);
JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id)); JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id));
@@ -559,8 +585,7 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
const ecma_builtin_property_descriptor_t *curr_property_p = ecma_builtin_property_list_references[builtin_id]; const ecma_builtin_property_descriptor_t *curr_property_p = ecma_builtin_property_list_references[builtin_id];
ecma_length_t index = 0; ecma_length_t index = 0;
ecma_internal_property_id_t mask_prop_id = ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31; uint32_t instantiated_bitset = ext_obj_p->u.built_in.instantiated_bitset;
ecma_property_t *mask_prop_p = ecma_find_internal_property (object_p, mask_prop_id);
ecma_collection_header_t *for_non_enumerable_p = (separate_enumerable ? non_enum_collection_p ecma_collection_header_t *for_non_enumerable_p = (separate_enumerable ? non_enum_collection_p
: main_collection_p); : main_collection_p);
@@ -571,8 +596,17 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
if (index == 32) if (index == 32)
{ {
ecma_internal_property_id_t mask_prop_id = ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63; ecma_property_t *mask_prop_p = ecma_find_internal_property (object_p,
mask_prop_p = ecma_find_internal_property (object_p, mask_prop_id); ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63);
if (mask_prop_p == NULL)
{
instantiated_bitset = 0;
}
else
{
instantiated_bitset = ecma_get_internal_property_value (mask_prop_p);
}
} }
uint32_t bit_for_index; uint32_t bit_for_index;
@@ -585,16 +619,11 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
bit_for_index = (uint32_t) 1u << index; bit_for_index = (uint32_t) 1u << index;
} }
bool was_instantiated = true; bool was_instantiated = false;
if (mask_prop_p != NULL) if (instantiated_bitset & bit_for_index)
{ {
uint32_t instantiated_bitset = ecma_get_internal_property_value (mask_prop_p); was_instantiated = true;
if (!(instantiated_bitset & bit_for_index))
{
was_instantiated = false;
}
} }
ecma_string_t *name_p = ecma_get_magic_string (curr_property_p->magic_string_id); ecma_string_t *name_p = ecma_get_magic_string (curr_property_p->magic_string_id);
@@ -614,52 +643,6 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
} }
} /* ecma_builtin_list_lazy_property_names */ } /* ecma_builtin_list_lazy_property_names */
/**
* Construct a Function object for specified built-in routine
*
* See also: ECMA-262 v5, 15
*
* @return pointer to constructed Function object
*/
ecma_object_t *
ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t builtin_id, /**< identifier of built-in object
that initially contains property
with the routine */
uint16_t routine_id, /**< builtin-wide identifier of the built-in
object's routine property */
uint8_t length_prop_value) /**< value of 'length' property
of function object to create */
{
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, ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION);
ecma_deref_object (prototype_obj_p);
ecma_set_object_is_builtin (func_obj_p);
uint64_t packed_value = JRT_SET_BIT_FIELD_VALUE (uint64_t, 0ull,
builtin_id,
ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_POS,
ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_WIDTH);
packed_value = JRT_SET_BIT_FIELD_VALUE (uint64_t, packed_value,
routine_id,
ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_POS,
ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_WIDTH);
packed_value = JRT_SET_BIT_FIELD_VALUE (uint64_t, packed_value,
length_prop_value,
ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_POS,
ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_WIDTH);
ecma_property_t *routine_desc_prop_p = ecma_create_internal_property (func_obj_p,
ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC);
JERRY_ASSERT (packed_value <= UINT32_MAX);
ecma_set_internal_property_value (routine_desc_prop_p, (uint32_t) packed_value);
return func_obj_p;
} /* ecma_builtin_make_function_object_for_routine */
/** /**
* Handle calling [[Call]] of built-in object * Handle calling [[Call]] of built-in object
* *
@@ -674,43 +657,21 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */
JERRY_ASSERT (ecma_get_object_is_builtin (obj_p)); JERRY_ASSERT (ecma_get_object_is_builtin (obj_p));
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); 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_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION) if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION)
{ {
ecma_property_t *desc_prop_p = ecma_get_internal_property (obj_p, ret_value = ecma_builtin_dispatch_routine (ext_obj_p->u.built_in.id,
ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC); ext_obj_p->u.built_in.routine_id,
uint64_t builtin_routine_desc = ecma_get_internal_property_value (desc_prop_p); this_arg_value,
arguments_list_p,
uint64_t built_in_id_field = JRT_EXTRACT_BIT_FIELD (uint64_t, builtin_routine_desc, arguments_list_len);
ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_POS,
ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_WIDTH);
JERRY_ASSERT (built_in_id_field < ECMA_BUILTIN_ID__COUNT);
uint64_t routine_id_field = JRT_EXTRACT_BIT_FIELD (uint64_t, builtin_routine_desc,
ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_POS,
ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_WIDTH);
JERRY_ASSERT (routine_id_field <= UINT16_MAX);
ecma_builtin_id_t built_in_id = (ecma_builtin_id_t) built_in_id_field;
uint16_t routine_id = (uint16_t) routine_id_field;
ret_value = ecma_builtin_dispatch_routine (built_in_id,
routine_id,
this_arg_value,
arguments_list_p,
arguments_list_len);
} }
else else
{ {
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (obj_p, switch ((ecma_builtin_id_t) ext_obj_p->u.built_in.id)
ECMA_INTERNAL_PROPERTY_BUILT_IN_ID);
ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ecma_get_internal_property_value (built_in_id_prop_p);
JERRY_ASSERT (ecma_builtin_is (obj_p, builtin_id));
switch (builtin_id)
{ {
#define BUILTIN(builtin_id, \ #define BUILTIN(builtin_id, \
object_type, \ object_type, \
@@ -765,14 +726,11 @@ ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (obj_p, ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
ECMA_INTERNAL_PROPERTY_BUILT_IN_ID);
ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ecma_get_internal_property_value (built_in_id_prop_p);
JERRY_ASSERT (ecma_builtin_is (obj_p, builtin_id));
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
switch (builtin_id)
switch (ext_obj_p->u.built_in.id)
{ {
#define BUILTIN(builtin_id, \ #define BUILTIN(builtin_id, \
object_type, \ object_type, \
@@ -90,7 +90,11 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of
ecma_object_t *array_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); ecma_object_t *array_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ARRAY_BUILTIN */ #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ARRAY_BUILTIN */
ecma_object_t *obj_p = ecma_create_object (array_prototype_obj_p, true, ECMA_OBJECT_TYPE_ARRAY); ecma_object_t *obj_p = ecma_create_object (array_prototype_obj_p,
false,
true,
ECMA_OBJECT_TYPE_ARRAY);
ecma_deref_object (array_prototype_obj_p); ecma_deref_object (array_prototype_obj_p);
/* /*
@@ -49,9 +49,7 @@ ecma_op_create_boolean_object (ecma_value_t arg) /**< argument passed to the Boo
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN */ #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN */
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
true,
ECMA_OBJECT_TYPE_GENERAL);
ecma_deref_object (prototype_obj_p); ecma_deref_object (prototype_obj_p);
ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
@@ -88,6 +88,7 @@ ecma_new_standard_error (ecma_standard_error_t error_type) /**< native error typ
ecma_object_t *prototype_obj_p = ecma_builtin_get (prototype_id); ecma_object_t *prototype_obj_p = ecma_builtin_get (prototype_id);
ecma_object_t *new_error_obj_p = ecma_create_object (prototype_obj_p, ecma_object_t *new_error_obj_p = ecma_create_object (prototype_obj_p,
false,
true, true,
ECMA_OBJECT_TYPE_GENERAL); ECMA_OBJECT_TYPE_GENERAL);
@@ -148,7 +148,7 @@ ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
// 1., 4., 13. // 1., 4., 13.
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE); ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
ecma_object_t *f = ecma_create_object (prototype_obj_p, true, ECMA_OBJECT_TYPE_FUNCTION); ecma_object_t *func_p = ecma_create_object (prototype_obj_p, true, true, ECMA_OBJECT_TYPE_FUNCTION);
ecma_deref_object (prototype_obj_p); ecma_deref_object (prototype_obj_p);
@@ -166,13 +166,13 @@ ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
* See also: ecma_object_get_class_name * See also: ecma_object_get_class_name
*/ */
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_p;
// 9. // 9.
ecma_property_t *scope_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_SCOPE); ECMA_SET_INTERNAL_VALUE_POINTER (ext_func_p->u.function.scope_cp, scope_p);
ECMA_SET_INTERNAL_VALUE_POINTER (ECMA_PROPERTY_VALUE_PTR (scope_prop_p)->value, scope_p);
// 10., 11., 12. // 10., 11., 12.
ecma_property_t *bytecode_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE); ECMA_SET_INTERNAL_VALUE_POINTER (ext_func_p->u.function.bytecode_cp, bytecode_data_p);
ECMA_SET_INTERNAL_VALUE_POINTER (ECMA_PROPERTY_VALUE_PTR (bytecode_prop_p)->value, bytecode_data_p);
ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p); ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p);
// 14., 15., 16., 17., 18. // 14., 15., 16., 17., 18.
@@ -204,14 +204,14 @@ ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
} }
ecma_string_t *magic_string_caller_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLER); ecma_string_t *magic_string_caller_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLER);
ecma_op_object_define_own_property (f, ecma_op_object_define_own_property (func_p,
magic_string_caller_p, magic_string_caller_p,
&prop_desc, &prop_desc,
false); false);
ecma_deref_ecma_string (magic_string_caller_p); ecma_deref_ecma_string (magic_string_caller_p);
ecma_string_t *magic_string_arguments_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS); ecma_string_t *magic_string_arguments_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS);
ecma_op_object_define_own_property (f, ecma_op_object_define_own_property (func_p,
magic_string_arguments_p, magic_string_arguments_p,
&prop_desc, &prop_desc,
false); false);
@@ -220,7 +220,7 @@ ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
ecma_deref_object (thrower_p); ecma_deref_object (thrower_p);
} }
return f; return func_p;
} /* ecma_op_create_function_object */ } /* ecma_op_create_function_object */
/** /**
@@ -287,16 +287,14 @@ ecma_op_function_try_lazy_instantiate_property (ecma_object_t *obj_p, /**< the f
if (is_length_property) if (is_length_property)
{ {
/* ECMA-262 v5, 13.2, 14-15 */ /* ECMA-262 v5, 13.2, 14-15 */
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) obj_p;
// 14
uint32_t len = 0;
ecma_property_t *bytecode_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE);
const ecma_compiled_code_t *bytecode_data_p; const ecma_compiled_code_t *bytecode_data_p;
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t, bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
ECMA_PROPERTY_VALUE_PTR (bytecode_prop_p)->value); ext_func_p->u.function.bytecode_cp);
// 14
uint32_t len;
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{ {
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p; cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p;
@@ -413,7 +411,8 @@ ecma_op_create_external_function_object (ecma_external_pointer_t code_p) /**< po
{ {
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE); ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
ecma_object_t *function_obj_p = ecma_create_object (prototype_obj_p, true, ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION); ecma_object_t *function_obj_p;
function_obj_p = ecma_create_object (prototype_obj_p, true, true, ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
ecma_deref_object (prototype_obj_p); ecma_deref_object (prototype_obj_p);
@@ -423,10 +422,8 @@ ecma_op_create_external_function_object (ecma_external_pointer_t code_p) /**< po
* See also: ecma_object_get_class_name * See also: ecma_object_get_class_name
*/ */
bool is_created = ecma_create_external_pointer_property (function_obj_p, ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) function_obj_p;
ECMA_INTERNAL_PROPERTY_NATIVE_CODE, ext_func_obj_p->u.external_function = code_p;
(ecma_external_pointer_t) code_p);
JERRY_ASSERT (is_created);
ecma_string_t *magic_string_prototype_p = ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE); ecma_string_t *magic_string_prototype_p = ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE);
ecma_builtin_helper_def_prop (function_obj_p, ecma_builtin_helper_def_prop (function_obj_p,
@@ -567,11 +564,10 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
else else
{ {
/* Entering Function Code (ECMA-262 v5, 10.4.3) */ /* Entering Function Code (ECMA-262 v5, 10.4.3) */
ecma_property_t *scope_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_SCOPE); ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_obj_p;
ecma_property_t *bytecode_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE);
ecma_object_t *scope_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, ecma_object_t *scope_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
ECMA_PROPERTY_VALUE_PTR (scope_prop_p)->value); ext_func_p->u.function.scope_cp);
// 8. // 8.
ecma_value_t this_binding; ecma_value_t this_binding;
@@ -580,7 +576,7 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
const ecma_compiled_code_t *bytecode_data_p; const ecma_compiled_code_t *bytecode_data_p;
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t, bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
ECMA_PROPERTY_VALUE_PTR (bytecode_prop_p)->value); ext_func_p->u.function.bytecode_cp);
is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) ? true : false; is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) ? true : false;
is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) ? true : false; is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) ? true : false;
@@ -649,14 +645,10 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
} }
else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION) else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
{ {
ecma_external_pointer_t handler_p; ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
bool is_retrieved = ecma_get_external_pointer_value (func_obj_p,
ECMA_INTERNAL_PROPERTY_NATIVE_CODE,
&handler_p);
JERRY_ASSERT (is_retrieved);
ret_value = jerry_dispatch_external_function (func_obj_p, ret_value = jerry_dispatch_external_function (func_obj_p,
handler_p, ext_func_obj_p->u.external_function,
this_arg_value, this_arg_value,
arguments_list_p, arguments_list_p,
arguments_list_len); arguments_list_len);
@@ -754,6 +746,7 @@ ecma_op_function_construct_simple_or_external (ecma_object_t *func_obj_p, /**< F
{ {
// 6. // 6.
obj_p = ecma_create_object (ecma_get_object_from_value (func_obj_prototype_prop_value), obj_p = ecma_create_object (ecma_get_object_from_value (func_obj_prototype_prop_value),
false,
true, true,
ECMA_OBJECT_TYPE_GENERAL); ECMA_OBJECT_TYPE_GENERAL);
} }
@@ -762,7 +755,7 @@ ecma_op_function_construct_simple_or_external (ecma_object_t *func_obj_p, /**< F
// 7. // 7.
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
obj_p = ecma_create_object (prototype_p, true, ECMA_OBJECT_TYPE_GENERAL); obj_p = ecma_create_object (prototype_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
ecma_deref_object (prototype_p); ecma_deref_object (prototype_p);
} }
@@ -55,6 +55,7 @@ ecma_op_create_number_object (ecma_value_t arg) /**< argument passed to the Numb
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN */ #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN */
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, ecma_object_t *obj_p = ecma_create_object (prototype_obj_p,
false,
true, true,
ECMA_OBJECT_TYPE_GENERAL); ECMA_OBJECT_TYPE_GENERAL);
ecma_deref_object (prototype_obj_p); ecma_deref_object (prototype_obj_p);
@@ -51,7 +51,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
// 2., 3., 6. // 2., 3., 6.
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
ecma_object_t *obj_p = ecma_create_object (prototype_p, true, ECMA_OBJECT_TYPE_GENERAL); ecma_object_t *obj_p = ecma_create_object (prototype_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
ecma_deref_object (prototype_p); ecma_deref_object (prototype_p);
@@ -116,7 +116,7 @@ ecma_op_create_object_object_noarg_and_set_prototype (ecma_object_t *object_prot
the object the object
(can be NULL) */ (can be NULL) */
{ {
ecma_object_t *obj_p = ecma_create_object (object_prototype_p, true, ECMA_OBJECT_TYPE_GENERAL); ecma_object_t *obj_p = ecma_create_object (object_prototype_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
/* /*
* [[Class]] property of ECMA_OBJECT_TYPE_GENERAL type objects * [[Class]] property of ECMA_OBJECT_TYPE_GENERAL type objects
+2 -4
View File
@@ -877,11 +877,9 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
if (ecma_get_object_is_builtin (obj_p)) if (ecma_get_object_is_builtin (obj_p))
{ {
ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (obj_p, ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
ECMA_INTERNAL_PROPERTY_BUILT_IN_ID);
ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ECMA_PROPERTY_VALUE_PTR (built_in_id_prop_p)->value;
switch (builtin_id) switch (ext_obj_p->u.built_in.id)
{ {
case ECMA_BUILTIN_ID_OBJECT_PROTOTYPE: case ECMA_BUILTIN_ID_OBJECT_PROTOTYPE:
{ {
@@ -232,7 +232,7 @@ ecma_op_create_regexp_object_from_bytecode (re_compiled_code_t *bytecode_p) /**<
ecma_object_t *re_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE); ecma_object_t *re_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE);
ecma_object_t *obj_p = ecma_create_object (re_prototype_obj_p, true, ECMA_OBJECT_TYPE_GENERAL); ecma_object_t *obj_p = ecma_create_object (re_prototype_obj_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
ecma_deref_object (re_prototype_obj_p); ecma_deref_object (re_prototype_obj_p);
/* Set the internal [[Class]] property */ /* Set the internal [[Class]] property */
@@ -284,7 +284,7 @@ ecma_op_create_regexp_object (ecma_string_t *pattern_p, /**< input pattern */
ecma_object_t *re_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE); ecma_object_t *re_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE);
ecma_object_t *obj_p = ecma_create_object (re_prototype_obj_p, true, ECMA_OBJECT_TYPE_GENERAL); ecma_object_t *obj_p = ecma_create_object (re_prototype_obj_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
ecma_deref_object (re_prototype_obj_p); ecma_deref_object (re_prototype_obj_p);
/* Set the internal [[Class]] property */ /* Set the internal [[Class]] property */
@@ -83,6 +83,7 @@ ecma_op_create_string_object (const ecma_value_t *arguments_list_p, /**< list of
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN */ #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN */
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, ecma_object_t *obj_p = ecma_create_object (prototype_obj_p,
false,
true, true,
ECMA_OBJECT_TYPE_STRING); ECMA_OBJECT_TYPE_STRING);
ecma_deref_object (prototype_obj_p); ecma_deref_object (prototype_obj_p);
+1
View File
@@ -954,6 +954,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
ecma_object_t *obj_p = ecma_create_object (prototype_p, ecma_object_t *obj_p = ecma_create_object (prototype_p,
false,
true, true,
ECMA_OBJECT_TYPE_GENERAL); ECMA_OBJECT_TYPE_GENERAL);
ecma_deref_object (prototype_p); ecma_deref_object (prototype_p);