예제 #1
0
/**
 * Get the contents of the literal as a zero-terminated string.
 * If literal is a magic string record, the corresponding string is not copied to the buffer,
 * but is returned directly.
 *
 * @return pointer to the zero-terminated string.
 */
const lit_utf8_byte_t *
lit_literal_to_utf8_string (literal_t lit, /**< literal to be processed */
                            lit_utf8_byte_t *buff_p, /**< buffer to use as a string storage */
                            size_t size) /**< size of the buffer */
{
  JERRY_ASSERT (buff_p != NULL && size > 0);
  rcs_record_t::type_t type = lit->get_type ();

  switch (type)
  {
    case LIT_STR_T:
    {
      lit_charset_record_t *ch_rec_p = static_cast<lit_charset_record_t *> (lit);
      ch_rec_p->get_charset (buff_p, size);
      return buff_p;
    }
    case LIT_MAGIC_STR_T:
    {
      return lit_get_magic_string_utf8 (lit_magic_record_get_magic_str_id (lit));
    }
    case LIT_MAGIC_STR_EX_T:
    {
      return lit_get_magic_string_ex_utf8 (lit_magic_record_ex_get_magic_str_id (lit));
    }
    case LIT_NUMBER_T:
    {
      ecma_number_to_utf8_string (static_cast<lit_number_record_t *> (lit)->get_number (), buff_p, (ssize_t)size);

      return buff_p;
    }
    default: JERRY_UNREACHABLE ();
  }

  JERRY_UNREACHABLE ();
} /* lit_literal_to_utf8_string */
예제 #2
0
/**
 * Handle calling [[Call]] of built-in object
 *
 * @return ecma value
 */
ecma_value_t
ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */
                            ecma_value_t this_arg_value, /**< 'this' argument value */
                            const ecma_value_t *arguments_list_p, /**< arguments list */
                            ecma_length_t arguments_list_len) /**< arguments list length */
{
  JERRY_ASSERT (ecma_get_object_is_builtin (obj_p));

  ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
  ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;

  if (ecma_builtin_function_is_routine (obj_p))
  {
    ret_value = ecma_builtin_dispatch_routine (ext_obj_p->u.built_in.id,
                                               ext_obj_p->u.built_in.routine_id,
                                               this_arg_value,
                                               arguments_list_p,
                                               arguments_list_len);
  }
  else
  {
    JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION);

    switch ((ecma_builtin_id_t) ext_obj_p->u.built_in.id)
    {
#define BUILTIN(builtin_id, \
                object_type, \
                object_prototype_builtin_id, \
                is_extensible, \
                is_static, \
                lowercase_name) \
      case builtin_id: \
      { \
        if (object_type == ECMA_OBJECT_TYPE_FUNCTION) \
        { \
          ret_value = ecma_builtin_ ## lowercase_name ## _dispatch_call (arguments_list_p, \
                                                                         arguments_list_len); \
        } \
        break; \
      }
#include "ecma-builtins.inc.h"

      case ECMA_BUILTIN_ID__COUNT:
      {
        JERRY_UNREACHABLE ();
      }

      default:
      {
        JERRY_UNREACHABLE (); /* The built-in is not implemented. */
      }
    }
  }

  JERRY_ASSERT (!ecma_is_value_empty (ret_value));

  return ret_value;
} /* ecma_builtin_dispatch_call */
예제 #3
0
/**
 * Handle calling [[Construct]] of built-in object
 *
 * @return ecma value
 */
ecma_value_t
ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */
                                 const ecma_value_t *arguments_list_p, /**< arguments list */
                                 ecma_length_t arguments_list_len) /**< arguments list length */
{
  JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
  JERRY_ASSERT (ecma_get_object_is_builtin (obj_p));

  ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);

  ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (obj_p,
                                                                    ECMA_INTERNAL_PROPERTY_BUILT_IN_ID);
  ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->u.internal_property.value;

  JERRY_ASSERT (ecma_builtin_is (obj_p, builtin_id));

  JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
  switch (builtin_id)
  {
#define BUILTIN(builtin_id, \
                object_type, \
                object_prototype_builtin_id, \
                is_extensible, \
                is_static, \
                lowercase_name) \
    case builtin_id: \
      { \
        if (object_type == ECMA_OBJECT_TYPE_FUNCTION) \
        { \
          ret_value = ecma_builtin_ ## lowercase_name ## _dispatch_construct (arguments_list_p, \
                                                                              arguments_list_len); \
        } \
        break; \
      }
#include "ecma-builtins.inc.h"

    case ECMA_BUILTIN_ID__COUNT:
    {
      JERRY_UNREACHABLE ();
    }

    default:
    {
#ifdef CONFIG_ECMA_COMPACT_PROFILE
      JERRY_UNREACHABLE ();
#else /* CONFIG_ECMA_COMPACT_PROFILE */
      JERRY_UNIMPLEMENTED ("The built-in is not implemented.");
#endif /* !CONFIG_ECMA_COMPACT_PROFILE */
    }
  }

  JERRY_ASSERT (!ecma_is_value_empty (ret_value));

  return ret_value;
} /* ecma_builtin_dispatch_construct */
예제 #4
0
/**
 * Invalidate LCache entries associated with given object and property name / property
 */
void
ecma_lcache_invalidate (ecma_object_t *object_p, /**< object */
                        jmem_cpointer_t name_cp, /**< property name */
                        ecma_property_t *prop_p) /**< property */
{
  JERRY_ASSERT (object_p != NULL);
  JERRY_ASSERT (prop_p != NULL && ecma_is_property_lcached (prop_p));
  JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
                || ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);

#ifndef CONFIG_ECMA_LCACHE_DISABLE
  jmem_cpointer_t object_cp;
  ECMA_SET_NON_NULL_POINTER (object_cp, object_p);

  lit_string_hash_t name_hash = ecma_string_get_property_name_hash (*prop_p, name_cp);
  size_t row_index = ecma_lcache_row_index (object_cp, name_hash);
  ecma_lcache_hash_entry_t *entry_p = JERRY_HASH_TABLE_CONTEXT (table) [row_index];

  for (uint32_t entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++)
  {
    if (entry_p->object_cp != ECMA_NULL_POINTER && entry_p->prop_p == prop_p)
    {
      JERRY_ASSERT (entry_p->object_cp == object_cp);

      ecma_lcache_invalidate_entry (entry_p);
      return;
    }
    entry_p++;
  }

  /* The property must be present. */
  JERRY_UNREACHABLE ();
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
} /* ecma_lcache_invalidate */
예제 #5
0
/**
 * Check if literal equals to charset record
 *
 * @return true if equal
 *         false otherwise
 */
static bool
lit_literal_equal_charset_rec (literal_t lit,                /**< literal to compare */
                               lit_charset_record_t *record) /**< charset record to compare */
{
  switch (lit->get_type ())
  {
    case LIT_STR_T:
    {
      return static_cast<lit_charset_record_t *>(lit)->equal (record);
    }
    case LIT_MAGIC_STR_T:
    {
      return record->equal_zt (ecma_get_magic_string_zt (lit_magic_record_get_magic_str_id (lit)));
    }
    case LIT_MAGIC_STR_EX_T:
    {
      return record->equal_zt (ecma_get_magic_string_ex_zt (lit_magic_record_ex_get_magic_str_id (lit)));
    }
    case LIT_NUMBER_T:
    {
      ecma_char_t buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
      ecma_number_to_zt_string (static_cast<lit_number_record_t *>(lit)->get_number (),
                                buff,
                                ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER);

      return record->equal_zt (buff);
    }
    default:
    {
      JERRY_UNREACHABLE ();
    }
  }
} /* lit_literal_equal_charset_rec */
예제 #6
0
/**
 * Check if two literals are equal
 *
 * @return true if equal
 *         false otherwise
 */
bool
lit_literal_equal (literal_t lit1, /**< first literal */
                   literal_t lit2) /**< second literal */
{
  switch (lit2->get_type ())
  {
    case lit_literal_storage_t::LIT_STR:
    {
      return lit_literal_equal_charset_rec (lit1, static_cast<lit_charset_record_t *>(lit2));
    }
    case lit_literal_storage_t::LIT_MAGIC_STR:
    {
      lit_magic_string_id_t magic_str_id = lit_magic_record_get_magic_str_id (lit2);
      return lit_literal_equal_utf8 (lit1,
                                     lit_get_magic_string_utf8 (magic_str_id),
                                     lit_get_magic_string_size (magic_str_id));
    }
    case lit_literal_storage_t::LIT_MAGIC_STR_EX:
    {
      lit_magic_string_ex_id_t magic_str_ex_id = lit_magic_record_ex_get_magic_str_id (lit2);
      return lit_literal_equal_utf8 (lit1,
                                     lit_get_magic_string_ex_utf8 (magic_str_ex_id),
                                     lit_get_magic_string_ex_size (magic_str_ex_id));
    }
    case lit_literal_storage_t::LIT_NUMBER:
    {
      return lit_literal_equal_num (lit1, static_cast<lit_number_record_t *>(lit2)->get_number ());
    }
    default:
    {
      JERRY_UNREACHABLE ();
    }
  }
} /* lit_literal_equal */
예제 #7
0
/**
 * Check if literal equals to zero-terminated string
 *
 * @return true if equal
 *         false otherwise
 */
bool
lit_literal_equal_zt (literal_t lit,          /**< literal to compare */
                      const ecma_char_t *str) /**< zero-terminated string to compare */
{
  switch (lit->get_type ())
  {
    case LIT_STR_T:
    {
      return static_cast<lit_charset_record_t *>(lit)->equal_zt (str);
    }
    case LIT_MAGIC_STR_T:
    {
      ecma_magic_string_id_t magic_id = lit_magic_record_get_magic_str_id (lit);
      return ecma_compare_zt_strings (str, ecma_get_magic_string_zt (magic_id));
    }
    case LIT_MAGIC_STR_EX_T:
    {
      ecma_magic_string_ex_id_t magic_id = lit_magic_record_ex_get_magic_str_id (lit);
      return ecma_compare_zt_strings (str, ecma_get_magic_string_ex_zt (magic_id));
    }
    case LIT_NUMBER_T:
    {
      ecma_char_t buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
      ecma_number_to_zt_string (static_cast<lit_number_record_t *>(lit)->get_number (),
                                buff,
                                ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER);

      return ecma_compare_zt_strings (str, buff);
    }
    default:
    {
      JERRY_UNREACHABLE ();
    }
  }
} /* lit_literal_equal_zt */
예제 #8
0
/**
 * Free the chunk
 */
inline void __attr_hot___ __attr_always_inline___
jmem_pools_free (void *chunk_p, /**< pointer to the chunk */
                 size_t size) /**< size of the chunk */
{
  JERRY_ASSERT (chunk_p != NULL);

  jmem_pools_chunk_t *const chunk_to_free_p = (jmem_pools_chunk_t *) chunk_p;

  VALGRIND_DEFINED_SPACE (chunk_to_free_p, size);

  if (size <= 8)
  {
    chunk_to_free_p->next_p = JERRY_CONTEXT (jmem_free_8_byte_chunk_p);
    JERRY_CONTEXT (jmem_free_8_byte_chunk_p) = chunk_to_free_p;
  }
  else
  {
#ifdef JERRY_CPOINTER_32_BIT
    JERRY_ASSERT (size <= 16);

    chunk_to_free_p->next_p = JERRY_CONTEXT (jmem_free_16_byte_chunk_p);
    JERRY_CONTEXT (jmem_free_16_byte_chunk_p) = chunk_to_free_p;
#else /* !JERRY_CPOINTER_32_BIT */
    JERRY_UNREACHABLE ();
#endif /* JERRY_CPOINTER_32_BIT */
  }

  VALGRIND_NOACCESS_SPACE (chunk_to_free_p, size);

  JMEM_POOLS_STAT_FREE_POOL ();
} /* jmem_pools_free */
예제 #9
0
/**
 * [[HasInstance]] ecma object's operation
 *
 * See also:
 *          ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 9
 */
ecma_completion_value_t
ecma_op_object_has_instance (ecma_object_t *obj_p, /**< the object */
                             ecma_value_t value) /**< argument 'V' */
{
  JERRY_ASSERT (obj_p != NULL
                && !ecma_is_lexical_environment (obj_p));

  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_ARRAY:
    case ECMA_OBJECT_TYPE_GENERAL:
    case ECMA_OBJECT_TYPE_STRING:
    case ECMA_OBJECT_TYPE_ARGUMENTS:
    {
      return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
    }

    case ECMA_OBJECT_TYPE_FUNCTION:
    case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
    case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
    case ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION:
    {
      return ecma_op_function_has_instance (obj_p, value);
    }
  }

  JERRY_UNREACHABLE ();
} /* ecma_op_object_has_instance */
예제 #10
0
/**
 * Get size of stored literal
 *
 * @return size of literal
 */
size_t __attr_pure___
lit_get_literal_size (const lit_record_t *lit_p) /**< literal record */
{
  const lit_record_type_t type = (const lit_record_type_t) lit_p->type;
  size_t size = 0;

  switch (type)
  {
    case LIT_RECORD_TYPE_NUMBER:
    {
      size = sizeof (lit_number_record_t);
      break;
    }
    case LIT_RECORD_TYPE_CHARSET:
    {
      const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit_p;
      size = rec_p->size + LIT_CHARSET_HEADER_SIZE;
      break;
    }
    case LIT_RECORD_TYPE_MAGIC_STR:
    case LIT_RECORD_TYPE_MAGIC_STR_EX:
    {
      size = sizeof (lit_magic_record_t);
      break;
    }
    default:
    {
      JERRY_UNREACHABLE ();
      break;
    }
  }

  JERRY_ASSERT (size > 0);
  return size;
} /* lit_get_literal_size */
예제 #11
0
/**
 * Check that
 */
static void
ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ecma-object */
                                          const ecma_property_t *prop_p) /**< ecma-property */
{
#ifndef JERRY_NDEBUG
  ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_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;

    for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
    {
      if ((prop_pair_p->header.types + i) == prop_p)
      {
        return;
      }
    }

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

  JERRY_UNREACHABLE ();

#else /* JERRY_NDEBUG */
  (void) object_p;
  (void) prop_p;
#endif /* JERRY_NDEBUG */
} /* ecma_assert_object_contains_the_property */
예제 #12
0
/**
 * Free property values and change their type to deleted.
 */
void
ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to */
                    ecma_string_t *name_p, /**< name of the property or NULL */
                    ecma_property_t *property_p) /**< property */
{
  JERRY_ASSERT (object_p != NULL && property_p != NULL);

  switch (ECMA_PROPERTY_GET_TYPE (property_p))
  {
    case ECMA_PROPERTY_TYPE_NAMEDDATA:
    {
      ecma_free_named_data_property (object_p, property_p);
      ecma_lcache_invalidate (object_p, name_p, property_p);
      break;
    }
    case ECMA_PROPERTY_TYPE_NAMEDACCESSOR:
    {
      ecma_lcache_invalidate (object_p, name_p, property_p);
      break;
    }
    case ECMA_PROPERTY_TYPE_INTERNAL:
    {
      JERRY_ASSERT (name_p == NULL);
      ecma_free_internal_property (property_p);
      break;
    }
    default:
    {
      JERRY_UNREACHABLE ();
      break;
    }
  }

  property_p->type_and_flags = ECMA_PROPERTY_TYPE_DELETED;
} /* ecma_free_property */
예제 #13
0
const char *
lexer_keyword_to_string (keyword kw)
{
  switch (kw)
  {
    case KW_BREAK: return "break";
    case KW_CASE: return "case";
    case KW_CATCH: return "catch";
    case KW_CLASS: return "class";

    case KW_CONST: return "const";
    case KW_CONTINUE: return "continue";
    case KW_DEBUGGER: return "debugger";
    case KW_DEFAULT: return "default";
    case KW_DELETE: return "delete";

    case KW_DO: return "do";
    case KW_ELSE: return "else";
    case KW_ENUM: return "enum";
    case KW_EXPORT: return "export";
    case KW_EXTENDS: return "extends";

    case KW_FINALLY: return "finally";
    case KW_FOR: return "for";
    case KW_FUNCTION: return "function";
    case KW_IF: return "if";
    case KW_IN: return "in";

    case KW_INSTANCEOF: return "instanceof";
    case KW_INTERFACE: return "interface";
    case KW_IMPORT: return "import";
    case KW_IMPLEMENTS: return "implements";
    case KW_LET: return "let";

    case KW_NEW: return "new";
    case KW_PACKAGE: return "package";
    case KW_PRIVATE: return "private";
    case KW_PROTECTED: return "protected";
    case KW_PUBLIC: return "public";

    case KW_RETURN: return "return";
    case KW_STATIC: return "static";
    case KW_SUPER: return "super";
    case KW_SWITCH: return "switch";
    case KW_THIS: return "this";

    case KW_THROW: return "throw";
    case KW_TRY: return "try";
    case KW_TYPEOF: return "typeof";
    case KW_VAR: return "var";
    case KW_VOID: return "void";

    case KW_WHILE: return "while";
    case KW_WITH: return "with";
    case KW_YIELD: return "yield";
    default: JERRY_UNREACHABLE ();
  }
}
예제 #14
0
/**
 * Allocate a chunk of specified size
 *
 * @return pointer to allocated chunk, if allocation was successful,
 *         or NULL - if not enough memory.
 */
void * __attr_hot___ __attr_always_inline___
jmem_pools_alloc (size_t size) /**< size of the chunk */
{
#ifdef JMEM_GC_BEFORE_EACH_ALLOC
  jmem_run_free_unused_memory_callbacks (JMEM_FREE_UNUSED_MEMORY_SEVERITY_HIGH);
#endif /* JMEM_GC_BEFORE_EACH_ALLOC */

  if (size <= 8)
  {
    if (JERRY_CONTEXT (jmem_free_8_byte_chunk_p) != NULL)
    {
      const jmem_pools_chunk_t *const chunk_p = JERRY_CONTEXT (jmem_free_8_byte_chunk_p);

      JMEM_POOLS_STAT_REUSE ();

      VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));

      JERRY_CONTEXT (jmem_free_8_byte_chunk_p) = chunk_p->next_p;

      VALGRIND_UNDEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));

      return (void *) chunk_p;
    }
    else
    {
      JMEM_POOLS_STAT_NEW_ALLOC ();
      return (void *) jmem_heap_alloc_block (8);
    }
  }

#ifdef JERRY_CPOINTER_32_BIT
  JERRY_ASSERT (size <= 16);

  if (JERRY_CONTEXT (jmem_free_16_byte_chunk_p) != NULL)
  {
    const jmem_pools_chunk_t *const chunk_p = JERRY_CONTEXT (jmem_free_16_byte_chunk_p);

    JMEM_POOLS_STAT_REUSE ();

    VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));

    JERRY_CONTEXT (jmem_free_16_byte_chunk_p) = chunk_p->next_p;

    VALGRIND_UNDEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));

    return (void *) chunk_p;
  }
  else
  {
    JMEM_POOLS_STAT_NEW_ALLOC ();
    return (void *) jmem_heap_alloc_block (16);
  }
#else /* !JERRY_CPOINTER_32_BIT */
  JERRY_UNREACHABLE ();
  return NULL;
#endif
} /* jmem_pools_alloc */
예제 #15
0
/**
 * If the property's name is one of built-in properties of the object
 * that is not instantiated yet, instantiate the property and
 * return pointer to the instantiated property.
 *
 * @return pointer property, if one was instantiated,
 *         NULL - otherwise.
 */
ecma_property_t*
ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object */
                                          ecma_string_t *string_p) /**< property's name */
{
  JERRY_ASSERT (ecma_get_object_is_builtin (object_p));

  ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (object_p,
                                                                    ECMA_INTERNAL_PROPERTY_BUILT_IN_ID);
  ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->u.internal_property.value;

  JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id));

  switch (builtin_id)
  {
#define BUILTIN(builtin_id, \
                object_type, \
                object_prototype_builtin_id, \
                is_extensible, \
                is_static, \
                lowercase_name) \
    case builtin_id: \
    { \
      return ecma_builtin_ ## lowercase_name ## _try_to_instantiate_property (object_p, \
                                                                              string_p); \
    }
#include "ecma-builtins.inc.h"

    case ECMA_BUILTIN_ID__COUNT:
    {
      JERRY_UNREACHABLE ();
    }

    default:
    {
#ifdef CONFIG_ECMA_COMPACT_PROFILE
      JERRY_UNREACHABLE ();
#else /* CONFIG_ECMA_COMPACT_PROFILE */
      JERRY_UNIMPLEMENTED ("The built-in is not implemented.");
#endif /* !CONFIG_ECMA_COMPACT_PROFILE */
    }
  }

  JERRY_UNREACHABLE ();
} /* ecma_builtin_try_to_instantiate_property */
예제 #16
0
/**
 * Dispatcher of built-in routines
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value.
 */
static ecma_value_t
ecma_builtin_dispatch_routine (ecma_builtin_id_t builtin_object_id, /**< built-in object' identifier */
                               uint16_t builtin_routine_id, /**< builtin-wide identifier
                                                             *   of the built-in object's
                                                             *   routine property */
                               ecma_value_t this_arg_value, /**< 'this' argument value */
                               const ecma_value_t arguments_list[], /**< list of arguments passed to routine */
                               ecma_length_t arguments_number) /**< length of arguments' list */
{
  switch (builtin_object_id)
  {
#define BUILTIN(builtin_id, \
                object_type, \
                object_prototype_builtin_id, \
                is_extensible, \
                is_static, \
                lowercase_name) \
    case builtin_id: \
      { \
        return ecma_builtin_ ## lowercase_name ## _dispatch_routine (builtin_routine_id, \
                                                                     this_arg_value, \
                                                                     arguments_list, \
                                                                     arguments_number); \
      }
#include "ecma-builtins.inc.h"

    case ECMA_BUILTIN_ID__COUNT:
    {
      JERRY_UNREACHABLE ();
    }

    default:
    {
#ifdef CONFIG_ECMA_COMPACT_PROFILE
      JERRY_UNREACHABLE ();
#else /* CONFIG_ECMA_COMPACT_PROFILE */
      JERRY_UNIMPLEMENTED ("The built-in is not implemented.");
#endif /* !CONFIG_ECMA_COMPACT_PROFILE */
    }
  }

  JERRY_UNREACHABLE ();
} /* ecma_builtin_dispatch_routine */
예제 #17
0
/**
 * Get specified magic string as zero-terminated string from external table
 *
 * @return pointer to zero-terminated magic string
 */
const lit_utf8_byte_t *
lit_get_magic_string_ex_utf8 (lit_magic_string_ex_id_t id) /**< extern magic string id */
{
  if (lit_magic_string_ex_array && id < lit_magic_string_ex_count)
  {
    return lit_magic_string_ex_array[id];
  }

  JERRY_UNREACHABLE ();
} /* lit_get_magic_string_ex_utf8 */
예제 #18
0
/**
 * Get the contents of the literal as a zero-terminated string.
 * If literal is a magic string record, the corresponding string is not copied to the buffer,
 * but is returned directly.
 *
 * @return pointer to the zero-terminated string.
 */
const ecma_char_t *
lit_literal_to_charset (literal_t lit,     /**< literal to be processed */
                        ecma_char_t *buff, /**< buffer to use as a string storage */
                        size_t size)       /**< size of the buffer */
{
  JERRY_ASSERT (buff != NULL && size > sizeof (ecma_char_t));
  rcs_record_t::type_t type = lit->get_type ();

  switch (type)
  {
    case LIT_STR_T:
    {
      lit_charset_record_t *ch_rec_p = static_cast<lit_charset_record_t *> (lit);
      ecma_length_t index = ch_rec_p->get_charset (buff, size);

      if (index != 0 && ((size_t)index + 1) * sizeof (ecma_char_t) > size)
      {
        index--;
      }
      buff[index] = '\0';

      return buff;
    }
    case LIT_MAGIC_STR_T:
    {
      return ecma_get_magic_string_zt (lit_magic_record_get_magic_str_id (lit));
    }
    case LIT_MAGIC_STR_EX_T:
    {
      return ecma_get_magic_string_ex_zt (lit_magic_record_ex_get_magic_str_id (lit));
    }
    case LIT_NUMBER_T:
    {
      ecma_number_to_zt_string (static_cast<lit_number_record_t *> (lit)->get_number (), buff, (ssize_t)size);

      return buff;
    }
    default: JERRY_UNREACHABLE ();
  }

  JERRY_UNREACHABLE ();
} /* lit_literal_to_charset */
예제 #19
0
/**
 * Free property values and change their type to deleted.
 */
void
ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to */
                    jmem_cpointer_t name_cp, /**< name of the property or ECMA_NULL_POINTER */
                    ecma_property_t *property_p) /**< property */
{
  JERRY_ASSERT (object_p != NULL && property_p != NULL);

  switch (ECMA_PROPERTY_GET_TYPE (*property_p))
  {
    case ECMA_PROPERTY_TYPE_NAMEDDATA:
    {
      if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_STRING_CONTAINER_MAGIC_STRING)
      {
        if (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
            || name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER)
        {
          ecma_free_native_pointer (property_p);
          break;
        }
      }

      ecma_free_value_if_not_object (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
      break;
    }
    case ECMA_PROPERTY_TYPE_NAMEDACCESSOR:
    {
#ifdef JERRY_CPOINTER_32_BIT
      ecma_getter_setter_pointers_t *getter_setter_pair_p;
      getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t,
                                               ECMA_PROPERTY_VALUE_PTR (property_p)->getter_setter_pair_cp);
      jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t));
#endif /* JERRY_CPOINTER_32_BIT */
      break;
    }
    default:
    {
      JERRY_UNREACHABLE ();
      return;
    }
  }

  if (ecma_is_property_lcached (property_p))
  {
    ecma_lcache_invalidate (object_p, name_cp, property_p);
  }

  if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_PROPERTY_NAME_TYPE_STRING)
  {
    ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, name_cp);
    ecma_deref_ecma_string (prop_name_p);
  }

  *property_p = ECMA_PROPERTY_TYPE_DELETED;
} /* ecma_free_property */
예제 #20
0
/**
 * Check if two literals are equal
 *
 * @return true if equal
 *         false otherwise
 */
bool
lit_literal_equal (lit_literal_t lit1, /**< first literal */
                   lit_literal_t lit2) /**< second literal */
{
  switch (lit2->type)
  {
    case LIT_RECORD_TYPE_CHARSET:
    {
      return lit_literal_equal_charset_rec (lit1, lit2);
    }
    case LIT_RECORD_TYPE_MAGIC_STR:
    {
      lit_magic_string_id_t magic_str_id = lit_magic_literal_get_magic_str_id (lit2);

      return lit_literal_equal_utf8 (lit1,
                                     lit_get_magic_string_utf8 (magic_str_id),
                                     lit_get_magic_string_size (magic_str_id));
    }
    case LIT_RECORD_TYPE_MAGIC_STR_EX:
    {
      lit_magic_string_ex_id_t magic_str_ex_id = lit_magic_literal_get_magic_str_ex_id (lit2);

      return lit_literal_equal_utf8 (lit1,
                                     lit_get_magic_string_ex_utf8 (magic_str_ex_id),
                                     lit_get_magic_string_ex_size (magic_str_ex_id));
    }
    case LIT_RECORD_TYPE_NUMBER:
    {
      ecma_number_t num = lit_number_literal_get_number (lit2);
      return lit_literal_equal_num (lit1, num);
    }
    default:
    {
      JERRY_UNREACHABLE ();
      break;
    }
  }

  JERRY_UNREACHABLE ();
  return 0;
} /* lit_literal_equal */
예제 #21
0
/**
 * Get specified magic string as zero-terminated string
 *
 * @return pointer to zero-terminated magic string
 */
const lit_utf8_byte_t *
lit_get_magic_string_utf8 (lit_magic_string_id_t id) /**< magic string id */
{
  switch (id)
  {
#define LIT_MAGIC_STRING_DEF(id, utf8_string) \
     case id: return (lit_utf8_byte_t*) utf8_string;
#include "lit-magic-strings.inc.h"
#undef LIT_MAGIC_STRING_DEF

    case LIT_MAGIC_STRING__COUNT: break;
  }

  JERRY_UNREACHABLE ();
} /* lit_get_magic_string_utf8 */
예제 #22
0
/**
 * Instantiate specified ECMA built-in object
 */
static void
ecma_instantiate_builtin (ecma_builtin_id_t id) /**< built-in id */
{
  switch (id)
  {
#define BUILTIN(builtin_id, \
                object_type, \
                object_prototype_builtin_id, \
                is_extensible, \
                is_static, \
                lowercase_name) \
    case builtin_id: \
    { \
      JERRY_ASSERT (JERRY_CONTEXT (ecma_builtin_objects)[builtin_id] == NULL); \
      \
      ecma_object_t *prototype_obj_p; \
      if (object_prototype_builtin_id == ECMA_BUILTIN_ID__COUNT) \
      { \
        prototype_obj_p = NULL; \
      } \
      else \
      { \
        if (JERRY_CONTEXT (ecma_builtin_objects)[object_prototype_builtin_id] == NULL) \
        { \
          ecma_instantiate_builtin (object_prototype_builtin_id); \
        } \
        prototype_obj_p = JERRY_CONTEXT (ecma_builtin_objects)[object_prototype_builtin_id]; \
        JERRY_ASSERT (prototype_obj_p != NULL); \
      } \
      \
      ecma_object_t *builtin_obj_p = ecma_builtin_init_object (builtin_id, \
                                                               prototype_obj_p, \
                                                               object_type, \
                                                               is_extensible); \
      JERRY_CONTEXT (ecma_builtin_objects)[builtin_id] = builtin_obj_p; \
      \
      break; \
    }
#include "ecma-builtins.inc.h"

    default:
    {
      JERRY_ASSERT (id < ECMA_BUILTIN_ID__COUNT);

      JERRY_UNREACHABLE (); /* The built-in is not implemented. */
    }
  }
} /* ecma_instantiate_builtin */
예제 #23
0
linked_list
linked_list_init (uint16_t element_size)
{
  size_t size = sizeof (linked_list_header) + linked_list_block_size (element_size);
  linked_list list = (linked_list) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_SHORT_TERM);
  if (list == null_list)
  {
    printf ("Out of memory");
    JERRY_UNREACHABLE ();
  }
  memset (list, 0, size);
  linked_list_header* header = (linked_list_header *) list;
  header->next = null_list;
  header->element_size = element_size;
  return list;
}
예제 #24
0
linked_list
linked_list_init (uint16_t element_size)
{
  JERRY_ASSERT (element_size <= linked_list_block_size ());
  size_t size = sizeof (linked_list_header) + linked_list_block_size ();
  linked_list list = (linked_list) jsp_mm_alloc (size);
  if (list == null_list)
  {
    printf ("Out of memory");
    JERRY_UNREACHABLE ();
  }
  memset (list, 0, size);
  linked_list_header* header = (linked_list_header *) list;
  header->next = null_list;
  header->element_size = element_size;
  return list;
}
예제 #25
0
/**
 * Check if literal equals to charset record
 *
 * @return true if is_equal
 *         false otherwise
 */
static bool
lit_literal_equal_charset_rec (lit_literal_t lit, /**< literal to compare */
                               lit_literal_t record) /**< charset record to compare */
{
  switch (lit->type)
  {
    case LIT_RECORD_TYPE_CHARSET:
    {
      return lit_literal_equal_charset (lit,
                                        lit_charset_literal_get_charset (record),
                                        lit_charset_literal_get_size (record));
    }
    case LIT_RECORD_TYPE_MAGIC_STR:
    {
      lit_magic_string_id_t magic_string_id = lit_magic_literal_get_magic_str_id (lit);
      return lit_literal_equal_charset (record,
                                        lit_get_magic_string_utf8 (magic_string_id),
                                        lit_get_magic_string_size (magic_string_id));
    }
    case LIT_RECORD_TYPE_MAGIC_STR_EX:
    {
      lit_magic_string_ex_id_t magic_string_id = lit_magic_literal_get_magic_str_ex_id (lit);

      return lit_literal_equal_charset (record,
                                        lit_get_magic_string_ex_utf8 (magic_string_id),
                                        lit_get_magic_string_ex_size (magic_string_id));
    }
    case LIT_RECORD_TYPE_NUMBER:
    {
      ecma_number_t num = lit_number_literal_get_number (lit);

      lit_utf8_byte_t buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
      lit_utf8_size_t copied = ecma_number_to_utf8_string (num, buff, sizeof (buff));

      return lit_literal_equal_charset (record, buff, copied);
    }
    default:
    {
      JERRY_UNREACHABLE ();
      return false;
    }
  }
} /* lit_literal_equal_charset_rec */
예제 #26
0
/**
 * Check whether the object contains a property
 */
static void
ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ecma-object */
                                          const ecma_property_value_t *prop_value_p, /**< property value */
                                          ecma_property_types_t type) /**< expected property type */
{
#ifndef JERRY_NDEBUG
  ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);

  JERRY_ASSERT (prop_iter_p != NULL);

  if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
  {
    prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
                                    prop_iter_p->next_property_cp);
  }

  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;

    for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
    {
      if ((prop_pair_p->values + i) == prop_value_p)
      {
        JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_pair_p->header.types[i]) == type);
        return;
      }
    }

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

  JERRY_UNREACHABLE ();

#else /* JERRY_NDEBUG */
  JERRY_UNUSED (object_p);
  JERRY_UNUSED (prop_value_p);
  JERRY_UNUSED (type);
#endif /* !JERRY_NDEBUG */
} /* ecma_assert_object_contains_the_property */
예제 #27
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 */
예제 #28
0
/**
 * Decrease reference counter and deallocate ecma-string
 * if the counter becomes zero.
 */
void
ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */
{
  JERRY_ASSERT (string_p != NULL);
  JERRY_ASSERT (string_p->refs_and_container >= ECMA_STRING_REF_ONE);

  /* Decrease reference counter. */
  string_p->refs_and_container = (uint16_t) (string_p->refs_and_container - ECMA_STRING_REF_ONE);

  if (string_p->refs_and_container >= ECMA_STRING_REF_ONE)
  {
    return;
  }

  switch (ECMA_STRING_GET_CONTAINER (string_p))
  {
    case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
    {
      jmem_heap_free_block (string_p, string_p->u.utf8_string.size + sizeof (ecma_string_t));
      return;
    }
    case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
    case ECMA_STRING_CONTAINER_MAGIC_STRING:
    case ECMA_STRING_CONTAINER_MAGIC_STRING_EX:
    {
      /* only the string descriptor itself should be freed */
      break;
    }
    case ECMA_STRING_LITERAL_NUMBER:
    {
      ecma_fast_free_value (string_p->u.lit_number);
      break;
    }
    default:
    {
      JERRY_UNREACHABLE ();
      break;
    }
  }

  ecma_dealloc_string (string_p);
} /* ecma_deref_ecma_string */
예제 #29
0
/**
 * Check if literal equals to utf-8 string
 *
 * @return true if equal
 *         false otherwise
 */
bool
lit_literal_equal_utf8 (lit_literal_t lit, /**< literal to compare */
                        const lit_utf8_byte_t *str_p, /**< utf-8 string to compare */
                        lit_utf8_size_t str_size) /**< string size in bytes */
{
  switch (lit->type)
  {
    case LIT_RECORD_TYPE_CHARSET:
    {
      if (lit_charset_literal_get_size (lit) != str_size)
      {
        return 0;
      }
      return !strncmp ((const char *) lit_charset_literal_get_charset (lit), (const char *) str_p, str_size);
    }
    case LIT_RECORD_TYPE_MAGIC_STR:
    {
      lit_magic_string_id_t magic_id = lit_magic_literal_get_magic_str_id (lit);
      return lit_compare_utf8_string_and_magic_string (str_p, str_size, magic_id);
    }
    case LIT_RECORD_TYPE_MAGIC_STR_EX:
    {
      lit_magic_string_ex_id_t magic_id = lit_magic_literal_get_magic_str_ex_id (lit);
      return lit_compare_utf8_string_and_magic_string_ex (str_p, str_size, magic_id);
    }
    case LIT_RECORD_TYPE_NUMBER:
    {
      ecma_number_t num = lit_number_literal_get_number (lit);

      lit_utf8_byte_t num_buf[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
      lit_utf8_size_t num_size = ecma_number_to_utf8_string (num, num_buf, sizeof (num_buf));

      return lit_compare_utf8_strings (str_p, str_size, num_buf, num_size);
    }
    default:
    {
      JERRY_UNREACHABLE ();
    }
  }
} /* lit_literal_equal_utf8 */
예제 #30
0
/**
 * [[Delete]] ecma general object's operation
 *
 * See also:
 *          ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
 *          ECMA-262 v5, 8.12.7
 *
 * @return completion value
 *         Returned value must be freed with ecma_free_completion_value
 */
ecma_completion_value_t
ecma_op_general_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);

  // 1.
  ecma_property_t *desc_p = ecma_op_object_get_own_property (obj_p, property_name_p);

  // 2.
  if (desc_p == NULL)
  {
    return ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_TRUE);
  }

  // 3.
  if (ecma_is_property_configurable (desc_p))
  {
    // a.
    ecma_delete_property (obj_p, desc_p);

    // b.
    return ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_TRUE);
  }
  else if (is_throw)
  {
    // 4.
    return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
  }
  else
  {
    // 5.
    return ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_FALSE);
  }

  JERRY_UNREACHABLE ();
} /* ecma_op_general_object_delete */