/**
 * [[Delete]] ecma Arguments object's operation
 *
 * See also:
 *          ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
 *          ECMA-262 v5, 10.6
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value
 */
ecma_value_t
ecma_op_arguments_object_delete (ecma_object_t *obj_p, /**< the object */
                                 ecma_string_t *property_name_p, /**< property name */
                                 bool is_throw) /**< flag that controls failure handling */
{
  // 1.
  ecma_property_t *map_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
  ecma_object_t *map_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t,
                                                    map_prop_p->u.internal_property.value);

  // 2.
  ecma_property_t *mapped_prop_p = ecma_op_object_get_own_property (map_p, property_name_p);

  // 3.
  ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);

  ECMA_TRY_CATCH (delete_in_args_ret,
                  ecma_op_general_object_delete (obj_p,
                                                 property_name_p,
                                                 is_throw),
                  ret_value);

  if (ecma_is_value_true (delete_in_args_ret))
  {
    if (mapped_prop_p != NULL)
    {
      ecma_value_t delete_in_map_completion = ecma_op_object_delete (map_p, property_name_p, false);
      JERRY_ASSERT (ecma_is_value_true (delete_in_map_completion));
    }

    ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
  }
  else
  {
    JERRY_ASSERT (ecma_is_value_boolean (delete_in_args_ret));

    ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
  }

  ECMA_FINALIZE (delete_in_args_ret);

  return ret_value;
} /* ecma_op_arguments_object_delete */
Example #2
0
/**
 * [[Delete]] ecma object's operation
 *
 * See also:
 *          ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value
 */
ecma_completion_value_t
ecma_op_object_delete (ecma_object_t *obj_p, /**< the object */
                       ecma_string_t *property_name_p, /**< property name */
                       bool is_throw) /**< flag that controls failure handling */
{
  JERRY_ASSERT (obj_p != NULL
                && !ecma_is_lexical_environment (obj_p));
  JERRY_ASSERT (property_name_p != NULL);

  const ecma_object_type_t type = ecma_get_object_type (obj_p);
  ecma_assert_object_type_is_valid (type);

  switch (type)
  {
    case ECMA_OBJECT_TYPE_GENERAL:
    case ECMA_OBJECT_TYPE_ARRAY:
    case ECMA_OBJECT_TYPE_FUNCTION:
    case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
    case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
    case ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION:
    case ECMA_OBJECT_TYPE_STRING:
    {
      return ecma_op_general_object_delete (obj_p,
                                            property_name_p,
                                            is_throw);
    }

    case ECMA_OBJECT_TYPE_ARGUMENTS:
    {
      return ecma_op_arguments_object_delete (obj_p,
                                              property_name_p,
                                              is_throw);
    }
  }

  JERRY_ASSERT (false);

  return ecma_make_empty_completion_value ();
} /* ecma_op_object_delete */
/**
 * Abstract operation Walk defined in 15.12.2
 *
 * See also:
 *          ECMA-262 v5, 15.12.2
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
static ecma_value_t
ecma_builtin_json_walk (ecma_object_t *reviver_p, /**< reviver function */
                        ecma_object_t *holder_p, /**< holder object */
                        ecma_string_t *name_p) /**< property name */
{
  JERRY_ASSERT (reviver_p);
  JERRY_ASSERT (holder_p);
  JERRY_ASSERT (name_p);

  ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);

  ECMA_TRY_CATCH (value_get,
                  ecma_op_object_get (holder_p, name_p),
                  ret_value);

  if (ecma_is_value_object (value_get))
  {
    ecma_object_t *object_p = ecma_get_object_from_value (value_get);

    ecma_collection_header_t *props_p = ecma_op_object_get_property_names (object_p, false, true, false);

    ecma_collection_iterator_t iter;
    ecma_collection_iterator_init (&iter, props_p);

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

      ECMA_TRY_CATCH (value_walk,
                      ecma_builtin_json_walk (reviver_p,
                                              object_p,
                                              property_name_p),
                      ret_value);

      /*
       * We cannot optimize this function since any members
       * can be changed (deleted) by the reviver function.
       */
      if (ecma_is_value_undefined (value_walk))
      {
        ecma_value_t delete_val = ecma_op_general_object_delete (object_p,
                                                                 property_name_p,
                                                                 false);
        JERRY_ASSERT (ecma_is_value_boolean (delete_val));
      }
      else
      {
        ecma_builtin_json_define_value_property (object_p,
                                                 property_name_p,
                                                 value_walk);
      }

      ECMA_FINALIZE (value_walk);
    }

    ecma_free_values_collection (props_p, true);
  }

  if (ecma_is_value_empty (ret_value))
  {
    ecma_value_t arguments_list[2];

    arguments_list[0] = ecma_make_string_value (name_p);
    arguments_list[1] = value_get;

   /*
    * The completion value can be anything including exceptions.
    */
    ret_value = ecma_op_function_call (reviver_p,
                                       ecma_make_object_value (holder_p),
                                       arguments_list,
                                       2);
  }
  else
  {
    JERRY_ASSERT (ecma_is_value_error (ret_value));
  }

  ECMA_FINALIZE (value_get);

  return ret_value;
} /* ecma_builtin_json_walk */