/**
 * 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 */
/**
 * The Date.prototype object's 'toString' routine
 *
 * See also:
 *          ECMA-262 v5, 15.9.5.2
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
static ecma_value_t
ecma_builtin_date_prototype_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 (prim_value,
                  ecma_date_get_primitive_value (this_arg),
                  ret_value);

  ecma_number_t *prim_num_p = ecma_get_number_from_value (prim_value);

  if (ecma_number_is_nan (*prim_num_p))
  {
    ecma_string_t *magic_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INVALID_DATE_UL);
    ret_value = ecma_make_string_value (magic_str_p);
  }
  else
  {
    ret_value = ecma_date_value_to_string (*prim_num_p);
  }

  ECMA_FINALIZE (prim_value);

  return ret_value;
} /* ecma_builtin_date_prototype_to_string */
Exemplo n.º 3
0
/**
 * List names of a Function object's lazy instantiated properties,
 * adding them to corresponding string collections
 *
 * See also:
 *          ecma_op_function_try_lazy_instantiate_property
 */
void
ecma_op_function_list_lazy_property_names (bool separate_enumerable, /**< true - list enumerable properties into
                                                                      *          main collection and non-enumerable
                                                                      *          to collection of 'skipped
                                                                      *          non-enumerable' properties,
                                                                      *   false - list all properties into main
                                                                      *           collection.
                                                                      */
                                           ecma_collection_header_t *main_collection_p, /**< 'main' collection */
                                           ecma_collection_header_t *non_enum_collection_p) /**< skipped
                                                                                             *   'non-enumerable'
                                                                                             *   collection */
{
  ecma_collection_header_t *for_enumerable_p = main_collection_p;
  JERRY_UNUSED (for_enumerable_p);

  ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;

  ecma_string_t *name_p;

  /* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */
  name_p = ecma_new_ecma_length_string ();
  ecma_append_to_values_collection (for_non_enumerable_p, ecma_make_string_value (name_p), true);
  ecma_deref_ecma_string (name_p);

  /* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */
  name_p = ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE);
  ecma_append_to_values_collection (for_non_enumerable_p, ecma_make_string_value (name_p), true);
  ecma_deref_ecma_string (name_p);
} /* ecma_op_function_list_lazy_property_names */
/**
 * The Date.prototype object's 'toJSON' routine
 *
 * See also:
 *          ECMA-262 v5, 15.9.5.44
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
static ecma_value_t
ecma_builtin_date_prototype_to_json (ecma_value_t this_arg, /**< this argument */
                                     ecma_value_t arg) /**< key */
{
  JERRY_UNUSED (arg);
  ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);

  /* 1. */
  ECMA_TRY_CATCH (obj,
                  ecma_op_to_object (this_arg),
                  ret_value);

  /* 2. */
  ECMA_TRY_CATCH (tv,
                  ecma_op_to_primitive (obj, ECMA_PREFERRED_TYPE_NUMBER),
                  ret_value);

  /* 3. */
  if (ecma_is_value_number (tv))
  {
    ecma_number_t num_value = ecma_get_number_from_value (tv);

    if (ecma_number_is_nan (num_value) || ecma_number_is_infinity (num_value))
    {
      ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_NULL);
    }
  }

  if (ecma_is_value_empty (ret_value))
  {
    ecma_string_t *to_iso_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_TO_ISO_STRING_UL);
    ecma_object_t *value_obj_p = ecma_get_object_from_value (obj);

    /* 4. */
    ECMA_TRY_CATCH (to_iso,
                    ecma_op_object_get (value_obj_p, to_iso_str_p),
                    ret_value);

    /* 5. */
    if (!ecma_op_is_callable (to_iso))
    {
      ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
    }
    /* 6. */
    else
    {
      ecma_object_t *to_iso_obj_p = ecma_get_object_from_value (to_iso);
      ret_value = ecma_op_function_call (to_iso_obj_p, this_arg, NULL, 0);
    }

    ECMA_FINALIZE (to_iso);

    ecma_deref_ecma_string (to_iso_str_p);
  }

  ECMA_FINALIZE (tv);
  ECMA_FINALIZE (obj);

  return ret_value;
} /* ecma_builtin_date_prototype_to_json */
Exemplo n.º 5
0
/**
 * Allocate new ecma-string and fill it with characters from the utf8 string
 *
 * @return pointer to ecma-string descriptor
 */
ecma_string_t *
ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, /**< utf-8 string */
                                lit_utf8_size_t string_size) /**< string size */
{
  JERRY_ASSERT (string_p != NULL || string_size == 0);
  JERRY_ASSERT (lit_is_cesu8_string_valid (string_p, string_size));

  lit_magic_string_id_t magic_string_id;
  if (lit_is_utf8_string_magic (string_p, string_size, &magic_string_id))
  {
    return ecma_get_magic_string (magic_string_id);
  }

  lit_magic_string_ex_id_t magic_string_ex_id;
  if (lit_is_ex_utf8_string_magic (string_p, string_size, &magic_string_ex_id))
  {
    return ecma_get_magic_string_ex (magic_string_ex_id);
  }

  JERRY_ASSERT (string_size > 0 && string_size <= UINT16_MAX);

  ecma_string_t *string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + string_size);

  string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE;
  string_desc_p->hash = lit_utf8_string_calc_hash (string_p, string_size);
  string_desc_p->u.common_field = 0;
  string_desc_p->u.utf8_string.size = (uint16_t) string_size;
  string_desc_p->u.utf8_string.length = (uint16_t) lit_utf8_string_length (string_p, string_size);

  lit_utf8_byte_t *data_p = (lit_utf8_byte_t *) (string_desc_p + 1);
  memcpy (data_p, string_p, string_size);
  return string_desc_p;
} /* ecma_new_ecma_string_from_utf8 */
Exemplo n.º 6
0
/**
 * External function object creation operation.
 *
 * Note:
 *      external function object is implementation-defined object type
 *      that represent functions implemented in native code, using Embedding API
 *
 * @return pointer to newly created external function object
 */
ecma_object_t *
ecma_op_create_external_function_object (ecma_external_pointer_t code_p) /**< pointer to external native handler */
{
  ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);

  ecma_object_t *function_obj_p;
  function_obj_p = ecma_create_object (prototype_obj_p,
                                       sizeof (ecma_extended_object_t),
                                       ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);

  ecma_deref_object (prototype_obj_p);

  /*
   * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION type.
   *
   * See also: ecma_object_get_class_name
   */

  ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) function_obj_p;
  ext_func_obj_p->u.external_function = code_p;

  ecma_string_t *magic_string_prototype_p = ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE);
  ecma_builtin_helper_def_prop (function_obj_p,
                                magic_string_prototype_p,
                                ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
                                true, /* Writable */
                                false, /* Enumerable */
                                false, /* Configurable */
                                false); /* Failure handling */

  ecma_deref_ecma_string (magic_string_prototype_p);

  return function_obj_p;
} /* ecma_op_create_external_function_object */
/**
 * The Date.prototype object's 'getYear' routine
 *
 * See also:
 *          ECMA-262 v5, AnnexB.B.2.4
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
static ecma_value_t
ecma_builtin_date_prototype_get_year (ecma_value_t this_arg) /**< this argument */
{
  ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);

  /* 1. */
  ECMA_TRY_CATCH (value, ecma_builtin_date_prototype_get_time (this_arg), ret_value);
  ecma_number_t *this_num_p = ecma_get_number_from_value (value);
  /* 2. */
  if (ecma_number_is_nan (*this_num_p))
  {
    ecma_string_t *nan_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_NAN);
    ret_value = ecma_make_string_value (nan_str_p);
  }
  else
  {
    /* 3. */
    ecma_number_t *ret_num_p = ecma_alloc_number ();
    *ret_num_p = ecma_date_year_from_time (ecma_date_local_time (*this_num_p)) - 1900;
    ret_value = ecma_make_number_value (ret_num_p);
  }
  ECMA_FINALIZE (value);

  return ret_value;
} /* ecma_builtin_date_prototype_get_year */
/**
 * 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 */
Exemplo n.º 9
0
/**
 * Allocate new ecma-string and fill it with ecma-number
 *
 * @return pointer to ecma-string descriptor
 */
ecma_string_t *
ecma_new_ecma_string_from_number (ecma_number_t num) /**< ecma-number */
{
  uint32_t uint32_num = ecma_number_to_uint32 (num);
  if (num == ((ecma_number_t) uint32_num))
  {
    return ecma_new_ecma_string_from_uint32 (uint32_num);
  }

  if (ecma_number_is_nan (num))
  {
    return ecma_get_magic_string (LIT_MAGIC_STRING_NAN);
  }

  if (ecma_number_is_infinity (num))
  {
    lit_magic_string_id_t id = (ecma_number_is_negative (num) ? LIT_MAGIC_STRING_NEGATIVE_INFINITY_UL
                                                              : LIT_MAGIC_STRING_INFINITY_UL);
    return ecma_get_magic_string (id);
  }

  lit_utf8_byte_t str_buf[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
  lit_utf8_size_t str_size = ecma_number_to_utf8_string (num, str_buf, sizeof (str_buf));

  JERRY_ASSERT (str_size > 0);
#ifndef JERRY_NDEBUG
  lit_magic_string_id_t magic_string_id;
  lit_magic_string_ex_id_t magic_string_ex_id;

  JERRY_ASSERT (!lit_is_utf8_string_magic (str_buf, str_size, &magic_string_id)
                && !lit_is_ex_utf8_string_magic (str_buf, str_size, &magic_string_ex_id));
#endif /* !JERRY_NDEBUG */

  ecma_string_t *string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + str_size);

  string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE;
  string_desc_p->hash = lit_utf8_string_calc_hash (str_buf, str_size);
  string_desc_p->u.common_field = 0;
  string_desc_p->u.utf8_string.size = (uint16_t) str_size;
  string_desc_p->u.utf8_string.length = (uint16_t) str_size;

  lit_utf8_byte_t *data_p = (lit_utf8_byte_t *) (string_desc_p + 1);
  memcpy (data_p, str_buf, str_size);
  return string_desc_p;
} /* ecma_new_ecma_string_from_number */
Exemplo n.º 10
0
/**
 * Checks whether the property name is "length".
 *
 * @return true if the property name is length
 *         false otherwise
 */
static inline bool __attr_always_inline___
ecma_op_general_object_property_name_is_length (ecma_string_t *property_name_p) /**< property name */
{
  ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH);

  bool property_name_is_length = ecma_compare_ecma_strings (property_name_p,
                                                            magic_string_length_p);

  ecma_deref_ecma_string (magic_string_length_p);

  return property_name_is_length;
} /* ecma_op_general_object_property_name_is_length */
/**
 * 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_property_t *bytecode_prop_p;
    ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
    bytecode_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE);

    void *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (void, ecma_get_internal_property_value (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 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 'toString' routine
 *
 * See also:
 *          ECMA-262 v5, 15.3.4.2
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value.
 */
static ecma_completion_value_t
ecma_builtin_function_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */
{
  ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();

  if (!ecma_op_is_callable (this_arg))
  {
    ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
  }
  else
  {
    ecma_string_t *function_to_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__FUNCTION_TO_STRING);
    ret_value = ecma_make_normal_completion_value (ecma_make_string_value (function_to_string_p));
  }
  return ret_value;
} /* ecma_builtin_function_prototype_object_to_string */
/**
 * The String.prototype object's 'charAt' routine
 *
 * See also:
 *          ECMA-262 v5, 15.5.4.4
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value.
 */
static ecma_completion_value_t
ecma_builtin_string_prototype_object_char_at (ecma_value_t this_arg, /**< this argument */
                                              ecma_value_t arg) /**< routine's argument */
{
  ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();

  /* 1 */
  ECMA_TRY_CATCH (check_coercible_val,
                  ecma_op_check_object_coercible (this_arg),
                  ret_value);

  /* 2 */
  ECMA_TRY_CATCH (to_string_val,
                  ecma_op_to_string (this_arg),
                  ret_value);

  /* 3 */
  ECMA_OP_TO_NUMBER_TRY_CATCH (index_num,
                               arg,
                               ret_value);

  /* 4 */
  ecma_string_t *original_string_p = ecma_get_string_from_value (to_string_val);
  const ecma_length_t len = ecma_string_get_length (original_string_p);

  /* 5 */
  if (index_num < 0 || index_num >= len || !len)
  {
    ret_value = ecma_make_normal_completion_value (ecma_make_string_value (
                                                   ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY)));
  }
  else
  {
    /* 6 */
    ecma_char_t new_ecma_char = ecma_string_get_char_at_pos (original_string_p, ecma_number_to_uint32 (index_num));
    ret_value = ecma_make_normal_completion_value (ecma_make_string_value (
                                                   ecma_new_ecma_string_from_code_unit (new_ecma_char)));
  }

  ECMA_OP_TO_NUMBER_FINALIZE (index_num);

  ECMA_FINALIZE (to_string_val);
  ECMA_FINALIZE (check_coercible_val);

  return ret_value;
} /* ecma_builtin_string_prototype_object_char_at */
Exemplo n.º 15
0
/**
 * 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 */
                                               ecma_number_t length_prop_num_value) /**< ecma-number - 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, true);

  uint64_t packed_value = jrt_set_bit_field_value (0,
                                                   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 (packed_value,
                                          routine_id,
                                          ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_POS,
                                          ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_WIDTH);
  ecma_property_t *routine_id_prop_p = ecma_create_internal_property (func_obj_p,
                                                                      ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_ID);

  JERRY_ASSERT ((uint32_t) packed_value == packed_value);
  routine_id_prop_p->u.internal_property.value = (uint32_t) packed_value;

  ecma_string_t* magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH);
  ecma_property_t *len_prop_p = ecma_create_named_data_property (func_obj_p,
                                                                 magic_string_length_p,
                                                                 false, false, false);

  ecma_deref_ecma_string (magic_string_length_p);

  ecma_number_t* len_p = ecma_alloc_number ();
  *len_p = length_prop_num_value;

  ecma_set_named_data_property_value (len_prop_p, ecma_make_number_value (len_p));

  return func_obj_p;
} /* ecma_builtin_make_function_object_for_routine */
Exemplo n.º 16
0
/**
 * Standard ecma-error object constructor.
 *
 * @return pointer to ecma-object representing specified error
 *         with reference counter set to one.
 */
ecma_object_t *
ecma_new_standard_error_with_message (ecma_standard_error_t error_type, /**< native error type */
                                      ecma_string_t *message_string_p) /**< message string */
{
  ecma_object_t *new_error_obj_p = ecma_new_standard_error (error_type);

  ecma_string_t *message_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MESSAGE);
  ecma_property_t *prop_p = ecma_create_named_data_property (new_error_obj_p,
                                                             message_magic_string_p,
                                                             ECMA_PROPERTY_CONFIGURABLE_WRITABLE);

  ecma_ref_ecma_string (message_string_p);
  ecma_set_named_data_property_value (prop_p,
                                      ecma_make_string_value (message_string_p));
  ecma_deref_ecma_string (message_magic_string_p);

  return new_error_obj_p;
} /* ecma_new_standard_error_with_message */
Exemplo n.º 17
0
/**
 * External function object creation operation.
 *
 * Note:
 *      external function object is implementation-defined object type
 *      that represent functions implemented in native code, using Embedding API
 *
 * @return pointer to newly created external function object
 */
ecma_object_t*
ecma_op_create_external_function_object (ecma_external_pointer_t code_p) /**< pointer to external native handler */
{
  ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);

  ecma_object_t *function_obj_p = ecma_create_object (prototype_obj_p, true, ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);

  ecma_deref_object (prototype_obj_p);

  /*
   * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION type.
   *
   * See also: ecma_object_get_class_name
   */

  bool is_created = ecma_create_external_pointer_property (function_obj_p,
                                                           ECMA_INTERNAL_PROPERTY_NATIVE_CODE,
                                                           (ecma_external_pointer_t) code_p);
  JERRY_ASSERT (is_created);

  ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
  {
    prop_desc.is_value_defined = true;
    prop_desc.value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);

    prop_desc.is_writable_defined = true;
    prop_desc.is_writable = true;

    prop_desc.is_enumerable_defined = true;
    prop_desc.is_enumerable = false;

    prop_desc.is_configurable_defined = true;
    prop_desc.is_configurable = false;
  }

  ecma_string_t *magic_string_prototype_p = ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE);
  ecma_op_object_define_own_property (function_obj_p,
                                      magic_string_prototype_p,
                                      &prop_desc,
                                      false);
  ecma_deref_ecma_string (magic_string_prototype_p);

  return function_obj_p;
} /* ecma_op_create_external_function_object */
Exemplo n.º 18
0
/**
 * 'typeof' opcode handler.
 *
 * See also: ECMA-262 v5, 11.4.3
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value
 */
ecma_value_t
opfunc_typeof (ecma_value_t left_value) /**< left value */
{
  ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);

  ecma_string_t *type_str_p = NULL;

  if (ecma_is_value_undefined (left_value))
  {
    type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_UNDEFINED);
  }
  else if (ecma_is_value_null (left_value))
  {
    type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_OBJECT);
  }
  else if (ecma_is_value_boolean (left_value))
  {
    type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_BOOLEAN);
  }
  else if (ecma_is_value_number (left_value))
  {
    type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_NUMBER);
  }
  else if (ecma_is_value_string (left_value))
  {
    type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_STRING);
  }
  else
  {
    JERRY_ASSERT (ecma_is_value_object (left_value));

    if (ecma_op_is_callable (left_value))
    {
      type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_FUNCTION);
    }
    else
    {
      type_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_OBJECT);
    }
  }

  ret_value = ecma_make_string_value (type_str_p);

  return ret_value;
} /* opfunc_typeof */
/**
 * 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 */
/**
 * The Date.prototype object's 'toDateString' routine
 *
 * See also:
 *          ECMA-262 v5, 15.9.5.3
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
static ecma_value_t
ecma_builtin_date_prototype_to_date_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_DATE_UL)
  {
    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Incompatible 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);
    ecma_property_t *prim_prop_p = ecma_get_internal_property (obj_p,
                                                               ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE);
    ecma_number_t *prim_value_num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t,
                                                                       ecma_get_internal_property_value (prim_prop_p));

    if (ecma_number_is_nan (*prim_value_num_p))
    {
      ecma_string_t *magic_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INVALID_DATE_UL);
      ret_value = ecma_make_string_value (magic_str_p);
    }
    else
    {
      ret_value = ecma_date_value_to_date_string (*prim_value_num_p);
    }

    ECMA_FINALIZE (obj_this);
  }

  return ret_value;
} /* ecma_builtin_date_prototype_to_date_string */
/**
 * 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 */
/**
 * 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 'toLocaleString' routine
 *
 * See also:
 *          ECMA-262 v5, 15.2.4.3
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value.
 */
static ecma_completion_value_t
ecma_builtin_object_prototype_object_to_locale_string (ecma_value_t this_arg) /**< this argument */
{
  ecma_completion_value_t return_value = ecma_make_empty_completion_value ();
  /* 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_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
  }
  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);
  }
  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 */
Exemplo n.º 24
0
/**
 * 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 completion value
 *         Returned value must be freed with ecma_free_completion_value.
 */
ecma_completion_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_completion_value_t ret_value = ecma_make_empty_completion_value ();

  /* 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_get_magic_string (LIT_MAGIC_STRING_LENGTH);
    /* 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_completion_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 */
      if (ecma_op_object_get_property (ecma_get_object_from_value (value),
                                       array_index_string_p) != NULL)
      {
        ecma_string_t *new_array_index_string_p = ecma_new_ecma_string_from_uint32 (*length_p + array_index);

        /* 5.b.iii.3.a */
        ECMA_TRY_CATCH (get_value,
                        ecma_op_object_get (ecma_get_object_from_value (value),
                                            array_index_string_p),
                        ret_value);

        ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
        {
          prop_desc.is_value_defined = true;
          prop_desc.value = get_value;

          prop_desc.is_writable_defined = true;
          prop_desc.is_writable = true;

          prop_desc.is_enumerable_defined = true;
          prop_desc.is_enumerable = true;

          prop_desc.is_configurable_defined = true;
          prop_desc.is_configurable = true;
        }

        /* 5.b.iii.3.b */
        /* This will always be a simple value since 'is_throw' is false, so no need to free. */
        ecma_completion_value_t put_comp = ecma_op_object_define_own_property (obj_p,
                                                                               new_array_index_string_p,
                                                                               &prop_desc,
                                                                               false);
        JERRY_ASSERT (ecma_is_completion_value_normal_true (put_comp));

        ECMA_FINALIZE (get_value);
        ecma_deref_ecma_string (new_array_index_string_p);
      }

      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)++);

    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 = true;

      prop_desc.is_enumerable_defined = true;
      prop_desc.is_enumerable = true;

      prop_desc.is_configurable_defined = true;
      prop_desc.is_configurable = true;
    }

    /* 5.c.i */
    /* This will always be a simple value since 'is_throw' is false, so no need to free. */
    ecma_completion_value_t put_comp = ecma_op_object_define_own_property (obj_p,
                                                                           new_array_index_string_p,
                                                                           &prop_desc,
                                                                           false);
    JERRY_ASSERT (ecma_is_completion_value_normal_true (put_comp));

    ecma_deref_ecma_string (new_array_index_string_p);
  }

  if (ecma_is_completion_value_empty (ret_value))
  {
    ret_value = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_TRUE);
  }

  return ret_value;
} /* ecma_builtin_helper_array_concat_value */
/**
 * 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 */
Exemplo n.º 26
0
/**
 * GetBindingValue operation.
 *
 * See also: ECMA-262 v5, 10.2.1
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value.
 */
ecma_completion_value_t
ecma_op_get_binding_value (ecma_object_t *lex_env_p, /**< lexical environment */
                           ecma_string_t *name_p, /**< argument N */
                           bool is_strict) /**< argument S */
{
  JERRY_ASSERT (lex_env_p != NULL
                && ecma_is_lexical_environment (lex_env_p));
  JERRY_ASSERT (name_p != NULL);

  if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
  {
#ifndef JERRY_NDEBUG
# ifdef CONFIG_ECMA_COMPACT_PROFILE
    bool is_equal = false;

    ecma_string_t *arguments_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS);
    if (ecma_compare_ecma_strings (name_p, arguments_magic_string_p))
    {
      is_equal = true;
    }
    ecma_deref_ecma_string (arguments_magic_string_p);

    JERRY_ASSERT (!is_equal);

    if (is_equal)
    {
      return ecma_make_throw_obj_completion_value (ecma_builtin_get (ECMA_BUILTIN_ID_COMPACT_PROFILE_ERROR));
    }
# endif /* CONFIG_ECMA_COMPACT_PROFILE */
#endif /* !JERRY_NDEBUG */

    ecma_property_t *property_p = ecma_get_named_data_property (lex_env_p, name_p);

    ecma_value_t prop_value = ecma_get_named_data_property_value (property_p);

    /* is the binding mutable? */
    if (!ecma_is_property_writable (property_p)
        && ecma_is_value_empty (prop_value))
    {
      /* unitialized immutable binding */
      if (is_strict)
      {
        return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_REFERENCE));
      }
      else
      {
        return ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_UNDEFINED);
      }
    }

    return ecma_make_normal_completion_value (ecma_copy_value (prop_value, true));
  }
  else
  {
    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND);

    ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);

    if (ecma_op_object_get_property (binding_obj_p, name_p) == NULL)
    {
      if (is_strict)
      {
        return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_REFERENCE));
      }
      else
      {
        return ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_UNDEFINED);
      }
    }

    return ecma_op_object_get (binding_obj_p, name_p);
  }
} /* ecma_op_get_binding_value */
Exemplo n.º 27
0
/**
 * SetMutableBinding operation.
 *
 * See also: ECMA-262 v5, 10.2.1
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value.
 */
ecma_completion_value_t
ecma_op_set_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environment */
                             ecma_string_t *name_p, /**< argument N */
                             ecma_value_t value, /**< argument V */
                             bool is_strict) /**< argument S */
{
  JERRY_ASSERT (lex_env_p != NULL
                && ecma_is_lexical_environment (lex_env_p));
  JERRY_ASSERT (name_p != NULL);

  if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
  {
#ifndef JERRY_NDEBUG
# ifdef CONFIG_ECMA_COMPACT_PROFILE
    bool is_equal = false;

    ecma_string_t *arguments_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS);
    if (ecma_compare_ecma_strings (name_p, arguments_magic_string_p))
    {
      is_equal = true;
    }
    ecma_deref_ecma_string (arguments_magic_string_p);

    JERRY_ASSERT (!is_equal);

    if (is_equal)
    {
      return ecma_make_throw_obj_completion_value (ecma_builtin_get (ECMA_BUILTIN_ID_COMPACT_PROFILE_ERROR));
    }
# endif /* CONFIG_ECMA_COMPACT_PROFILE */
#endif /* !JERRY_NDEBUG */

    ecma_property_t *property_p = ecma_get_named_data_property (lex_env_p, name_p);

    if (ecma_is_property_writable (property_p))
    {
      ecma_named_data_property_assign_value (lex_env_p, property_p, value);
    }
    else if (is_strict)
    {
      return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
    }
  }
  else
  {
    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND);

    ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);

    ecma_completion_value_t completion = ecma_op_object_put (binding_obj_p,
                                                             name_p,
                                                             value,
                                                             is_strict);

    if (ecma_is_completion_value_throw (completion))
    {
      return completion;
    }
    else
    {
      JERRY_ASSERT (ecma_is_completion_value_normal_true (completion)
                    || ecma_is_completion_value_normal_false (completion));
    }
  }

  return ecma_make_empty_completion_value ();
} /* ecma_op_set_mutable_binding */
Exemplo n.º 28
0
/**
 * [[DefineOwnProperty]] ecma array object's operation
 *
 * See also:
 *          ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
 *          ECMA-262 v5, 15.4.5.1
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value
 */
ecma_completion_value_t
ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array object */
                                          ecma_string_t *property_name_p, /**< property name */
                                          const ecma_property_descriptor_t *property_desc_p, /**< property descriptor */
                                          bool is_throw) /**< flag that controls failure handling */
{
  JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY);


  // 1.
  ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH);
  ecma_property_t *len_prop_p = ecma_op_object_get_own_property (obj_p, magic_string_length_p);
  JERRY_ASSERT (len_prop_p != NULL && len_prop_p->type == ECMA_PROPERTY_NAMEDDATA);

  // 2.
  ecma_value_t old_len_value = ecma_get_named_data_property_value (len_prop_p);

  ecma_number_t *num_p = ecma_get_number_from_value (old_len_value);
  uint32_t old_len_uint32 = ecma_number_to_uint32 (*num_p);

  // 3.
  bool is_property_name_equal_length = ecma_compare_ecma_strings (property_name_p,
                                                                  magic_string_length_p);

  ecma_deref_ecma_string (magic_string_length_p);

  if (is_property_name_equal_length)
  {
    // a.
    if (!property_desc_p->is_value_defined)
    {
      // i.
      return ecma_op_general_object_define_own_property (obj_p, property_name_p, property_desc_p, is_throw);
    }

    ecma_number_t new_len_num;

    // c.
    ecma_completion_value_t completion = ecma_op_to_number (property_desc_p->value);
    if (ecma_is_completion_value_throw (completion))
    {
      return completion;
    }

    JERRY_ASSERT (ecma_is_completion_value_normal (completion)
                  && ecma_is_value_number (ecma_get_completion_value_value (completion)));

    new_len_num = *ecma_get_number_from_completion_value (completion);

    ecma_free_completion_value (completion);

    uint32_t new_len_uint32 = ecma_number_to_uint32 (new_len_num);

    // d.
    if (ecma_uint32_to_number (new_len_uint32) != new_len_num)
    {
      return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_RANGE));
    }
    else
    {
      // b., e.
      ecma_number_t *new_len_num_p = ecma_alloc_number ();
      *new_len_num_p = new_len_num;

      ecma_property_descriptor_t new_len_property_desc = *property_desc_p;
      new_len_property_desc.value = ecma_make_number_value (new_len_num_p);

      ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();

      // f.
      if (new_len_uint32 >= old_len_uint32)
      {
        // i.
        magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH);
        ret_value = ecma_op_general_object_define_own_property (obj_p,
                                                                magic_string_length_p,
                                                                &new_len_property_desc,
                                                                is_throw);
        ecma_deref_ecma_string (magic_string_length_p);
      }
      else
      {
        // g.
        if (!ecma_is_property_writable (len_prop_p))
        {
          ret_value = ecma_reject (is_throw);
        }
        else
        {
          // h.
          bool new_writable;
          if (!new_len_property_desc.is_writable_defined
              || new_len_property_desc.is_writable)
          {
            new_writable = true;
          }
          else
          {
            // ii.
            new_writable = false;

            // iii.
            new_len_property_desc.is_writable_defined = true;
            new_len_property_desc.is_writable = true;
          }

          // j.
          magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH);
          ecma_completion_value_t succeeded = ecma_op_general_object_define_own_property (obj_p,
                                                                                          magic_string_length_p,
                                                                                          &new_len_property_desc,
                                                                                          is_throw);
          ecma_deref_ecma_string (magic_string_length_p);

          /* Handling normal false and throw values */
          if (!ecma_is_completion_value_normal_true (succeeded))
          {
            JERRY_ASSERT (ecma_is_completion_value_normal_false (succeeded)
                          || ecma_is_completion_value_throw (succeeded));

            // k.
            ret_value = succeeded;
          }
          else
          {
            // l
            JERRY_ASSERT (new_len_uint32 < old_len_uint32);

            /*
             * Item i. is replaced with faster iteration: only indices that actually exist in the array, are iterated
             */
            bool is_reduce_succeeded = true;

            ecma_collection_header_t *array_index_props_p = ecma_op_object_get_property_names (obj_p,
                                                                                               true,
                                                                                               false,
                                                                                               false);

            ecma_length_t array_index_props_num = array_index_props_p->unit_number;

            MEM_DEFINE_LOCAL_ARRAY (array_index_values_p, array_index_props_num, uint32_t);

            ecma_collection_iterator_t iter;
            ecma_collection_iterator_init (&iter, array_index_props_p);

            uint32_t array_index_values_pos = 0;

            while (ecma_collection_iterator_next (&iter))
            {
              ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);

              uint32_t index;
              bool is_index = ecma_string_get_array_index (property_name_p, &index);
              JERRY_ASSERT (is_index);
              JERRY_ASSERT (index < old_len_uint32);

              array_index_values_p[array_index_values_pos++] = index;
            }

            JERRY_ASSERT (array_index_values_pos == array_index_props_num);

            while (array_index_values_pos != 0
                   && array_index_values_p[--array_index_values_pos] >= new_len_uint32)
            {
              uint32_t index = array_index_values_p[array_index_values_pos];

              // ii.
              ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
              ecma_completion_value_t delete_succeeded = ecma_op_object_delete (obj_p,
                                                                                index_string_p,
                                                                                false);
              ecma_deref_ecma_string (index_string_p);

              if (ecma_is_completion_value_normal_false (delete_succeeded))
              {
                // iii.
                new_len_uint32 = (index + 1u);

                ecma_number_t *new_len_num_p = ecma_get_number_from_value (new_len_property_desc.value);

                // 1.
                *new_len_num_p = ecma_uint32_to_number (index + 1u);

                // 2.
                if (!new_writable)
                {
                  new_len_property_desc.is_writable_defined = true;
                  new_len_property_desc.is_writable = false;
                }

                // 3.
                ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH);
                ecma_completion_value_t completion = ecma_op_general_object_define_own_property (obj_p,
                                                                                                 magic_string_length_p,
                                                                                                 &new_len_property_desc,
                                                                                                 false);
                ecma_deref_ecma_string (magic_string_length_p);

                JERRY_ASSERT (ecma_is_completion_value_normal_true (completion)
                              || ecma_is_completion_value_normal_false (completion));

                is_reduce_succeeded = false;

                break;
              }
            }

            MEM_FINALIZE_LOCAL_ARRAY (array_index_values_p);

            ecma_free_values_collection (array_index_props_p, true);

            if (!is_reduce_succeeded)
            {
              ret_value = ecma_reject (is_throw);
            }
            else
            {
              // m.
              if (!new_writable)
              {
                ecma_property_descriptor_t prop_desc_not_writable = ecma_make_empty_property_descriptor ();

                prop_desc_not_writable.is_writable_defined = true;
                prop_desc_not_writable.is_writable = false;

                ecma_completion_value_t completion_set_not_writable;
                magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH);
                completion_set_not_writable = ecma_op_general_object_define_own_property (obj_p,
                                                                                          magic_string_length_p,
                                                                                          &prop_desc_not_writable,
                                                                                          false);
                ecma_deref_ecma_string (magic_string_length_p);
                JERRY_ASSERT (ecma_is_completion_value_normal_true (completion_set_not_writable));
              }

              ret_value = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_TRUE);
            }
          }
        }
      }

      ecma_dealloc_number (new_len_num_p);

      return ret_value;
    }

    JERRY_UNREACHABLE ();
  }
  else
  {
    // 4.a.
    uint32_t index;

    if (!ecma_string_get_array_index (property_name_p, &index))
    {
      // 5.
      return ecma_op_general_object_define_own_property (obj_p,
                                                         property_name_p,
                                                         property_desc_p,
                                                         is_throw);
    }

    // 4.

    // b.
    if (index >= old_len_uint32
        && !ecma_is_property_writable (len_prop_p))
    {
      return ecma_reject (is_throw);
    }

    // c.
    ecma_completion_value_t succeeded = ecma_op_general_object_define_own_property (obj_p,
                                                                                    property_name_p,
                                                                                    property_desc_p,
                                                                                    false);
    // d.
    JERRY_ASSERT (ecma_is_completion_value_normal_true (succeeded)
                  || ecma_is_completion_value_normal_false (succeeded));

    if (ecma_is_completion_value_normal_false (succeeded))
    {
      return ecma_reject (is_throw);
    }

    // e.
    if (index >= old_len_uint32)
    {
      // i., ii.
      ecma_number_t *num_p = ecma_alloc_number ();
      *num_p = ecma_number_add (ecma_uint32_to_number (index), ECMA_NUMBER_ONE);

      ecma_named_data_property_assign_value (obj_p, len_prop_p, ecma_make_number_value (num_p));

      ecma_dealloc_number (num_p);
    }

    // f.
    return ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_TRUE);
  }

  JERRY_UNREACHABLE ();
} /* ecma_op_array_object_define_own_property */
Exemplo n.º 29
0
/**
 * Array object creation operation.
 *
 * See also: ECMA-262 v5, 15.4.2.1
 *           ECMA-262 v5, 15.4.2.2
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value
 */
ecma_completion_value_t
ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of arguments that
                                                                        are passed to Array constructor */
                             ecma_length_t arguments_list_len, /**< length of the arguments' list */
                             bool is_treat_single_arg_as_length) /**< if the value is true,
                                                                      arguments_list_len is 1
                                                                      and single argument is Number,
                                                                      then treat the single argument
                                                                      as new Array's length rather
                                                                      than as single item of the Array */
{
  JERRY_ASSERT (arguments_list_len == 0
                || arguments_list_p != NULL);

  uint32_t length;
  const ecma_value_t *array_items_p;
  ecma_length_t array_items_count;

  if (is_treat_single_arg_as_length
      && arguments_list_len == 1
      && ecma_is_value_number (arguments_list_p[0]))
  {
    ecma_number_t *num_p = ecma_get_number_from_value (arguments_list_p[0]);
    uint32_t num_uint32 = ecma_number_to_uint32 (*num_p);
    if (*num_p != ecma_uint32_to_number (num_uint32))
    {
      return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_RANGE));
    }
    else
    {
      length = num_uint32;
      array_items_p = NULL;
      array_items_count = 0;
    }
  }
  else
  {
    length = arguments_list_len;
    array_items_p = arguments_list_p;
    array_items_count = arguments_list_len;
  }

#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ARRAY_BUILTIN
  ecma_object_t *array_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_ARRAY_PROTOTYPE);
#else /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ARRAY_BUILTIN */
  ecma_object_t *array_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
#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_deref_object (array_prototype_obj_p);

  /*
   * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_ARRAY type.
   *
   * See also: ecma_object_get_class_name
   */

  ecma_string_t *length_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH);
  ecma_number_t *length_num_p = ecma_alloc_number ();
  *length_num_p = ecma_uint32_to_number (length);

  ecma_property_t *length_prop_p = ecma_create_named_data_property (obj_p,
                                                                    length_magic_string_p,
                                                                    true, false, false);
  ecma_set_named_data_property_value (length_prop_p, ecma_make_number_value (length_num_p));

  ecma_deref_ecma_string (length_magic_string_p);

  for (uint32_t index = 0;
       index < array_items_count;
       index++)
  {
    if (ecma_is_value_array_hole (array_items_p[index]))
    {
      continue;
    }

    ecma_string_t *item_name_string_p = ecma_new_ecma_string_from_uint32 (index);

    ecma_builtin_helper_def_prop (obj_p,
                                  item_name_string_p,
                                  array_items_p[index],
                                  true, /* Writable */
                                  true, /* Enumerable */
                                  true, /* Configurable */
                                  false); /* Failure handling */

    ecma_deref_ecma_string (item_name_string_p);
  }

  return ecma_make_normal_completion_value (ecma_make_object_value (obj_p));
} /* ecma_op_create_array_object */
Exemplo n.º 30
0
/*
 * Initializes the source, global, ignoreCase, multiline, and lastIndex properties of RegExp instance.
 */
void
re_initialize_props (ecma_object_t *re_obj_p, /**< RegExp obejct */
                     ecma_string_t *source_p, /**< source string */
                     uint8_t flags) /**< flags */
{
 /* Set source property. ECMA-262 v5, 15.10.7.1 */
  ecma_string_t *magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SOURCE);
  ecma_property_t *prop_p = ecma_find_named_property (re_obj_p, magic_string_p);

  if (prop_p == NULL)
  {
    prop_p = ecma_create_named_data_property (re_obj_p,
                                              magic_string_p,
                                              false, false, false);
  }

  ecma_deref_ecma_string (magic_string_p);
  JERRY_ASSERT (prop_p->type == ECMA_PROPERTY_NAMEDDATA);
  ecma_named_data_property_assign_value (re_obj_p,
                                         prop_p,
                                         ecma_make_string_value (source_p));

  ecma_simple_value_t prop_value;

  /* Set global property. ECMA-262 v5, 15.10.7.2 */
  magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GLOBAL);
  prop_p = ecma_find_named_property (re_obj_p, magic_string_p);

  if (prop_p == NULL)
  {
    prop_p = ecma_create_named_data_property (re_obj_p,
                                              magic_string_p,
                                              false, false, false);
  }

  ecma_deref_ecma_string (magic_string_p);
  prop_value = flags & RE_FLAG_GLOBAL ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE;
  JERRY_ASSERT (prop_p->type == ECMA_PROPERTY_NAMEDDATA);
  ecma_set_named_data_property_value (prop_p, ecma_make_simple_value (prop_value));

  /* Set ignoreCase property. ECMA-262 v5, 15.10.7.3 */
  magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_IGNORECASE_UL);
  prop_p = ecma_find_named_property (re_obj_p, magic_string_p);

  if (prop_p == NULL)
  {
    prop_p = ecma_create_named_data_property (re_obj_p,
                                              magic_string_p,
                                              false, false, false);
  }

  ecma_deref_ecma_string (magic_string_p);
  prop_value = flags & RE_FLAG_IGNORE_CASE ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE;
  JERRY_ASSERT (prop_p->type == ECMA_PROPERTY_NAMEDDATA);
  ecma_set_named_data_property_value (prop_p, ecma_make_simple_value (prop_value));

  /* Set multiline property. ECMA-262 v5, 15.10.7.4 */
  magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MULTILINE);
  prop_p = ecma_find_named_property (re_obj_p, magic_string_p);

  if (prop_p == NULL)
  {
    prop_p = ecma_create_named_data_property (re_obj_p,
                                              magic_string_p,
                                              false, false, false);
  }

  ecma_deref_ecma_string (magic_string_p);
  prop_value = flags & RE_FLAG_MULTILINE ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE;
  JERRY_ASSERT (prop_p->type == ECMA_PROPERTY_NAMEDDATA);
  ecma_set_named_data_property_value (prop_p, ecma_make_simple_value (prop_value));

  /* Set lastIndex property. ECMA-262 v5, 15.10.7.5 */
  magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL);
  prop_p = ecma_find_named_property (re_obj_p, magic_string_p);

  if (prop_p == NULL)
  {
    prop_p = ecma_create_named_data_property (re_obj_p,
                                              magic_string_p,
                                              true, false, false);
  }

  ecma_deref_ecma_string (magic_string_p);

  ecma_number_t *lastindex_num_p = ecma_alloc_number ();
  *lastindex_num_p = ECMA_NUMBER_ZERO;
  JERRY_ASSERT (prop_p->type == ECMA_PROPERTY_NAMEDDATA);
  ecma_named_data_property_assign_value (re_obj_p, prop_p, ecma_make_number_value (lastindex_num_p));
  ecma_dealloc_number (lastindex_num_p);
} /* re_initialize_props */