Ejemplo n.º 1
0
/**
 * Create a PromiseReactionJob.
 *
 * @return pointer to the PromiseReactionJob
 */
static ecma_job_promise_reaction_t *
ecma_create_promise_reaction_job (ecma_value_t reaction, /**< PromiseReaction */
                                  ecma_value_t argument) /**< argument for the reaction */
{
  JERRY_ASSERT (ecma_is_value_object (reaction));

  ecma_job_promise_reaction_t *job_p;
  job_p = (ecma_job_promise_reaction_t *) jmem_heap_alloc_block (sizeof (ecma_job_promise_reaction_t));
  job_p->reaction = ecma_copy_value (reaction);
  job_p->argument = ecma_copy_value (argument);

  return job_p;
} /* ecma_create_promise_reaction_job */
Ejemplo n.º 2
0
/**
 * Get this binding of current execution context
 *
 * @return ecma-value
 */
ecma_value_t
vm_get_this_binding (void)
{
  JERRY_ASSERT (vm_top_context_p != NULL);

  return ecma_copy_value (vm_top_context_p->this_binding, true);
} /* vm_get_this_binding */
Ejemplo n.º 3
0
/**
 * ToObject operation.
 *
 * See also:
 *          ECMA-262 v5, 9.9
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value
 */
ecma_value_t
ecma_op_to_object (ecma_value_t value) /**< ecma value */
{
  ecma_check_value_type_is_spec_defined (value);

  if (ecma_is_value_number (value))
  {
    return ecma_op_create_number_object (value);
  }
  else if (ecma_is_value_string (value))
  {
    return ecma_op_create_string_object (&value, 1);
  }
  else if (ecma_is_value_object (value))
  {
    return ecma_copy_value (value);
  }
  else
  {
    if (ecma_is_value_undefined (value)
        || ecma_is_value_null (value))
    {
      return ecma_raise_type_error (ECMA_ERR_MSG (""));
    }
    else
    {
      JERRY_ASSERT (ecma_is_value_boolean (value));

      return ecma_op_create_boolean_object (value);
    }
  }
} /* ecma_op_to_object */
/**
 * The String.prototype object's 'toString' routine
 *
 * See also:
 *          ECMA-262 v5, 15.5.4.2
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value.
 */
static ecma_completion_value_t
ecma_builtin_string_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */
{
  if (ecma_is_value_string (this_arg))
  {
    return ecma_make_normal_completion_value (ecma_copy_value (this_arg, true));
  }
  else if (ecma_is_value_object (this_arg))
  {
    ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);

    if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_STRING_UL)
    {
      ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p,
                                                                       ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE);

      ecma_string_t *prim_value_str_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
                                                                   prim_value_prop_p->u.internal_property.value);

      prim_value_str_p = ecma_copy_or_ref_ecma_string (prim_value_str_p);

      return ecma_make_normal_completion_value (ecma_make_string_value (prim_value_str_p));
    }
  }

  return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
} /* ecma_builtin_string_prototype_object_to_string */
/**
 * The Number.prototype object's 'valueOf' routine
 *
 * See also:
 *          ECMA-262 v5, 15.7.4.4
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
static ecma_value_t
ecma_builtin_number_prototype_object_value_of (ecma_value_t this_arg) /**< this argument */
{
  if (ecma_is_value_number (this_arg))
  {
    return ecma_copy_value (this_arg);
  }
  else if (ecma_is_value_object (this_arg))
  {
    ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);

    if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_NUMBER_UL)
    {
      ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p,
                                                                       ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE);

      ecma_number_t *prim_value_num_p;
      prim_value_num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t,
                                                          ecma_get_internal_property_value (prim_value_prop_p));

      ecma_number_t *ret_num_p = ecma_alloc_number ();
      *ret_num_p = *prim_value_num_p;

      return ecma_make_number_value (ret_num_p);
    }
  }

  return ecma_raise_type_error (ECMA_ERR_MSG (""));
} /* ecma_builtin_number_prototype_object_value_of */
Ejemplo n.º 6
0
/**
 * ToObject operation.
 *
 * See also:
 *          ECMA-262 v5, 9.9
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value
 */
ecma_completion_value_t
ecma_op_to_object (ecma_value_t value) /**< ecma-value */
{
  ecma_check_value_type_is_spec_defined (value);

  if (ecma_is_value_number (value))
  {
    return ecma_op_create_number_object (value);
  }
  else if (ecma_is_value_string (value))
  {
    return ecma_op_create_string_object (&value, 1);
  }
  else if (ecma_is_value_object (value))
  {
    return ecma_make_normal_completion_value (ecma_copy_value (value, true));
  }
  else
  {
    if (ecma_is_value_undefined (value)
        || ecma_is_value_null (value))
    {
      return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
    }
    else
    {
      JERRY_ASSERT (ecma_is_value_boolean (value));

      return ecma_op_create_boolean_object (value);
    }
  }
} /* ecma_op_to_object */
Ejemplo n.º 7
0
/**
 * 'Constructor call' opcode handler.
 *
 * See also: ECMA-262 v5, 11.2.2
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
ecma_value_t
opfunc_construct_n (ecma_value_t constructor_value, /**< constructor object value */
                    const ecma_value_t *arguments_list_p, /**< stack pointer */
                    ecma_length_t arguments_list_len) /**< number of arguments */
{
  ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);

  if (!ecma_is_constructor (constructor_value))
  {
    ret_value = ecma_raise_type_error ("");
  }
  else
  {
    ecma_object_t *constructor_obj_p = ecma_get_object_from_value (constructor_value);

    ECMA_TRY_CATCH (construction_ret_value,
                    ecma_op_function_construct (constructor_obj_p,
                                                arguments_list_p,
                                                arguments_list_len),
                    ret_value);

    ret_value = ecma_copy_value (construction_ret_value, true);

    ECMA_FINALIZE (construction_ret_value);
  }

  return ret_value;
} /* opfunc_construct_n */
Ejemplo n.º 8
0
/**
 * Get the result of the promise.
 *
 * @return ecma value of the promise result.
 *         Returned value must be freed with ecma_free_value
 */
inline ecma_value_t
ecma_promise_get_result (ecma_object_t *obj_p) /**< points to promise object */
{
  JERRY_ASSERT (ecma_is_promise (obj_p));

  ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;

  return ecma_copy_value (ext_object_p->u.class_prop.u.value);
} /* ecma_promise_get_result */
Ejemplo n.º 9
0
/**
 * Get this binding of current execution context
 *
 * @return ecma-value
 */
ecma_value_t
vm_get_this_binding (void)
{
  JERRY_ASSERT (vm_top_context_p != NULL);

  return ecma_copy_value (vm_stack_frame_get_reg_value (&vm_top_context_p->stack_frame,
                                                        VM_REG_SPECIAL_THIS_BINDING),
                                                        true);
} /* vm_get_this_binding */
Ejemplo n.º 10
0
/**
 * Create a PromiseResolveThenableJob
 *
 * @return pointer to the PromiseResolveThenableJob
 */
static ecma_job_promise_resolve_thenable_t *
ecma_create_promise_resolve_thenable_job (ecma_value_t promise, /**< promise to be resolved */
                                          ecma_value_t thenable, /**< thenable object */
                                          ecma_value_t then) /**< 'then' function */
{
  JERRY_ASSERT (ecma_is_promise (ecma_get_object_from_value (promise)));
  JERRY_ASSERT (ecma_is_value_object (thenable));
  JERRY_ASSERT (ecma_op_is_callable (then));

  ecma_job_promise_resolve_thenable_t *job_p;
  job_p = (ecma_job_promise_resolve_thenable_t *) jmem_heap_alloc_block (sizeof (ecma_job_promise_resolve_thenable_t));

  job_p->promise = ecma_copy_value (promise);
  job_p->thenable = ecma_copy_value (thenable);
  job_p->then = ecma_copy_value (then);

  return job_p;
} /* ecma_create_promise_resolve_thenable_job */
Ejemplo n.º 11
0
/**
 * GetBindingValue operation.
 *
 * See also: ECMA-262 v5, 10.2.1
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
ecma_value_t
ecma_op_get_binding_value (ecma_object_t *lex_env_p, /**< lexical environment */
                           ecma_string_t *name_p, /**< argument N */
                           bool is_strict) /**< argument S */
{
  JERRY_ASSERT (lex_env_p != NULL
                && ecma_is_lexical_environment (lex_env_p));
  JERRY_ASSERT (name_p != NULL);

  if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
  {
    ecma_property_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_raise_reference_error ("");
      }
      else
      {
        return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
      }
    }

    return 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_raise_reference_error ("");
      }
      else
      {
        return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
      }
    }

    return ecma_op_object_get (binding_obj_p, name_p);
  }
} /* ecma_op_get_binding_value */
/**
 * The Number.prototype object's 'valueOf' routine
 *
 * See also:
 *          ECMA-262 v5, 15.7.4.4
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
static ecma_value_t
ecma_builtin_number_prototype_object_value_of (ecma_value_t this_arg) /**< this argument */
{
  if (ecma_is_value_number (this_arg))
  {
    return ecma_copy_value (this_arg);
  }
  else if (ecma_is_value_object (this_arg))
  {
    ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);

    if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_NUMBER_UL)
    {
      ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p,
                                                                       ECMA_INTERNAL_PROPERTY_ECMA_VALUE);

      JERRY_ASSERT (ecma_is_value_number (ecma_get_internal_property_value (prim_value_prop_p)));

      return ecma_copy_value (ecma_get_internal_property_value (prim_value_prop_p));
    }
  }

  return ecma_raise_type_error (ECMA_ERR_MSG (""));
} /* ecma_builtin_number_prototype_object_value_of */
Ejemplo n.º 13
0
/**
 * ECMA-reference constructor.
 *
 * @return ECMA-reference
 *         Returned value must be freed through ecma_free_reference.
 */
ecma_reference_t
ecma_make_reference (ecma_value_t base, /**< base value */
                     ecma_string_t *name_p, /**< referenced name */
                     bool is_strict) /**< strict reference flag */
{
  ecma_ref_ecma_string (name_p);

  ecma_reference_t ref;
  ref.base = ecma_copy_value (base);
  ref.is_strict = (is_strict != 0);

  ECMA_SET_POINTER (ref.referenced_name_cp, name_p);

  return ref;
} /* ecma_make_reference */
Ejemplo n.º 14
0
/**
 * ToPrimitive operation.
 *
 * See also:
 *          ECMA-262 v5, 9.1
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value
 */
ecma_value_t
ecma_op_to_primitive (ecma_value_t value, /**< ecma value */
                      ecma_preferred_type_hint_t preferred_type) /**< preferred type hint */
{
  ecma_check_value_type_is_spec_defined (value);

  if (ecma_is_value_object (value))
  {
    ecma_object_t *obj_p = ecma_get_object_from_value (value);

    return ecma_op_object_default_value (obj_p, preferred_type);
  }
  else
  {
    return ecma_copy_value (value);
  }
} /* ecma_op_to_primitive */
/**
 * The Object object's 'create' routine
 *
 * See also:
 *          ECMA-262 v5, 15.2.3.5
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value.
 */
static ecma_completion_value_t
ecma_builtin_object_object_create (ecma_value_t this_arg, /**< 'this' argument */
                                   ecma_value_t arg1, /**< routine's first argument */
                                   ecma_value_t arg2) /**< routine's second argument */
{
  ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();

  // 1.
  if (!ecma_is_value_object (arg1) && !ecma_is_value_null (arg1))
  {
    ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
  }
  else
  {
    ecma_object_t *obj_p = NULL;

    if (!ecma_is_value_null (arg1))
    {
      obj_p = ecma_get_object_from_value (arg1);
    }
    // 2-3.
    ecma_object_t *result_obj_p = ecma_op_create_object_object_noarg_and_set_prototype (obj_p);

    // 4.
    if (!ecma_is_value_undefined (arg2))
    {
      ECMA_TRY_CATCH (obj,
                      ecma_builtin_object_object_define_properties (this_arg,
                                                                    ecma_make_object_value (result_obj_p),
                                                                    arg2),
                      ret_value);
      ECMA_FINALIZE (obj);
    }

    // 5.
    if (ecma_is_completion_value_empty (ret_value))
    {
      ret_value = ecma_make_normal_completion_value (ecma_copy_value (ecma_make_object_value (result_obj_p),
                                                                      true));
    }

    ecma_deref_object (result_obj_p);
  }

  return ret_value;
} /* ecma_builtin_object_object_create */
/**
 * Allocate a collection of ecma-values.
 *
 * @return pointer to the collection's header
 */
ecma_collection_header_t *
ecma_new_values_collection (const ecma_value_t values_buffer[], /**< ecma-values */
                            ecma_length_t values_number, /**< number of ecma-values */
                            bool do_ref_if_object) /**< if the value is object value,
                                                        increase reference counter of the object */
{
  JERRY_ASSERT (values_buffer != NULL || values_number == 0);

  const size_t values_in_chunk = sizeof (ecma_collection_chunk_t::data) / sizeof (ecma_value_t);

  ecma_collection_header_t *header_p = ecma_alloc_collection_header ();

  header_p->unit_number = values_number;

  mem_cpointer_t *next_chunk_cp_p = &header_p->first_chunk_cp;
  ecma_collection_chunk_t *last_chunk_p = NULL;
  ecma_value_t *cur_value_buf_iter_p = NULL;
  ecma_value_t *cur_value_buf_end_p = NULL;

  for (ecma_length_t value_index = 0;
       value_index < values_number;
       value_index++)
  {
    if (cur_value_buf_iter_p == cur_value_buf_end_p)
    {
      ecma_collection_chunk_t *chunk_p = ecma_alloc_collection_chunk ();
      ECMA_SET_POINTER (*next_chunk_cp_p, chunk_p);
      next_chunk_cp_p = &chunk_p->next_chunk_cp;

      cur_value_buf_iter_p = (ecma_value_t *) chunk_p->data;
      cur_value_buf_end_p = cur_value_buf_iter_p + values_in_chunk;

      last_chunk_p = chunk_p;
    }

    JERRY_ASSERT (cur_value_buf_iter_p + 1 <= cur_value_buf_end_p);

    *cur_value_buf_iter_p++ = ecma_copy_value (values_buffer[value_index], do_ref_if_object);
  }

  *next_chunk_cp_p = ECMA_NULL_POINTER;
  ECMA_SET_POINTER (header_p->last_chunk_cp, last_chunk_p);

  return header_p;
} /* ecma_new_values_collection */
/**
 * The Object object's 'defineProperty' routine
 *
 * See also:
 *          ECMA-262 v5, 15.2.3.6
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value.
 */
static ecma_completion_value_t
ecma_builtin_object_object_define_property (ecma_value_t this_arg __attr_unused___, /**< 'this' argument */
                                            ecma_value_t arg1, /**< routine's first argument */
                                            ecma_value_t arg2, /**< routine's second argument */
                                            ecma_value_t arg3) /**< routine's third argument */
{
  ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();

  if (!ecma_is_value_object (arg1))
  {
    ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
  }
  else
  {
    ecma_object_t *obj_p = ecma_get_object_from_value (arg1);

    ECMA_TRY_CATCH (name_str_value,
                    ecma_op_to_string (arg2),
                    ret_value);

    ecma_string_t *name_str_p = ecma_get_string_from_value (name_str_value);

    ecma_property_descriptor_t prop_desc;

    ECMA_TRY_CATCH (conv_result,
                    ecma_op_to_property_descriptor (arg3, &prop_desc),
                    ret_value);

    ECMA_TRY_CATCH (define_own_prop_ret,
                    ecma_op_object_define_own_property (obj_p,
                                                        name_str_p,
                                                        &prop_desc,
                                                        true),
                    ret_value);

    ret_value = ecma_make_normal_completion_value (ecma_copy_value (arg1, true));

    ECMA_FINALIZE (define_own_prop_ret);
    ecma_free_property_descriptor (&prop_desc);
    ECMA_FINALIZE (conv_result);
    ECMA_FINALIZE (name_str_value);
  }

  return ret_value;
} /* ecma_builtin_object_object_define_property */
Ejemplo n.º 18
0
/**
 * [[Get]] ecma general object's operation
 *
 * See also:
 *          ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
 *          ECMA-262 v5, 8.12.3
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value
 */
ecma_completion_value_t
ecma_op_general_object_get (ecma_object_t *obj_p, /**< the object */
                            ecma_string_t *property_name_p) /**< property name */
{
  JERRY_ASSERT (obj_p != NULL
                && !ecma_is_lexical_environment (obj_p));
  JERRY_ASSERT (property_name_p != NULL);

  // 1.
  const ecma_property_t *prop_p = ecma_op_object_get_property (obj_p, property_name_p);

  // 2.
  if (prop_p == NULL)
  {
    return ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_UNDEFINED);
  }

  // 3.
  if (prop_p->type == ECMA_PROPERTY_NAMEDDATA)
  {
    return ecma_make_normal_completion_value (ecma_copy_value (ecma_get_named_data_property_value (prop_p),
                                                               true));
  }
  else
  {
    // 4.
    ecma_object_t *getter_p = ecma_get_named_accessor_property_getter (prop_p);

    // 5.
    if (getter_p == NULL)
    {
      return ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_UNDEFINED);
    }
    else
    {
      return ecma_op_function_call (getter_p,
                                    ecma_make_object_value (obj_p),
                                    NULL);
    }
  }

  JERRY_UNREACHABLE ();
} /* ecma_op_general_object_get */
/**
 * The Object object's 'preventExtensions' routine
 *
 * See also:
 *          ECMA-262 v5, 15.2.3.10
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value.
 */
static ecma_completion_value_t
ecma_builtin_object_object_prevent_extensions (ecma_value_t this_arg __attr_unused___, /**< 'this' argument */
                                               ecma_value_t arg) /**< routine's argument */
{
  ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();

  if (!ecma_is_value_object (arg))
  {
    ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
  }
  else
  {
    ecma_object_t *obj_p = ecma_get_object_from_value (arg);
    ecma_set_object_extensible (obj_p, false);

    ret_value = ecma_make_normal_completion_value (ecma_copy_value (arg, true));
  }

  return ret_value;
} /* ecma_builtin_object_object_prevent_extensions */
Ejemplo n.º 20
0
/**
 * GetBindingValue operation.
 *
 * See also: ECMA-262 v5, 10.2.1
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
ecma_value_t
ecma_op_get_binding_value (ecma_object_t *lex_env_p, /**< lexical environment */
                           ecma_string_t *name_p, /**< argument N */
                           bool is_strict) /**< argument S */
{
  JERRY_ASSERT (lex_env_p != NULL
                && ecma_is_lexical_environment (lex_env_p));
  JERRY_ASSERT (name_p != NULL);

  if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
  {
    ecma_property_value_t *prop_value_p = ecma_get_named_data_property (lex_env_p, name_p);

    return ecma_copy_value (prop_value_p->value);
  }
  else
  {
    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);

    ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);

    ecma_value_t result = ecma_op_object_find (binding_obj_p, name_p);

    if (!ecma_is_value_found (result))
    {
      if (is_strict)
      {
        result = ecma_raise_reference_error (ECMA_ERR_MSG ("Binding does not exist or is uninitialised."));
      }
      else
      {
        result = ECMA_VALUE_UNDEFINED;
      }
    }

    return result;
  }
} /* ecma_op_get_binding_value */
Ejemplo n.º 21
0
/**
 * Construct property descriptor from specified property
 *
 * @return property descriptor, corresponding to type and content of the specified property, i.e.:
 *                  - for named data properties: { [Value], [Writable], [Enumerable], [Configurable] };
 *                  - for named accessor properties: { [Get] - if defined,
 *                                                     [Set] - if defined,
 *                                                     [Enumerable], [Configurable]
 *                                                   }.
 */
ecma_property_descriptor_t
ecma_get_property_descriptor_from_property (ecma_property_t *prop_p) /**< property */
{
  ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();

  prop_desc.is_enumerable = ecma_is_property_enumerable (prop_p);
  prop_desc.is_enumerable_defined = true;
  prop_desc.is_configurable = ecma_is_property_configurable (prop_p);
  prop_desc.is_configurable_defined = true;

  if (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA)
  {
    prop_desc.value = ecma_copy_value (ecma_get_named_data_property_value (prop_p));
    prop_desc.is_value_defined = true;
    prop_desc.is_writable = ecma_is_property_writable (prop_p);
    prop_desc.is_writable_defined = true;
  }
  else
  {
    JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
    prop_desc.get_p = ecma_get_named_accessor_property_getter (prop_p);
    prop_desc.is_get_defined = true;
    if (prop_desc.get_p != NULL)
    {
      ecma_ref_object (prop_desc.get_p);
    }

    prop_desc.set_p = ecma_get_named_accessor_property_setter (prop_p);
    prop_desc.is_set_defined = true;
    if (prop_desc.set_p != NULL)
    {
      ecma_ref_object (prop_desc.set_p);
    }
  }

  return prop_desc;
} /* ecma_get_property_descriptor_from_property */
/**
 * The Function.prototype object's 'apply' routine
 *
 * See also:
 *          ECMA-262 v5, 15.3.4.3
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
static ecma_value_t
ecma_builtin_function_prototype_object_apply (ecma_value_t this_arg, /**< this argument */
                                              ecma_value_t arg1, /**< first argument */
                                              ecma_value_t arg2) /**< second argument */
{
  ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);

  /* 1. */
  if (!ecma_op_is_callable (this_arg))
  {
    ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
  }
  else
  {
    ecma_object_t *func_obj_p = ecma_get_object_from_value (this_arg);

    /* 2. */
    if (ecma_is_value_null (arg2) || ecma_is_value_undefined (arg2))
    {
      ret_value = ecma_op_function_call (func_obj_p, arg1, NULL, 0);
    }
    else
    {
      /* 3. */
      if (!ecma_is_value_object (arg2))
      {
        ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
      }
      else
      {
        ecma_object_t *obj_p = ecma_get_object_from_value (arg2);
        ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string ();

        /* 4. */
        ECMA_TRY_CATCH (length_value,
                        ecma_op_object_get (obj_p, length_magic_string_p),
                        ret_value);

        ECMA_OP_TO_NUMBER_TRY_CATCH (length_number,
                                     length_value,
                                     ret_value);

        /* 5. */
        const uint32_t length = ecma_number_to_uint32 (length_number);

        /* 6. */
        JMEM_DEFINE_LOCAL_ARRAY (arguments_list_p, length, ecma_value_t);
        uint32_t last_index = 0;

        /* 7. */
        for (uint32_t index = 0;
             index < length && ecma_is_value_empty (ret_value);
             index++)
        {
          ecma_string_t *curr_idx_str_p = ecma_new_ecma_string_from_uint32 (index);

          ECMA_TRY_CATCH (get_value,
                          ecma_op_object_get (obj_p, curr_idx_str_p),
                          ret_value);

          arguments_list_p[index] = ecma_copy_value (get_value);
          last_index = index + 1;

          ECMA_FINALIZE (get_value);
          ecma_deref_ecma_string (curr_idx_str_p);
        }

        if (ecma_is_value_empty (ret_value))
        {
          JERRY_ASSERT (last_index == length);
          ret_value = ecma_op_function_call (func_obj_p,
                                             arg1,
                                             arguments_list_p,
                                             length);
        }

        for (uint32_t index = 0; index < last_index; index++)
        {
          ecma_free_value (arguments_list_p[index]);
        }

        JMEM_FINALIZE_LOCAL_ARRAY (arguments_list_p);

        ECMA_OP_TO_NUMBER_FINALIZE (length_number);
        ECMA_FINALIZE (length_value);
        ecma_deref_ecma_string (length_magic_string_p);
      }
    }
  }

  return ret_value;
} /* ecma_builtin_function_prototype_object_apply */
/**
 * Append new value to ecma-values collection
 */
void
ecma_append_to_values_collection (ecma_collection_header_t *header_p, /**< collection's header */
                                  ecma_value_t v, /**< ecma-value to append */
                                  bool do_ref_if_object) /**< if the value is object value,
                                                              increase reference counter of the object */
{
  const size_t values_in_chunk = sizeof (ecma_collection_chunk_t::data) / sizeof (ecma_value_t);

  size_t values_number = header_p->unit_number;
  size_t pos_of_new_value_in_chunk = values_number % values_in_chunk;

  values_number++;

  if ((ecma_length_t) values_number == values_number)
  {
    header_p->unit_number = (ecma_length_t) values_number;
  }
  else
  {
    jerry_fatal (ERR_OUT_OF_MEMORY);
  }

  ecma_collection_chunk_t *chunk_p = ECMA_GET_POINTER (ecma_collection_chunk_t,
                                                       header_p->last_chunk_cp);

  if (pos_of_new_value_in_chunk == 0)
  {
    /* all chunks are currently filled with values */

    chunk_p = ecma_alloc_collection_chunk ();
    chunk_p->next_chunk_cp = ECMA_NULL_POINTER;

    if (header_p->last_chunk_cp == ECMA_NULL_POINTER)
    {
      JERRY_ASSERT (header_p->first_chunk_cp == ECMA_NULL_POINTER);

      ECMA_SET_NON_NULL_POINTER (header_p->first_chunk_cp, chunk_p);
    }
    else
    {
      ecma_collection_chunk_t *last_chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
                                                                         header_p->last_chunk_cp);

      JERRY_ASSERT (last_chunk_p->next_chunk_cp == ECMA_NULL_POINTER);

      ECMA_SET_NON_NULL_POINTER (last_chunk_p->next_chunk_cp, chunk_p);
    }

    ECMA_SET_NON_NULL_POINTER (header_p->last_chunk_cp, chunk_p);
  }
  else
  {
    /* last chunk can be appended with the new value */
    JERRY_ASSERT (chunk_p != NULL);
  }

  ecma_value_t *values_p = (ecma_value_t *) chunk_p->data;

  JERRY_ASSERT ((uint8_t *) (values_p + pos_of_new_value_in_chunk + 1) <= (uint8_t *) (chunk_p + 1));

  values_p[pos_of_new_value_in_chunk] = ecma_copy_value (v, do_ref_if_object);
} /* ecma_append_to_values_collection */
Ejemplo n.º 24
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 */
/**
 * GetValue operation part (object base).
 *
 * See also: ECMA-262 v5, 8.7.1, section 4
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
ecma_value_t
ecma_op_get_value_object_base (ecma_reference_t ref) /**< ECMA-reference */
{
  const ecma_value_t base = ref.base;
  const bool is_unresolvable_reference = ecma_is_value_undefined (base);
  const bool has_primitive_base = (ecma_is_value_boolean (base)
                                   || ecma_is_value_number (base)
                                   || ecma_is_value_string (base));
  const bool has_object_base = (ecma_is_value_object (base)
                                && !(ecma_is_lexical_environment (ecma_get_object_from_value (base))));
  const bool is_property_reference = has_primitive_base || has_object_base;

  JERRY_ASSERT (!is_unresolvable_reference);
  JERRY_ASSERT (is_property_reference);

  ecma_string_t *referenced_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
                                                                ref.referenced_name_cp);

  // 4.a
  if (!has_primitive_base)
  {
    // 4.b case 1

    ecma_object_t *obj_p = ecma_get_object_from_value (base);
    JERRY_ASSERT (obj_p != NULL
                  && !ecma_is_lexical_environment (obj_p));

    return ecma_op_object_get (obj_p, referenced_name_p);
  }
  else
  {
    // 4.b case 2
    ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);

    // 1.
    ECMA_TRY_CATCH (obj_base, ecma_op_to_object (base), ret_value);

    ecma_object_t *obj_p = ecma_get_object_from_value (obj_base);
    JERRY_ASSERT (obj_p != NULL
                  && !ecma_is_lexical_environment (obj_p));


    // 2.
    ecma_property_t *prop_p = ecma_op_object_get_property (obj_p, referenced_name_p);

    if (prop_p == NULL)
    {
      // 3.
      ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
    }
    else if (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA)
    {
      // 4.
      ret_value = ecma_copy_value (ecma_get_named_data_property_value (prop_p), true);
    }
    else
    {
      // 5.
      JERRY_ASSERT (prop_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR);

      ecma_object_t *obj_p = ecma_get_named_accessor_property_getter (prop_p);

      // 6.
      if (obj_p == NULL)
      {
        ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
      }
      else
      {
        // 7.
        ret_value = ecma_op_function_call (obj_p, base, NULL, 0);
      }
    }

    ECMA_FINALIZE (obj_base);

    return ret_value;
  }
} /* ecma_op_get_value_object_base */
Ejemplo n.º 26
0
/**
 * [[Call]] implementation for Function objects,
 * created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION)
 * or 15.3.4.5 (ECMA_OBJECT_TYPE_BOUND_FUNCTION),
 * and for built-in Function objects
 * from section 15 (ECMA_OBJECT_TYPE_FUNCTION).
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value
 */
ecma_value_t
ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
                       ecma_value_t this_arg_value, /**< 'this' argument's value */
                       const ecma_value_t *arguments_list_p, /**< arguments list */
                       ecma_length_t arguments_list_len) /**< length of arguments list */
{
  JERRY_ASSERT (func_obj_p != NULL
                && !ecma_is_lexical_environment (func_obj_p));
  JERRY_ASSERT (ecma_op_is_callable (ecma_make_object_value (func_obj_p)));

  ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);

  if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION)
  {
    if (unlikely (ecma_get_object_is_builtin (func_obj_p)))
    {
      ret_value = ecma_builtin_dispatch_call (func_obj_p,
                                              this_arg_value,
                                              arguments_list_p,
                                              arguments_list_len);
    }
    else
    {
      /* Entering Function Code (ECMA-262 v5, 10.4.3) */
      ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_obj_p;

      ecma_object_t *scope_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
                                                                ext_func_p->u.function.scope_cp);

      // 8.
      ecma_value_t this_binding;
      bool is_strict;
      bool is_no_lex_env;

      const ecma_compiled_code_t *bytecode_data_p;
      bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
                                                         ext_func_p->u.function.bytecode_cp);

      is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) ? true : false;
      is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) ? true : false;

      // 1.
      if (is_strict)
      {
        this_binding = ecma_copy_value (this_arg_value);
      }
      else if (ecma_is_value_undefined (this_arg_value)
               || ecma_is_value_null (this_arg_value))
      {
        // 2.
        this_binding = ecma_make_object_value (ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL));
      }
      else
      {
        // 3., 4.
        this_binding = ecma_op_to_object (this_arg_value);

        JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (this_binding));
      }

      // 5.
      ecma_object_t *local_env_p;
      if (is_no_lex_env)
      {
        local_env_p = scope_p;
      }
      else
      {
        local_env_p = ecma_create_decl_lex_env (scope_p);
        if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_ARGUMENTS_NEEDED)
        {
          ecma_op_create_arguments_object (func_obj_p,
                                           local_env_p,
                                           arguments_list_p,
                                           arguments_list_len,
                                           bytecode_data_p);
        }
      }

      ret_value = vm_run (bytecode_data_p,
                          this_binding,
                          local_env_p,
                          false,
                          arguments_list_p,
                          arguments_list_len);

      if (!is_no_lex_env)
      {
        ecma_deref_object (local_env_p);
      }

      ecma_free_value (this_binding);
    }
  }
  else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
Ejemplo n.º 27
0
/**
 * The processor for PromiseReactionJob.
 *
 * See also: ES2015 25.4.2.1
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value
 */
static ecma_value_t
ecma_process_promise_reaction_job (void *obj_p) /**< the job to be operated */
{
  ecma_job_promise_reaction_t *job_p = (ecma_job_promise_reaction_t *) obj_p;
  ecma_object_t *reaction_p = ecma_get_object_from_value (job_p->reaction);

  ecma_string_t *str_capability = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_CAPABILITY);
  ecma_string_t *str_handler = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_HANDLER);
  ecma_string_t *str_resolve = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
  ecma_string_t *str_reject = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);

  /* 2. */
  ecma_value_t capability = ecma_op_object_get (reaction_p, str_capability);
  /* 3. */
  ecma_value_t handler = ecma_op_object_get (reaction_p, str_handler);

  JERRY_ASSERT (ecma_is_value_boolean (handler) || ecma_op_is_callable (handler));

  ecma_value_t handler_result;

  if (ecma_is_value_boolean (handler))
  {
    /* 4-5. True indicates "identity" and false indicates "thrower" */
    handler_result = ecma_copy_value (job_p->argument);
  }
  else
  {
    /* 6. */
    handler_result = ecma_op_function_call (ecma_get_object_from_value (handler),
                                            ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
                                            &(job_p->argument),
                                            1);
  }

  ecma_value_t status;

  if (ecma_is_value_false (handler) || ECMA_IS_VALUE_ERROR (handler_result))
  {
    if (ECMA_IS_VALUE_ERROR (handler_result))
    {
      handler_result = ecma_get_value_from_error_value (handler_result);
    }

    /* 7. */
    ecma_value_t reject = ecma_op_object_get (ecma_get_object_from_value (capability), str_reject);

    JERRY_ASSERT (ecma_op_is_callable (reject));

    status = ecma_op_function_call (ecma_get_object_from_value (reject),
                                    ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
                                    &handler_result,
                                    1);
    ecma_free_value (reject);
  }
  else
  {
    /* 8. */
    ecma_value_t resolve = ecma_op_object_get (ecma_get_object_from_value (capability), str_resolve);

    JERRY_ASSERT (ecma_op_is_callable (resolve));

    status = ecma_op_function_call (ecma_get_object_from_value (resolve),
                                    ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
                                    &handler_result,
                                    1);
    ecma_free_value (resolve);
  }

  ecma_free_value (handler_result);
  ecma_free_value (handler);
  ecma_free_value (capability);
  ecma_deref_ecma_string (str_capability);
  ecma_deref_ecma_string (str_handler);
  ecma_deref_ecma_string (str_resolve);
  ecma_deref_ecma_string (str_reject);
  ecma_free_promise_reaction_job (job_p);

  return status;
} /* ecma_process_promise_reaction_job */
/**
 * The Error.prototype object's 'toString' routine
 *
 * See also:
 *          ECMA-262 v5, 15.11.4.4
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
static ecma_value_t
ecma_builtin_error_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */
{
  ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);

  // 2.
  if (!ecma_is_value_object (this_arg))
  {
    ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
  }
  else
  {
    ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
    ecma_string_t *name_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_NAME);

    ECMA_TRY_CATCH (name_get_ret_value,
                    ecma_op_object_get (obj_p, name_magic_string_p),
                    ret_value);

    ecma_value_t name_to_str_completion;

    if (ecma_is_value_undefined (name_get_ret_value))
    {
      ecma_string_t *error_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ERROR_UL);

      name_to_str_completion = ecma_make_string_value (error_magic_string_p);
    }
    else
    {
      name_to_str_completion = ecma_op_to_string (name_get_ret_value);
    }

    if (unlikely (ecma_is_value_error (name_to_str_completion)))
    {
      ret_value = ecma_copy_value (name_to_str_completion);
    }
    else
    {
      ecma_string_t *message_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MESSAGE);

      ECMA_TRY_CATCH (msg_get_ret_value,
                      ecma_op_object_get (obj_p, message_magic_string_p),
                      ret_value);

      ecma_value_t msg_to_str_completion;

      if (ecma_is_value_undefined (msg_get_ret_value))
      {
        ecma_string_t *empty_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);

        msg_to_str_completion = ecma_make_string_value (empty_magic_string_p);
      }
      else
      {
        msg_to_str_completion = ecma_op_to_string (msg_get_ret_value);
      }

      if (unlikely (ecma_is_value_error (msg_to_str_completion)))
      {
        ret_value = ecma_copy_value (msg_to_str_completion);
      }
      else
      {
        ecma_string_t *name_string_p = ecma_get_string_from_value (name_to_str_completion);
        ecma_string_t *msg_string_p = ecma_get_string_from_value (msg_to_str_completion);

        ecma_string_t *ret_str_p;

        if (ecma_string_get_length (name_string_p) == 0)
        {
          ret_str_p = ecma_copy_or_ref_ecma_string (msg_string_p);
        }
        else if (ecma_string_get_length (msg_string_p) == 0)
        {
          ret_str_p = ecma_copy_or_ref_ecma_string (name_string_p);
        }
        else
        {
          const lit_utf8_size_t name_size = ecma_string_get_size (name_string_p);
          const lit_utf8_size_t msg_size = ecma_string_get_size (msg_string_p);
          const lit_utf8_size_t colon_size = lit_get_magic_string_size (LIT_MAGIC_STRING_COLON_CHAR);
          const lit_utf8_size_t space_size = lit_get_magic_string_size (LIT_MAGIC_STRING_SPACE_CHAR);
          const lit_utf8_size_t size = name_size + msg_size + colon_size + space_size;

          JMEM_DEFINE_LOCAL_ARRAY (ret_str_buffer, size, lit_utf8_byte_t);
          lit_utf8_byte_t *ret_str_buffer_p = ret_str_buffer;

          lit_utf8_size_t bytes = ecma_string_to_utf8_string (name_string_p, ret_str_buffer_p, name_size);
          JERRY_ASSERT (bytes == name_size);
          ret_str_buffer_p = ret_str_buffer_p + bytes;
          JERRY_ASSERT (ret_str_buffer_p <= ret_str_buffer + size);

          ret_str_buffer_p = lit_copy_magic_string_to_buffer (LIT_MAGIC_STRING_COLON_CHAR,
                                                              ret_str_buffer_p,
                                                              colon_size);
          JERRY_ASSERT (ret_str_buffer_p <= ret_str_buffer + size);

          ret_str_buffer_p = lit_copy_magic_string_to_buffer (LIT_MAGIC_STRING_SPACE_CHAR,
                                                              ret_str_buffer_p,
                                                              space_size);
          JERRY_ASSERT (ret_str_buffer_p <= ret_str_buffer + size);

          bytes = ecma_string_to_utf8_string (msg_string_p, ret_str_buffer_p, msg_size);
          JERRY_ASSERT (bytes == msg_size);
          ret_str_buffer_p = ret_str_buffer_p + bytes;
          JERRY_ASSERT (ret_str_buffer_p == ret_str_buffer + size);

          ret_str_p = ecma_new_ecma_string_from_utf8 (ret_str_buffer,
                                                      size);

          JMEM_FINALIZE_LOCAL_ARRAY (ret_str_buffer);
        }

        ret_value = ecma_make_string_value (ret_str_p);
      }

      ecma_free_value (msg_to_str_completion);

      ECMA_FINALIZE (msg_get_ret_value);

      ecma_deref_ecma_string (message_magic_string_p);
    }

    ecma_free_value (name_to_str_completion);

    ECMA_FINALIZE (name_get_ret_value);

    ecma_deref_ecma_string (name_magic_string_p);
  }

  return ret_value;
} /* ecma_builtin_error_prototype_object_to_string */
/**
 * The Object object's 'freeze' routine
 *
 * See also:
 *          ECMA-262 v5, 15.2.3.9
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value.
 */
static ecma_completion_value_t
ecma_builtin_object_object_freeze (ecma_value_t this_arg __attr_unused___, /**< 'this' argument */
                                   ecma_value_t arg) /**< routine's argument */
{
  ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();

  // 1.
  if (!ecma_is_value_object (arg))
  {
    ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
  }
  else
  {
    // 2.
    ecma_object_t *obj_p = ecma_get_object_from_value (arg);

    ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, false, false);


    ecma_collection_iterator_t iter;
    ecma_collection_iterator_init (&iter, props_p);

    while (ecma_collection_iterator_next (&iter)
           && ecma_is_completion_value_empty (ret_value))
    {
      ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p);
      ecma_property_t *property_p = ecma_op_object_get_own_property (obj_p, property_name_p);

      // 2.a
      ecma_property_descriptor_t prop_desc = ecma_get_property_descriptor_from_property (property_p);

      // 2.b
      if (property_p->type == ECMA_PROPERTY_NAMEDDATA && ecma_is_property_writable (property_p))
      {
        prop_desc.is_writable = false;
      }

      // 2.c
      if (ecma_is_property_configurable (property_p))
      {
        prop_desc.is_configurable = false;
      }

      // 2.d
      ECMA_TRY_CATCH (define_own_prop_ret,
                      ecma_op_object_define_own_property (obj_p,
                                                          property_name_p,
                                                          &prop_desc,
                                                          true),
                      ret_value);
      ECMA_FINALIZE (define_own_prop_ret);

      ecma_free_property_descriptor (&prop_desc);
    }

    ecma_free_values_collection (props_p, true);

    if (ecma_is_completion_value_empty (ret_value))
    {
      // 3.
      ecma_set_object_extensible (obj_p, false);

      // 4.
      ret_value = ecma_make_normal_completion_value (ecma_copy_value (arg, true));
    }
  }

  return ret_value;
} /* ecma_builtin_object_object_freeze */
/**
 * The Object object's 'defineProperties' routine
 *
 * See also:
 *          ECMA-262 v5, 15.2.3.7
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value.
 */
static ecma_completion_value_t
ecma_builtin_object_object_define_properties (ecma_value_t this_arg __attr_unused___, /**< 'this' argument */
                                              ecma_value_t arg1, /**< routine's first argument */
                                              ecma_value_t arg2) /**< routine's second argument */
{
  ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();

  // 1.
  if (!ecma_is_value_object (arg1))
  {
    ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
  }
  else
  {
    ecma_object_t *obj_p = ecma_get_object_from_value (arg1);

    // 2.
    ECMA_TRY_CATCH (props,
                    ecma_op_to_object (arg2),
                    ret_value);

    ecma_object_t *props_p = ecma_get_object_from_value (props);
    // 3.
    ecma_collection_header_t *prop_names_p = ecma_op_object_get_property_names (props_p, false, true, false);
    uint32_t property_number = prop_names_p->unit_number;

    ecma_collection_iterator_t iter;
    ecma_collection_iterator_init (&iter, prop_names_p);

    // 4.
    MEM_DEFINE_LOCAL_ARRAY (property_descriptors, property_number, ecma_property_descriptor_t);

    uint32_t property_descriptor_number = 0;

    while (ecma_collection_iterator_next (&iter)
           && ecma_is_completion_value_empty (ret_value))
    {
      // 5.a
      ECMA_TRY_CATCH (desc_obj,
                      ecma_op_object_get (props_p, ecma_get_string_from_value (*iter.current_value_p)),
                      ret_value);

      // 5.b
      ECMA_TRY_CATCH (conv_result,
                      ecma_op_to_property_descriptor (desc_obj,
                                                      &property_descriptors[property_descriptor_number]),
                      ret_value);

      property_descriptor_number++;

      ECMA_FINALIZE (conv_result);
      ECMA_FINALIZE (desc_obj);
    }

    // 6.
    ecma_collection_iterator_init (&iter, prop_names_p);
    for (uint32_t index = 0;
         index < property_number && ecma_is_completion_value_empty (ret_value);
         index++)
    {
      bool is_next = ecma_collection_iterator_next (&iter);
      JERRY_ASSERT (is_next);

      ECMA_TRY_CATCH (define_own_prop_ret,
                      ecma_op_object_define_own_property (obj_p,
                                                          ecma_get_string_from_value (*iter.current_value_p),
                                                          &property_descriptors[index],
                                                          true),
                      ret_value);

      ECMA_FINALIZE (define_own_prop_ret);
    }

    // Clean up
    for (uint32_t index = 0;
         index < property_descriptor_number;
         index++)
    {
      ecma_free_property_descriptor (&property_descriptors[index]);
    }

    MEM_FINALIZE_LOCAL_ARRAY (property_descriptors);

    ecma_free_values_collection (prop_names_p, true);

    // 7.
    if (ecma_is_completion_value_empty (ret_value))
    {
      ret_value = ecma_make_normal_completion_value (ecma_copy_value (arg1, true));
    }

    ECMA_FINALIZE (props);
  }

  return ret_value;
} /* ecma_builtin_object_object_define_properties */