Beispiel #1
0
/**
 * Find named data property or named access property in specified object.
 *
 * @return pointer to the property, if it is found,
 *         NULL - otherwise.
 */
ecma_property_t *
ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in */
                          ecma_string_t *name_p) /**< property's name */
{
  JERRY_ASSERT (obj_p != NULL);
  JERRY_ASSERT (name_p != NULL);

  ecma_property_t *property_p;

  if (ecma_lcache_lookup (obj_p, name_p, &property_p))
  {
    return property_p;
  }

  property_p = NULL;

  ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_p);

  while (prop_iter_p != NULL)
  {
    JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));

    ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;

    JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2);

    if (prop_pair_p->names_cp[0] != ECMA_NULL_POINTER)
    {
      ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
                                                                  prop_pair_p->names_cp[0]);

      if (ecma_compare_ecma_strings (name_p, property_name_p))
      {
        property_p = prop_iter_p->types + 0;
        break;
      }
    }

    if (prop_pair_p->names_cp[1] != ECMA_NULL_POINTER)
    {
      ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
                                                                  prop_pair_p->names_cp[1]);

      if (ecma_compare_ecma_strings (name_p, property_name_p))
      {
        property_p = prop_iter_p->types + 1;
        break;
      }
    }

    prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
                                    prop_iter_p->next_property_cp);
  }

  ecma_lcache_insert (obj_p, name_p, property_p);

  return property_p;
} /* ecma_find_named_property */
Beispiel #2
0
/**
 * [[GetOwnProperty]] ecma object's operation
 *
 * See also:
 *          ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
 *
 * @return pointer to a property - if it exists,
 *         NULL (i.e. ecma-undefined) - otherwise.
 */
ecma_property_t*
ecma_op_object_get_own_property (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);

  ecma_property_t *prop_p = NULL;

  if (likely (ecma_lcache_lookup (obj_p, property_name_p, &prop_p)))
  {
    return prop_p;
  }
  else
  {
    return ecma_op_object_get_own_property_longpath (obj_p, property_name_p);
  }
} /* ecma_op_object_get_own_property */
Beispiel #3
0
/**
 * Resolve value corresponding to reference.
 *
 * @return value of the reference
 */
ecma_value_t
ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical environment */
                                 ecma_string_t *name_p) /**< identifier's name */
{
  JERRY_ASSERT (lex_env_p != NULL);

  while (lex_env_p != NULL)
  {
    ecma_lexical_environment_type_t lex_env_type = ecma_get_lex_env_type (lex_env_p);

    if (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
    {
      ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);

      if (property_p != NULL)
      {
        return ecma_fast_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
      }
    }
    else if (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND)
    {
      ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);

#ifndef CONFIG_ECMA_LCACHE_DISABLE
      ecma_property_t *property_p = ecma_lcache_lookup (binding_obj_p, name_p);

      if (property_p != NULL)
      {
        ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);

        if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA)
        {
          return ecma_fast_copy_value (prop_value_p->value);
        }

        JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);

        ecma_object_t *getter_p = ecma_get_named_accessor_property_getter (prop_value_p);

        if (getter_p == NULL)
        {
          return ECMA_VALUE_UNDEFINED;
        }

        ecma_value_t base_value = ecma_make_object_value (binding_obj_p);
        return ecma_op_function_call (getter_p, base_value, NULL, 0);
      }
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */

      ecma_value_t prop_value = ecma_op_object_find (binding_obj_p, name_p);

      if (ecma_is_value_found (prop_value))
      {
        return prop_value;
      }
    }
    else
    {
#if ENABLED (JERRY_ES2015_CLASS)
      JERRY_ASSERT (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND);
#else /* !ENABLED (JERRY_ES2015_CLASS) */
      JERRY_UNREACHABLE ();
#endif /* ENABLED (JERRY_ES2015_CLASS) */
    }

    lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
  }

#ifdef JERRY_ENABLE_ERROR_MESSAGES
  ecma_value_t name_val = ecma_make_string_value (name_p);
  ecma_value_t error_value = ecma_raise_standard_error_with_format (ECMA_ERROR_REFERENCE,
                                                                    "% is not defined",
                                                                    name_val);
#else /* !JERRY_ENABLE_ERROR_MESSAGES */
  ecma_value_t error_value = ecma_raise_reference_error (NULL);
#endif /* JERRY_ENABLE_ERROR_MESSAGES */
  return error_value;
} /* ecma_op_resolve_reference_value */
Beispiel #4
0
/**
 * Find named data property or named access property in specified object.
 *
 * @return pointer to the property, if it is found,
 *         NULL - otherwise.
 */
ecma_property_t *
ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in */
                          ecma_string_t *name_p) /**< property's name */
{
  JERRY_ASSERT (obj_p != NULL);
  JERRY_ASSERT (name_p != NULL);

  ecma_property_t *property_p = ecma_lcache_lookup (obj_p, name_p);

  if (property_p != NULL)
  {
    return property_p;
  }

  ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_p);

#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
  if (prop_iter_p != NULL
      && ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP)
  {
    ecma_string_t *property_real_name_p;
    property_p = ecma_property_hashmap_find ((ecma_property_hashmap_t *) prop_iter_p,
                                             name_p,
                                             &property_real_name_p);

    if (property_p != NULL
        && !ecma_is_property_lcached (property_p))
    {
      ecma_lcache_insert (obj_p, property_real_name_p, property_p);
    }

    return property_p;
  }
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */

  property_p = NULL;
  ecma_string_t *property_name_p = NULL;

  uint32_t steps = 0;

  while (prop_iter_p != NULL)
  {
    JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));

    ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;

    JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2);

    if (prop_pair_p->names_cp[0] != ECMA_NULL_POINTER)
    {
      property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
                                                   prop_pair_p->names_cp[0]);

      if (ecma_compare_ecma_strings (name_p, property_name_p))
      {
        property_p = prop_iter_p->types + 0;
        break;
      }
    }

    if (prop_pair_p->names_cp[1] != ECMA_NULL_POINTER)
    {
      property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
                                                   prop_pair_p->names_cp[1]);

      if (ecma_compare_ecma_strings (name_p, property_name_p))
      {
        property_p = prop_iter_p->types + 1;
        break;
      }
    }

    steps++;

    prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
                                    prop_iter_p->next_property_cp);
  }

  if (steps > (ECMA_PROPERTY_HASMAP_MINIMUM_SIZE / 4))
  {
    ecma_property_hashmap_create (obj_p);
  }

  if (property_p != NULL
      && !ecma_is_property_lcached (property_p))
  {
    ecma_lcache_insert (obj_p, property_name_p, property_p);
  }

  return property_p;
} /* ecma_find_named_property */