Remove several internal property types for primitive objects. (#1399)
Class and value internal properties are always exists for primitive types (e.g. Boolean, Regex) so they can be stored right after the object. This improve property access (since internal properties are searched by a slow linear algorithm) and reduces memory consumption, since only 8 byte is allocated for these two properties instead of 16 which is the size of a property pair. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -92,8 +92,7 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of
|
||||
#endif /* !CONFIG_DISABLE_ARRAY_BUILTIN */
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (array_prototype_obj_p,
|
||||
false,
|
||||
true,
|
||||
0,
|
||||
ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
ecma_deref_object (array_prototype_obj_p);
|
||||
|
||||
@@ -49,18 +49,17 @@ 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);
|
||||
#endif /* !CONFIG_DISABLE_BOOLEAN_BUILTIN */
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
ecma_object_t *object_p = ecma_create_object (prototype_obj_p,
|
||||
sizeof (ecma_extended_object_t),
|
||||
ECMA_OBJECT_TYPE_CLASS);
|
||||
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
|
||||
ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
*class_prop_p = LIT_MAGIC_STRING_BOOLEAN_UL;
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_BOOLEAN_UL;
|
||||
ext_object_p->u.class_prop.value = ecma_make_boolean_value (boolean_value);
|
||||
|
||||
ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
|
||||
|
||||
*prim_value_p = ecma_make_boolean_value (boolean_value);
|
||||
|
||||
return ecma_make_object_value (obj_p);
|
||||
return ecma_make_object_value (object_p);
|
||||
} /* ecma_op_create_boolean_object */
|
||||
|
||||
/**
|
||||
|
||||
@@ -92,15 +92,12 @@ 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 *new_error_obj_p = ecma_create_object (prototype_obj_p,
|
||||
false,
|
||||
true,
|
||||
ECMA_OBJECT_TYPE_GENERAL);
|
||||
sizeof (ecma_extended_object_t),
|
||||
ECMA_OBJECT_TYPE_CLASS);
|
||||
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
|
||||
ecma_value_t *class_prop_p = ecma_create_internal_property (new_error_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
*class_prop_p = LIT_MAGIC_STRING_ERROR_UL;
|
||||
((ecma_extended_object_t *) new_error_obj_p)->u.class_prop.class_id = LIT_MAGIC_STRING_ERROR_UL;
|
||||
|
||||
return new_error_obj_p;
|
||||
} /* ecma_new_standard_error */
|
||||
|
||||
@@ -153,7 +153,9 @@ ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
|
||||
// 1., 4., 13.
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
|
||||
|
||||
ecma_object_t *func_p = ecma_create_object (prototype_obj_p, true, true, ECMA_OBJECT_TYPE_FUNCTION);
|
||||
ecma_object_t *func_p = ecma_create_object (prototype_obj_p,
|
||||
sizeof (ecma_extended_object_t),
|
||||
ECMA_OBJECT_TYPE_FUNCTION);
|
||||
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
|
||||
@@ -355,7 +357,9 @@ 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 *function_obj_p;
|
||||
function_obj_p = ecma_create_object (prototype_obj_p, true, true, ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
|
||||
function_obj_p = ecma_create_object (prototype_obj_p,
|
||||
sizeof (ecma_extended_object_t),
|
||||
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
|
||||
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
|
||||
@@ -679,8 +683,7 @@ ecma_op_function_construct_simple_or_external (ecma_object_t *func_obj_p, /**< F
|
||||
{
|
||||
// 6.
|
||||
obj_p = ecma_create_object (ecma_get_object_from_value (func_obj_prototype_prop_value),
|
||||
false,
|
||||
true,
|
||||
0,
|
||||
ECMA_OBJECT_TYPE_GENERAL);
|
||||
}
|
||||
else
|
||||
@@ -688,7 +691,7 @@ ecma_op_function_construct_simple_or_external (ecma_object_t *func_obj_p, /**< F
|
||||
// 7.
|
||||
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
|
||||
obj_p = ecma_create_object (prototype_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
obj_p = ecma_create_object (prototype_p, 0, ECMA_OBJECT_TYPE_GENERAL);
|
||||
|
||||
ecma_deref_object (prototype_p);
|
||||
}
|
||||
|
||||
@@ -54,22 +54,19 @@ ecma_op_create_number_object (ecma_value_t arg) /**< argument passed to the Numb
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
#endif /* !CONFIG_DISABLE_NUMBER_BUILTIN */
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p,
|
||||
false,
|
||||
true,
|
||||
ECMA_OBJECT_TYPE_GENERAL);
|
||||
ecma_object_t *object_p = ecma_create_object (prototype_obj_p,
|
||||
sizeof (ecma_extended_object_t),
|
||||
ECMA_OBJECT_TYPE_CLASS);
|
||||
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
|
||||
ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
*class_prop_p = LIT_MAGIC_STRING_NUMBER_UL;
|
||||
|
||||
ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_NUMBER_UL;
|
||||
|
||||
/* Pass reference (no need to free conv_to_num_completion). */
|
||||
*prim_value_p = conv_to_num_completion;
|
||||
ext_object_p->u.class_prop.value = conv_to_num_completion;
|
||||
|
||||
return ecma_make_object_value (obj_p);
|
||||
return ecma_make_object_value (object_p);
|
||||
} /* ecma_op_create_number_object */
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,10 +49,46 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
||||
ecma_length_t arguments_number, /**< length of arguments list */
|
||||
const ecma_compiled_code_t *bytecode_data_p) /**< byte code */
|
||||
{
|
||||
bool is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0;
|
||||
|
||||
ecma_length_t formal_params_number;
|
||||
jmem_cpointer_t *literal_p;
|
||||
|
||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p;
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_data_p;
|
||||
|
||||
formal_params_number = args_p->argument_end;
|
||||
literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p;
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_data_p;
|
||||
|
||||
formal_params_number = args_p->argument_end;
|
||||
literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
|
||||
}
|
||||
|
||||
bool class_not_required = (!is_strict && arguments_number > 0 && formal_params_number > 0);
|
||||
|
||||
// 2., 3., 6.
|
||||
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (prototype_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
ecma_object_t *obj_p;
|
||||
|
||||
if (class_not_required)
|
||||
{
|
||||
obj_p = ecma_create_object (prototype_p, 0, ECMA_OBJECT_TYPE_GENERAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj_p = ecma_create_object (prototype_p, sizeof (ecma_extended_object_t), ECMA_OBJECT_TYPE_CLASS);
|
||||
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
|
||||
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_ARGUMENTS_UL;
|
||||
}
|
||||
|
||||
ecma_deref_object (prototype_p);
|
||||
|
||||
@@ -77,10 +113,6 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
||||
ecma_deref_ecma_string (indx_string_p);
|
||||
}
|
||||
|
||||
bool is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0;
|
||||
|
||||
// 1.
|
||||
|
||||
// 7.
|
||||
ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string ();
|
||||
ecma_value_t completion = ecma_builtin_helper_def_prop (obj_p,
|
||||
@@ -96,29 +128,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
||||
|
||||
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
|
||||
|
||||
ecma_length_t formal_params_number;
|
||||
jmem_cpointer_t *literal_p;
|
||||
|
||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p;
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_data_p;
|
||||
|
||||
formal_params_number = args_p->argument_end;
|
||||
literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p;
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_data_p;
|
||||
|
||||
formal_params_number = args_p->argument_end;
|
||||
literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
|
||||
}
|
||||
|
||||
if (!is_strict
|
||||
&& arguments_number > 0
|
||||
&& formal_params_number > 0)
|
||||
if (class_not_required)
|
||||
{
|
||||
// 8.
|
||||
ecma_object_t *map_p = ecma_op_create_object_object_noarg ();
|
||||
@@ -165,12 +175,6 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
||||
|
||||
ecma_deref_object (map_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4.
|
||||
ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
*class_prop_p = LIT_MAGIC_STRING_ARGUMENTS_UL;
|
||||
}
|
||||
|
||||
// 13.
|
||||
if (!is_strict)
|
||||
|
||||
@@ -115,7 +115,7 @@ ecma_op_create_object_object_noarg_and_set_prototype (ecma_object_t *object_prot
|
||||
the object
|
||||
(can be NULL) */
|
||||
{
|
||||
ecma_object_t *obj_p = ecma_create_object (object_prototype_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
ecma_object_t *obj_p = ecma_create_object (object_prototype_p, 0, ECMA_OBJECT_TYPE_GENERAL);
|
||||
|
||||
/*
|
||||
* [[Class]] property of ECMA_OBJECT_TYPE_GENERAL type objects
|
||||
@@ -203,7 +203,7 @@ ecma_op_general_object_default_value (ecma_object_t *obj_p, /**< the object */
|
||||
|
||||
if (hint == ECMA_PREFERRED_TYPE_NO)
|
||||
{
|
||||
if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_DATE_UL)
|
||||
if (ecma_object_class_is (obj_p, LIT_MAGIC_STRING_DATE_UL))
|
||||
{
|
||||
hint = ECMA_PREFERRED_TYPE_STRING;
|
||||
}
|
||||
|
||||
@@ -48,10 +48,10 @@
|
||||
#ifndef JERRY_NDEBUG
|
||||
#define JERRY_ASSERT_OBJECT_TYPE_IS_VALID(type) \
|
||||
JERRY_ASSERT (type == ECMA_OBJECT_TYPE_GENERAL \
|
||||
|| type == ECMA_OBJECT_TYPE_CLASS \
|
||||
|| type == ECMA_OBJECT_TYPE_FUNCTION \
|
||||
|| type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION \
|
||||
|| type == ECMA_OBJECT_TYPE_ARRAY \
|
||||
|| type == ECMA_OBJECT_TYPE_STRING \
|
||||
|| type == ECMA_OBJECT_TYPE_BOUND_FUNCTION \
|
||||
|| type == ECMA_OBJECT_TYPE_ARGUMENTS);
|
||||
#else /* JERRY_NDEBUG */
|
||||
@@ -84,43 +84,44 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
|
||||
|
||||
if (property_p == NULL)
|
||||
{
|
||||
if (type == ECMA_OBJECT_TYPE_STRING)
|
||||
if (type == ECMA_OBJECT_TYPE_CLASS)
|
||||
{
|
||||
if (ecma_string_is_length (property_name_p))
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
if (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL)
|
||||
{
|
||||
if (options & ECMA_PROPERTY_GET_VALUE)
|
||||
{
|
||||
ecma_value_t *prim_value_p = ecma_get_internal_property (object_p,
|
||||
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
|
||||
|
||||
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (*prim_value_p);
|
||||
ecma_length_t length = ecma_string_get_length (prim_value_str_p);
|
||||
|
||||
property_ref_p->virtual_value = ecma_make_uint32_value (length);
|
||||
}
|
||||
|
||||
return ECMA_PROPERTY_TYPE_VIRTUAL;
|
||||
}
|
||||
|
||||
uint32_t index;
|
||||
|
||||
if (ecma_string_get_array_index (property_name_p, &index))
|
||||
{
|
||||
ecma_value_t *prim_value_p = ecma_get_internal_property (object_p,
|
||||
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
|
||||
|
||||
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (*prim_value_p);
|
||||
|
||||
if (index < ecma_string_get_length (prim_value_str_p))
|
||||
if (ecma_string_is_length (property_name_p))
|
||||
{
|
||||
if (options & ECMA_PROPERTY_GET_VALUE)
|
||||
{
|
||||
ecma_char_t char_at_idx = ecma_string_get_char_at_pos (prim_value_str_p, index);
|
||||
ecma_string_t *char_str_p = ecma_new_ecma_string_from_code_unit (char_at_idx);
|
||||
property_ref_p->virtual_value = ecma_make_string_value (char_str_p);
|
||||
ecma_value_t prim_value_p = ext_object_p->u.class_prop.value;
|
||||
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (prim_value_p);
|
||||
|
||||
ecma_length_t length = ecma_string_get_length (prim_value_str_p);
|
||||
property_ref_p->virtual_value = ecma_make_uint32_value (length);
|
||||
}
|
||||
|
||||
return ECMA_PROPERTY_FLAG_ENUMERABLE | ECMA_PROPERTY_TYPE_VIRTUAL;
|
||||
return ECMA_PROPERTY_TYPE_VIRTUAL;
|
||||
}
|
||||
|
||||
uint32_t index;
|
||||
|
||||
if (ecma_string_get_array_index (property_name_p, &index))
|
||||
{
|
||||
ecma_value_t prim_value_p = ext_object_p->u.class_prop.value;
|
||||
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (prim_value_p);
|
||||
|
||||
if (index < ecma_string_get_length (prim_value_str_p))
|
||||
{
|
||||
if (options & ECMA_PROPERTY_GET_VALUE)
|
||||
{
|
||||
ecma_char_t char_at_idx = ecma_string_get_char_at_pos (prim_value_str_p, index);
|
||||
ecma_string_t *char_str_p = ecma_new_ecma_string_from_code_unit (char_at_idx);
|
||||
property_ref_p->virtual_value = ecma_make_string_value (char_str_p);
|
||||
}
|
||||
|
||||
return ECMA_PROPERTY_FLAG_ENUMERABLE | ECMA_PROPERTY_TYPE_VIRTUAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -330,32 +331,35 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
|
||||
|
||||
if (property_p == NULL)
|
||||
{
|
||||
if (type == ECMA_OBJECT_TYPE_STRING)
|
||||
if (type == ECMA_OBJECT_TYPE_CLASS)
|
||||
{
|
||||
if (ecma_string_is_length (property_name_p))
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
if (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL)
|
||||
{
|
||||
ecma_value_t *prim_value_p = ecma_get_internal_property (object_p,
|
||||
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
|
||||
|
||||
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (*prim_value_p);
|
||||
ecma_length_t length = ecma_string_get_length (prim_value_str_p);
|
||||
|
||||
return ecma_make_uint32_value (length);
|
||||
}
|
||||
|
||||
uint32_t index;
|
||||
|
||||
if (ecma_string_get_array_index (property_name_p, &index))
|
||||
{
|
||||
ecma_value_t *prim_value_p = ecma_get_internal_property (object_p,
|
||||
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
|
||||
|
||||
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (*prim_value_p);
|
||||
|
||||
if (index < ecma_string_get_length (prim_value_str_p))
|
||||
if (ecma_string_is_length (property_name_p))
|
||||
{
|
||||
ecma_char_t char_at_idx = ecma_string_get_char_at_pos (prim_value_str_p, index);
|
||||
return ecma_make_string_value (ecma_new_ecma_string_from_code_unit (char_at_idx));
|
||||
ecma_value_t prim_value_p = ext_object_p->u.class_prop.value;
|
||||
|
||||
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (prim_value_p);
|
||||
ecma_length_t length = ecma_string_get_length (prim_value_str_p);
|
||||
|
||||
return ecma_make_uint32_value (length);
|
||||
}
|
||||
|
||||
uint32_t index;
|
||||
|
||||
if (ecma_string_get_array_index (property_name_p, &index))
|
||||
{
|
||||
ecma_value_t prim_value_p = ext_object_p->u.class_prop.value;
|
||||
|
||||
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (prim_value_p);
|
||||
|
||||
if (index < ecma_string_get_length (prim_value_str_p))
|
||||
{
|
||||
ecma_char_t char_at_idx = ecma_string_get_char_at_pos (prim_value_str_p, index);
|
||||
return ecma_make_string_value (ecma_new_ecma_string_from_code_unit (char_at_idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -582,20 +586,23 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
|
||||
|
||||
if (property_p == NULL)
|
||||
{
|
||||
if (type == ECMA_OBJECT_TYPE_STRING)
|
||||
if (type == ECMA_OBJECT_TYPE_CLASS)
|
||||
{
|
||||
uint32_t index;
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
if (ecma_string_get_array_index (property_name_p, &index))
|
||||
if (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL)
|
||||
{
|
||||
ecma_value_t *prim_value_p = ecma_get_internal_property (object_p,
|
||||
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
|
||||
uint32_t index;
|
||||
|
||||
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (*prim_value_p);
|
||||
|
||||
if (index < ecma_string_get_length (prim_value_str_p))
|
||||
if (ecma_string_get_array_index (property_name_p, &index))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
ecma_value_t prim_value_p = ext_object_p->u.class_prop.value;
|
||||
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (prim_value_p);
|
||||
|
||||
if (index < ecma_string_get_length (prim_value_str_p))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -776,10 +783,10 @@ ecma_op_object_delete (ecma_object_t *obj_p, /**< the object */
|
||||
switch (type)
|
||||
{
|
||||
case ECMA_OBJECT_TYPE_GENERAL:
|
||||
case ECMA_OBJECT_TYPE_CLASS:
|
||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
||||
case ECMA_OBJECT_TYPE_ARRAY:
|
||||
case ECMA_OBJECT_TYPE_STRING:
|
||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||
{
|
||||
return ecma_op_general_object_delete (obj_p,
|
||||
@@ -825,10 +832,10 @@ ecma_op_object_default_value (ecma_object_t *obj_p, /**< the object */
|
||||
* static const default_value_ptr_t default_value [ECMA_OBJECT_TYPE__COUNT] =
|
||||
* {
|
||||
* [ECMA_OBJECT_TYPE_GENERAL] = &ecma_op_general_object_default_value,
|
||||
* [ECMA_OBJECT_TYPE_CLASS] = &ecma_op_general_object_default_value,
|
||||
* [ECMA_OBJECT_TYPE_FUNCTION] = &ecma_op_general_object_default_value,
|
||||
* [ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION] = &ecma_op_general_object_default_value,
|
||||
* [ECMA_OBJECT_TYPE_ARRAY] = &ecma_op_general_object_default_value,
|
||||
* [ECMA_OBJECT_TYPE_STRING] = &ecma_op_general_object_default_value,
|
||||
* [ECMA_OBJECT_TYPE_BOUND_FUNCTION] = &ecma_op_general_object_default_value,
|
||||
* [ECMA_OBJECT_TYPE_ARGUMENTS] = &ecma_op_general_object_default_value
|
||||
* };
|
||||
@@ -864,9 +871,9 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */
|
||||
switch (type)
|
||||
{
|
||||
case ECMA_OBJECT_TYPE_GENERAL:
|
||||
case ECMA_OBJECT_TYPE_CLASS:
|
||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
||||
case ECMA_OBJECT_TYPE_STRING:
|
||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||
{
|
||||
return ecma_op_general_object_define_own_property (obj_p,
|
||||
@@ -994,8 +1001,8 @@ ecma_op_object_has_instance (ecma_object_t *obj_p, /**< the object */
|
||||
switch (type)
|
||||
{
|
||||
case ECMA_OBJECT_TYPE_GENERAL:
|
||||
case ECMA_OBJECT_TYPE_CLASS:
|
||||
case ECMA_OBJECT_TYPE_ARRAY:
|
||||
case ECMA_OBJECT_TYPE_STRING:
|
||||
case ECMA_OBJECT_TYPE_ARGUMENTS:
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function object."));
|
||||
@@ -1100,6 +1107,14 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ECMA_OBJECT_TYPE_GENERAL:
|
||||
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
||||
case ECMA_OBJECT_TYPE_ARRAY:
|
||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||
case ECMA_OBJECT_TYPE_ARGUMENTS:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||
{
|
||||
ecma_op_function_list_lazy_property_names (is_enumerable_only,
|
||||
@@ -1107,22 +1122,17 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
skipped_non_enumerable_p);
|
||||
break;
|
||||
}
|
||||
|
||||
case ECMA_OBJECT_TYPE_STRING:
|
||||
case ECMA_OBJECT_TYPE_CLASS:
|
||||
{
|
||||
ecma_op_string_list_lazy_property_names (obj_p,
|
||||
is_enumerable_only,
|
||||
prop_names_p,
|
||||
skipped_non_enumerable_p);
|
||||
break;
|
||||
}
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
case ECMA_OBJECT_TYPE_GENERAL:
|
||||
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
||||
case ECMA_OBJECT_TYPE_ARRAY:
|
||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||
case ECMA_OBJECT_TYPE_ARGUMENTS:
|
||||
{
|
||||
if (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL)
|
||||
{
|
||||
ecma_op_string_list_lazy_property_names (obj_p,
|
||||
is_enumerable_only,
|
||||
prop_names_p,
|
||||
skipped_non_enumerable_p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -1413,9 +1423,10 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
|
||||
{
|
||||
return LIT_MAGIC_STRING_ARRAY_UL;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_STRING:
|
||||
case ECMA_OBJECT_TYPE_CLASS:
|
||||
{
|
||||
return LIT_MAGIC_STRING_STRING_UL;
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
|
||||
return ext_object_p->u.class_prop.class_id;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_ARGUMENTS:
|
||||
{
|
||||
@@ -1441,24 +1452,6 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
|
||||
{
|
||||
return LIT_MAGIC_STRING_OBJECT_UL;
|
||||
}
|
||||
#ifndef CONFIG_DISABLE_STRING_BUILTIN
|
||||
case ECMA_BUILTIN_ID_STRING_PROTOTYPE:
|
||||
{
|
||||
return LIT_MAGIC_STRING_STRING_UL;
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_STRING_BUILTIN */
|
||||
#ifndef CONFIG_DISABLE_BOOLEAN_BUILTIN
|
||||
case ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE:
|
||||
{
|
||||
return LIT_MAGIC_STRING_BOOLEAN_UL;
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_BOOLEAN_BUILTIN */
|
||||
#ifndef CONFIG_DISABLE_NUMBER_BUILTIN
|
||||
case ECMA_BUILTIN_ID_NUMBER_PROTOTYPE:
|
||||
{
|
||||
return LIT_MAGIC_STRING_NUMBER_UL;
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_NUMBER_BUILTIN */
|
||||
#ifndef CONFIG_DISABLE_MATH_BUILTIN
|
||||
case ECMA_BUILTIN_ID_MATH:
|
||||
{
|
||||
@@ -1483,18 +1476,6 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
|
||||
{
|
||||
return LIT_MAGIC_STRING_ERROR_UL;
|
||||
}
|
||||
#ifndef CONFIG_DISABLE_DATE_BUILTIN
|
||||
case ECMA_BUILTIN_ID_DATE_PROTOTYPE:
|
||||
{
|
||||
return LIT_MAGIC_STRING_DATE_UL;
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_DATE_BUILTIN */
|
||||
#ifndef CONFIG_DISABLE_REGEXP_BUILTIN
|
||||
case ECMA_BUILTIN_ID_REGEXP_PROTOTYPE:
|
||||
{
|
||||
return LIT_MAGIC_STRING_REGEXP_UL;
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_GLOBAL));
|
||||
@@ -1505,22 +1486,35 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_value_t *class_name_prop_p = ecma_find_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
|
||||
if (class_name_prop_p == NULL)
|
||||
{
|
||||
return LIT_MAGIC_STRING_OBJECT_UL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return *class_name_prop_p;
|
||||
}
|
||||
return LIT_MAGIC_STRING_OBJECT_UL;
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* ecma_object_get_class_name */
|
||||
|
||||
/**
|
||||
* Get value of an object if the class matches
|
||||
*
|
||||
* @return value of the object if the class matches
|
||||
* ECMA_SIMPLE_VALUE_NOT_FOUND otherwise
|
||||
*/
|
||||
inline bool __attr_always_inline___
|
||||
ecma_object_class_is (ecma_object_t *object_p, /**< object */
|
||||
uint32_t class_id) /**< class id */
|
||||
{
|
||||
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_CLASS)
|
||||
{
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
if (ext_object_p->u.class_prop.class_id == class_id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} /* ecma_object_class_is */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@@ -48,6 +48,7 @@ extern bool ecma_op_object_is_prototype_of (ecma_object_t *, ecma_object_t *);
|
||||
extern ecma_collection_header_t * ecma_op_object_get_property_names (ecma_object_t *, bool, bool, bool);
|
||||
|
||||
extern lit_magic_string_id_t ecma_object_get_class_name (ecma_object_t *);
|
||||
extern bool ecma_object_class_is (ecma_object_t *, uint32_t);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -223,24 +223,27 @@ 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 *obj_p = ecma_create_object (re_prototype_obj_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
ecma_object_t *object_p = ecma_create_object (re_prototype_obj_p,
|
||||
sizeof (ecma_extended_object_t),
|
||||
ECMA_OBJECT_TYPE_CLASS);
|
||||
|
||||
ecma_deref_object (re_prototype_obj_p);
|
||||
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
/* Set the internal [[Class]] property */
|
||||
ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
*class_prop_p = LIT_MAGIC_STRING_REGEXP_UL;
|
||||
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_REGEXP_UL;
|
||||
|
||||
/* Set bytecode internal property. */
|
||||
ecma_value_t *bytecode_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE);
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (*bytecode_prop_p, bytecode_p);
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.value, bytecode_p);
|
||||
ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_p);
|
||||
|
||||
/* Initialize RegExp object properties */
|
||||
re_initialize_props (obj_p,
|
||||
re_initialize_props (object_p,
|
||||
ECMA_GET_NON_NULL_POINTER (ecma_string_t, bytecode_p->pattern_cp),
|
||||
bytecode_p->header.status_flags);
|
||||
|
||||
return ecma_make_object_value (obj_p);
|
||||
return ecma_make_object_value (object_p);
|
||||
} /* ecma_op_create_regexp_object_from_bytecode */
|
||||
|
||||
/**
|
||||
@@ -274,31 +277,32 @@ 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 *obj_p = ecma_create_object (re_prototype_obj_p, false, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
ecma_object_t *object_p = ecma_create_object (re_prototype_obj_p,
|
||||
sizeof (ecma_extended_object_t),
|
||||
ECMA_OBJECT_TYPE_CLASS);
|
||||
|
||||
ecma_deref_object (re_prototype_obj_p);
|
||||
|
||||
/* Set the internal [[Class]] property */
|
||||
ecma_value_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
*class_prop_p = LIT_MAGIC_STRING_REGEXP_UL;
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_UNDEFINED;
|
||||
|
||||
re_initialize_props (obj_p, pattern_p, flags);
|
||||
|
||||
/* Set bytecode internal property. */
|
||||
ecma_value_t *bytecode_prop_p = ecma_create_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE);
|
||||
re_initialize_props (object_p, pattern_p, flags);
|
||||
|
||||
/* Compile bytecode. */
|
||||
const re_compiled_code_t *bc_p = NULL;
|
||||
ECMA_TRY_CATCH (empty, re_compile_bytecode (&bc_p, pattern_p, flags), ret_value);
|
||||
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (*bytecode_prop_p, bc_p);
|
||||
ret_value = ecma_make_object_value (obj_p);
|
||||
/* Set [[Class]] and bytecode internal properties. */
|
||||
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_REGEXP_UL;
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.value, bc_p);
|
||||
|
||||
ret_value = ecma_make_object_value (object_p);
|
||||
|
||||
ECMA_FINALIZE (empty);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
ecma_deref_object (obj_p);
|
||||
ecma_deref_object (object_p);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
@@ -1235,11 +1239,11 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */
|
||||
|
||||
ecma_object_t *regexp_object_p = ecma_get_object_from_value (regexp_value);
|
||||
|
||||
JERRY_ASSERT (ecma_object_get_class_name (regexp_object_p) == LIT_MAGIC_STRING_REGEXP_UL);
|
||||
JERRY_ASSERT (ecma_object_class_is (regexp_object_p, LIT_MAGIC_STRING_REGEXP_UL));
|
||||
|
||||
ecma_value_t *bytecode_prop_p = ecma_get_internal_property (regexp_object_p,
|
||||
ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE);
|
||||
re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t, *bytecode_prop_p);
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) regexp_object_p;
|
||||
re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t,
|
||||
ext_object_p->u.class_prop.value);
|
||||
|
||||
if (bc_p == NULL)
|
||||
{
|
||||
|
||||
@@ -76,23 +76,17 @@ ecma_op_create_string_object (const ecma_value_t *arguments_list_p, /**< list of
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
#endif /* !CONFIG_DISABLE_STRING_BUILTIN */
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p,
|
||||
false,
|
||||
true,
|
||||
ECMA_OBJECT_TYPE_STRING);
|
||||
ecma_object_t *object_p = ecma_create_object (prototype_obj_p,
|
||||
sizeof (ecma_extended_object_t),
|
||||
ECMA_OBJECT_TYPE_CLASS);
|
||||
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
|
||||
/*
|
||||
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_STRING type.
|
||||
*
|
||||
* See also: ecma_object_get_class_name
|
||||
*/
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_STRING_UL;
|
||||
ext_object_p->u.class_prop.value = ecma_make_string_value (prim_prop_str_value_p);
|
||||
|
||||
ecma_value_t *prim_value_prop_p = ecma_create_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
|
||||
*prim_value_prop_p = ecma_make_string_value (prim_prop_str_value_p);
|
||||
|
||||
return ecma_make_object_value (obj_p);
|
||||
return ecma_make_object_value (object_p);
|
||||
} /* ecma_op_create_string_object */
|
||||
|
||||
/**
|
||||
@@ -116,15 +110,16 @@ ecma_op_string_list_lazy_property_names (ecma_object_t *obj_p, /**< a String obj
|
||||
* collection
|
||||
*/
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_STRING);
|
||||
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_CLASS);
|
||||
|
||||
ecma_collection_header_t *for_enumerable_p = main_collection_p;
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
|
||||
ecma_value_t *prim_value_p = ecma_get_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
|
||||
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (*prim_value_p);
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
|
||||
JERRY_ASSERT (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL);
|
||||
|
||||
ecma_string_t *prim_value_str_p = ecma_get_string_from_value (ext_object_p->u.class_prop.value);
|
||||
|
||||
ecma_length_t length = ecma_string_get_length (prim_value_str_p);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user