Exemplo n.º 1
0
/**
 * Print literal.
 */
void
util_print_literal (lexer_literal_t *literal_p) /**< literal */
{
  if (literal_p->type == LEXER_IDENT_LITERAL)
  {
    if (literal_p->status_flags & LEXER_FLAG_VAR)
    {
      printf ("var_ident(");
    }
    else
    {
      printf ("ident(");
    }
    util_print_chars (literal_p->u.char_p, literal_p->prop.length);
  }
  else if (literal_p->type == LEXER_FUNCTION_LITERAL)
  {
    printf ("function");
    return;
  }
  else if (literal_p->type == LEXER_STRING_LITERAL)
  {
    printf ("string(");
    util_print_chars (literal_p->u.char_p, literal_p->prop.length);
  }
  else if (literal_p->type == LEXER_NUMBER_LITERAL)
  {
    ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, literal_p->u.value);

    JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER);

    printf ("number(");
    util_print_number (ecma_get_number_from_value (value_p->u.lit_number));
  }
  else if (literal_p->type == LEXER_REGEXP_LITERAL)
  {
    printf ("regexp");
    return;
  }
  else
  {
    printf ("unknown");
    return;
  }

  printf (")");
} /* util_print_literal */
Exemplo n.º 2
0
/**
 * Deletes a variable.
 *
 * @return ecma value
 *         Returned value must be freed with ecma_free_value
 */
ecma_value_t
vm_op_delete_var (jmem_cpointer_t name_literal, /**< name literal */
                  ecma_object_t *lex_env_p) /**< lexical environment */
{
  ecma_value_t completion_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);

  ecma_string_t *var_name_str_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, name_literal);

  ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (lex_env_p, var_name_str_p);

  if (ref_base_lex_env_p == NULL)
  {
    completion_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
  }
  else
  {
    JERRY_ASSERT (ecma_is_lexical_environment (ref_base_lex_env_p));

    completion_value = ecma_op_delete_binding (ref_base_lex_env_p, var_name_str_p);
  }

  return completion_value;
} /* vm_op_delete_var */
Exemplo n.º 3
0
/**
 * Abort (finalize) the current stack context, and remove it.
 *
 * @return new stack top
 */
ecma_value_t *
vm_stack_context_abort (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
                        ecma_value_t *vm_stack_top_p) /**< current stack top */
{
    switch (VM_GET_CONTEXT_TYPE (vm_stack_top_p[-1]))
    {
    case VM_CONTEXT_FINALLY_THROW:
    case VM_CONTEXT_FINALLY_RETURN:
    {
        ecma_free_value (vm_stack_top_p[-2]);

        VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
        vm_stack_top_p -= PARSER_TRY_CONTEXT_STACK_ALLOCATION;
        break;
    }
    case VM_CONTEXT_FINALLY_JUMP:
    case VM_CONTEXT_TRY:
    {
        VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
        vm_stack_top_p -= PARSER_TRY_CONTEXT_STACK_ALLOCATION;
        break;
    }
    case VM_CONTEXT_CATCH:
    case VM_CONTEXT_WITH:
    {
        ecma_deref_object (frame_ctx_p->lex_env_p);
        frame_ctx_p->lex_env_p = ecma_get_object_from_value (vm_stack_top_p[-2]);

        JERRY_ASSERT (PARSER_TRY_CONTEXT_STACK_ALLOCATION == PARSER_WITH_CONTEXT_STACK_ALLOCATION);

        VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
        vm_stack_top_p -= PARSER_TRY_CONTEXT_STACK_ALLOCATION;
        break;
    }
    case VM_CONTEXT_FOR_IN:
    {
        jmem_cpointer_t current = (jmem_cpointer_t) vm_stack_top_p[-2];

        while (current != JMEM_CP_NULL)
        {
            ecma_collection_chunk_t *chunk_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
                                               current);

            lit_utf8_byte_t *data_ptr = chunk_p->data;
            ecma_free_value (*(ecma_value_t *) data_ptr);

            current = chunk_p->next_chunk_cp;
            ecma_dealloc_collection_chunk (chunk_p);
        }

        ecma_free_value (vm_stack_top_p[-3]);

        VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION);
        vm_stack_top_p -= PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION;
        break;
    }
    default:
    {
        JERRY_UNREACHABLE ();
        break;
    }
    }

    return vm_stack_top_p;
} /* vm_stack_context_abort */
Exemplo n.º 4
0
/**
 * Receive message from the client.
 *
 * @return true - if message is processed successfully
 *         false - otherwise
 */
inline bool __attr_always_inline___
jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the received data */
                                uint32_t message_size, /**< message size */
                                bool *resume_exec_p, /**< pointer to the resume exec flag */
                                uint8_t *expected_message_type_p, /**< message type */
                                jerry_debugger_uint8_data_t **message_data_p) /**< custom message data */
{
  /* Process the received message. */

  if (recv_buffer_p[0] >= JERRY_DEBUGGER_CONTINUE
      && !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE))
  {
    JERRY_ERROR_MSG ("Message requires breakpoint mode\n");
    jerry_debugger_close_connection ();
    return false;
  }

  if (*expected_message_type_p != 0)
  {
    JERRY_ASSERT (*expected_message_type_p == JERRY_DEBUGGER_EVAL_PART
                  || *expected_message_type_p == JERRY_DEBUGGER_CLIENT_SOURCE_PART);

    jerry_debugger_uint8_data_t *uint8_data_p = (jerry_debugger_uint8_data_t *) *message_data_p;

    if (recv_buffer_p[0] != *expected_message_type_p)
    {
      jmem_heap_free_block (uint8_data_p, uint8_data_p->uint8_size + sizeof (jerry_debugger_uint8_data_t));
      JERRY_ERROR_MSG ("Unexpected message\n");
      jerry_debugger_close_connection ();
      return false;
    }

    JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_uint8_data_part_t, uint8_data_part_p);

    if (message_size < sizeof (jerry_debugger_receive_uint8_data_part_t) + 1)
    {
      jmem_heap_free_block (uint8_data_p, uint8_data_p->uint8_size + sizeof (jerry_debugger_uint8_data_t));
      JERRY_ERROR_MSG ("Invalid message size\n");
      jerry_debugger_close_connection ();
      return false;
    }

    uint32_t expected_data = uint8_data_p->uint8_size - uint8_data_p->uint8_offset;

    message_size -= (uint32_t) sizeof (jerry_debugger_receive_uint8_data_part_t);

    if (message_size > expected_data)
    {
      jmem_heap_free_block (uint8_data_p, uint8_data_p->uint8_size + sizeof (jerry_debugger_uint8_data_t));
      JERRY_ERROR_MSG ("Invalid message size\n");
      jerry_debugger_close_connection ();
      return false;
    }

    lit_utf8_byte_t *string_p = (lit_utf8_byte_t *) (uint8_data_p + 1);
    memcpy (string_p + uint8_data_p->uint8_offset,
            (lit_utf8_byte_t *) (uint8_data_part_p + 1),
            message_size);

    if (message_size < expected_data)
    {
      uint8_data_p->uint8_offset += message_size;
      return true;
    }

    bool result;

    if (*expected_message_type_p == JERRY_DEBUGGER_EVAL_PART)
    {
      if (jerry_debugger_send_eval (string_p, uint8_data_p->uint8_size))
      {
        *resume_exec_p = true;
      }
      result = (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) != 0;
    }
    else
    {
      result = true;
      JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
      *resume_exec_p = true;
    }

    *expected_message_type_p = 0;
    return result;
  }

  switch (recv_buffer_p[0])
  {
    case JERRY_DEBUGGER_FREE_BYTE_CODE_CP:
    {
      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_byte_code_cp_t);

      JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_byte_code_cp_t, byte_code_p);

      jmem_cpointer_t byte_code_free_cp;
      memcpy (&byte_code_free_cp, byte_code_p->byte_code_cp, sizeof (jmem_cpointer_t));

      if (byte_code_free_cp != JERRY_CONTEXT (debugger_byte_code_free_tail))
      {
        JERRY_ERROR_MSG ("Invalid byte code free order\n");
        jerry_debugger_close_connection ();
        return false;
      }

      jerry_debugger_byte_code_free_t *byte_code_free_p;
      byte_code_free_p = JMEM_CP_GET_NON_NULL_POINTER (jerry_debugger_byte_code_free_t,
                                                       byte_code_free_cp);

      if (byte_code_free_p->prev_cp != ECMA_NULL_POINTER)
      {
        JERRY_CONTEXT (debugger_byte_code_free_tail) = byte_code_free_p->prev_cp;
      }
      else
      {
        JERRY_CONTEXT (debugger_byte_code_free_head) = ECMA_NULL_POINTER;
        JERRY_CONTEXT (debugger_byte_code_free_tail) = ECMA_NULL_POINTER;
      }

#ifdef JMEM_STATS
      jmem_stats_free_byte_code_bytes (((size_t) byte_code_free_p->size) << JMEM_ALIGNMENT_LOG);
#endif /* JMEM_STATS */

      jmem_heap_free_block (byte_code_free_p,
                            ((size_t) byte_code_free_p->size) << JMEM_ALIGNMENT_LOG);
      return true;
    }

    case JERRY_DEBUGGER_UPDATE_BREAKPOINT:
    {
      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_update_breakpoint_t);

      JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_update_breakpoint_t, update_breakpoint_p);

      jmem_cpointer_t byte_code_cp;
      memcpy (&byte_code_cp, update_breakpoint_p->byte_code_cp, sizeof (jmem_cpointer_t));
      uint8_t *byte_code_p = JMEM_CP_GET_NON_NULL_POINTER (uint8_t, byte_code_cp);

      uint32_t offset;
      memcpy (&offset, update_breakpoint_p->offset, sizeof (uint32_t));
      byte_code_p += offset;

      JERRY_ASSERT (*byte_code_p == CBC_BREAKPOINT_ENABLED || *byte_code_p == CBC_BREAKPOINT_DISABLED);

      *byte_code_p = update_breakpoint_p->is_set_breakpoint ? CBC_BREAKPOINT_ENABLED : CBC_BREAKPOINT_DISABLED;
      return true;
    }

    case JERRY_DEBUGGER_MEMSTATS:
    {
      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);

      jerry_debugger_send_memstats ();
      return true;
    }

    case JERRY_DEBUGGER_STOP:
    {
      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);

      JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
      JERRY_CONTEXT (debugger_stop_context) = NULL;
      *resume_exec_p = false;
      return true;
    }

    case JERRY_DEBUGGER_CONTINUE:
    {
      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);

      JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_STOP);
      JERRY_CONTEXT (debugger_stop_context) = NULL;
      *resume_exec_p = true;
      return true;
    }

    case JERRY_DEBUGGER_STEP:
    {
      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);

      JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
      JERRY_CONTEXT (debugger_stop_context) = NULL;
      *resume_exec_p = true;
      return true;
    }

    case JERRY_DEBUGGER_NEXT:
    {
      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);

      JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
      JERRY_CONTEXT (debugger_stop_context) = JERRY_CONTEXT (vm_top_context_p);
      *resume_exec_p = true;
      return true;
    }

    case JERRY_DEBUGGER_FINISH:
    {
      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);

      JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);

      /* This will point to the current context's parent (where the function was called)
       * and in case of NULL the result will the same as in case of STEP. */
      JERRY_CONTEXT (debugger_stop_context) = JERRY_CONTEXT (vm_top_context_p->prev_context_p);
      *resume_exec_p = true;
      return true;
    }

    case JERRY_DEBUGGER_GET_BACKTRACE:
    {
      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_get_backtrace_t);

      jerry_debugger_send_backtrace (recv_buffer_p);
      return true;
    }

    case JERRY_DEBUGGER_EXCEPTION_CONFIG:
    {
      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_exception_config_t);
      JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_exception_config_t, exception_config_p);

      if (exception_config_p->enable == 0)
      {
        JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_IGNORE_EXCEPTION);
        JERRY_DEBUG_MSG ("Stop at exception disabled\n");
      }
      else
      {
        JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE_EXCEPTION);
        JERRY_DEBUG_MSG ("Stop at exception enabled\n");
      }

      return true;
    }

    case JERRY_DEBUGGER_PARSER_CONFIG:
    {
      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_parser_config_t);
      JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_parser_config_t, parser_config_p);

      if (parser_config_p->enable_wait != 0)
      {
        JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_PARSER_WAIT);
        JERRY_DEBUG_MSG ("Waiting after parsing enabled\n");
      }
      else
      {
        JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_PARSER_WAIT);
        JERRY_DEBUG_MSG ("Waiting after parsing disabled\n");
      }

      return true;
    }

    case JERRY_DEBUGGER_PARSER_RESUME:
    {
      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);

      if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_PARSER_WAIT_MODE))
      {
        JERRY_ERROR_MSG ("Not in parser wait mode\n");
        jerry_debugger_close_connection ();
        return false;
      }

      JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_PARSER_WAIT_MODE);
      return true;
    }

    case JERRY_DEBUGGER_EVAL:
    {
      if (message_size < sizeof (jerry_debugger_receive_eval_first_t) + 1)
      {
        JERRY_ERROR_MSG ("Invalid message size\n");
        jerry_debugger_close_connection ();
        return false;
      }

      JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_eval_first_t, eval_first_p);

      uint32_t eval_size;
      memcpy (&eval_size, eval_first_p->eval_size, sizeof (uint32_t));

      if (eval_size <= JERRY_CONTEXT (debugger_max_receive_size) - sizeof (jerry_debugger_receive_eval_first_t))
      {
        if (eval_size != message_size - sizeof (jerry_debugger_receive_eval_first_t))
        {
          JERRY_ERROR_MSG ("Invalid message size\n");
          jerry_debugger_close_connection ();
          return false;
        }

        if (jerry_debugger_send_eval ((lit_utf8_byte_t *) (eval_first_p + 1), eval_size))
        {
          *resume_exec_p = true;
        }

        return (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) != 0;
      }

      jerry_debugger_uint8_data_t *eval_uint8_data_p;
      size_t eval_data_size = sizeof (jerry_debugger_uint8_data_t) + eval_size;

      eval_uint8_data_p = (jerry_debugger_uint8_data_t *) jmem_heap_alloc_block (eval_data_size);

      eval_uint8_data_p->uint8_size = eval_size;
      eval_uint8_data_p->uint8_offset = (uint32_t) (message_size - sizeof (jerry_debugger_receive_eval_first_t));

      lit_utf8_byte_t *eval_string_p = (lit_utf8_byte_t *) (eval_uint8_data_p + 1);
      memcpy (eval_string_p,
              (lit_utf8_byte_t *) (eval_first_p + 1),
              message_size - sizeof (jerry_debugger_receive_eval_first_t));

      *message_data_p = eval_uint8_data_p;
      *expected_message_type_p = JERRY_DEBUGGER_EVAL_PART;

      return true;
    }

    case JERRY_DEBUGGER_CLIENT_SOURCE:
    {
      if (message_size <= sizeof (jerry_debugger_receive_client_source_first_t))
      {
        JERRY_ERROR_MSG ("Invalid message size\n");
        jerry_debugger_close_connection ();
        return false;
      }

      if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE))
      {
        JERRY_ERROR_MSG ("Not in client source mode\n");
        jerry_debugger_close_connection ();
        return false;
      }

      JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_client_source_first_t, client_source_first_p);

      uint32_t client_source_size;
      memcpy (&client_source_size, client_source_first_p->code_size, sizeof (uint32_t));

      uint32_t header_size = sizeof (jerry_debugger_receive_client_source_first_t);

      if (client_source_size <= JERRY_CONTEXT (debugger_max_receive_size) - header_size
          && client_source_size != message_size - header_size)
      {
        JERRY_ERROR_MSG ("Invalid message size\n");
        jerry_debugger_close_connection ();
        return false;
      }

      jerry_debugger_uint8_data_t *client_source_data_p;
      size_t client_source_data_size = sizeof (jerry_debugger_uint8_data_t) + client_source_size;

      client_source_data_p = (jerry_debugger_uint8_data_t *) jmem_heap_alloc_block (client_source_data_size);

      client_source_data_p->uint8_size = client_source_size;
      client_source_data_p->uint8_offset = (uint32_t) (message_size
                                            - sizeof (jerry_debugger_receive_client_source_first_t));

      lit_utf8_byte_t *client_source_string_p = (lit_utf8_byte_t *) (client_source_data_p + 1);
      memcpy (client_source_string_p,
              (lit_utf8_byte_t *) (client_source_first_p + 1),
              message_size - sizeof (jerry_debugger_receive_client_source_first_t));

      *message_data_p = client_source_data_p;

      if (client_source_data_p->uint8_size != client_source_data_p->uint8_offset)
      {
        *expected_message_type_p = JERRY_DEBUGGER_CLIENT_SOURCE_PART;
      }
      else
      {
        JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
        *resume_exec_p = true;
      }
      return true;
    }

    case JERRY_DEBUGGER_NO_MORE_SOURCES:
    {
      if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE))
      {
        JERRY_ERROR_MSG ("Not in client source mode\n");
        jerry_debugger_close_connection ();
        return false;
      }

      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);

      JERRY_DEBUGGER_UPDATE_FLAGS (JERRY_DEBUGGER_CLIENT_NO_SOURCE, JERRY_DEBUGGER_CLIENT_SOURCE_MODE);

      *resume_exec_p = true;

      return true;
    }

    case JERRY_DEBUGGER_CONTEXT_RESET:
    {
      if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE))
      {
        JERRY_ERROR_MSG ("Not in client source mode\n");
        jerry_debugger_close_connection ();
        return false;
      }

      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);

      JERRY_DEBUGGER_UPDATE_FLAGS (JERRY_DEBUGGER_CONTEXT_RESET_MODE, JERRY_DEBUGGER_CLIENT_SOURCE_MODE);

      *resume_exec_p = true;

      return true;
    }

    default:
    {
      JERRY_ERROR_MSG ("Unexpected message.");
      jerry_debugger_close_connection ();
      return false;
    }
  }
} /* jerry_debugger_process_message */
Exemplo n.º 5
0
/**
 * Arguments object creation operation.
 *
 * See also: ECMA-262 v5, 10.6
 */
void
ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function */
                                 ecma_object_t *lex_env_p, /**< lexical environment the Arguments
                                                                object is created for */
                                 const ecma_value_t *arguments_list_p, /**< arguments list */
                                 ecma_length_t arguments_number, /**< length of arguments list */
                                 const ecma_compiled_code_t *bytecode_data_p) /**< byte code */
{
  // 2., 3., 6.
  ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);

  ecma_object_t *obj_p = ecma_create_object (prototype_p, false, true, ECMA_OBJECT_TYPE_GENERAL);

  ecma_deref_object (prototype_p);

  // 11.a, 11.b
  for (ecma_length_t indx = 0;
       indx < arguments_number;
       indx++)
  {
    ecma_value_t completion;
    ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 (indx);

    completion = ecma_builtin_helper_def_prop (obj_p,
                                               indx_string_p,
                                               arguments_list_p[indx],
                                               true, /* Writable */
                                               true, /* Enumerable */
                                               true, /* Configurable */
                                               false); /* Failure handling */

    JERRY_ASSERT (ecma_is_value_true (completion));

    ecma_deref_ecma_string (indx_string_p);
  }

  bool is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0;

  // 1.

  // 4.
  ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
  ECMA_PROPERTY_VALUE_PTR (class_prop_p)->value = LIT_MAGIC_STRING_ARGUMENTS_UL;

  // 7.
  ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string ();
  ecma_value_t completion = ecma_builtin_helper_def_prop (obj_p,
                                                          length_magic_string_p,
                                                          ecma_make_uint32_value (arguments_number),
                                                          true, /* Writable */
                                                          false, /* Enumerable */
                                                          true, /* Configurable */
                                                          false); /* Failure handling */

  JERRY_ASSERT (ecma_is_value_true (completion));
  ecma_deref_ecma_string (length_magic_string_p);

  ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();

  if (bytecode_data_p != NULL)
  {
    ecma_length_t formal_params_number;
    jmem_cpointer_t *literal_p;

    if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
    {
      cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p;
      uint8_t *byte_p = (uint8_t *) bytecode_data_p;

      formal_params_number = args_p->argument_end;
      literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
    }
    else
    {
      cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p;
      uint8_t *byte_p = (uint8_t *) bytecode_data_p;

      formal_params_number = args_p->argument_end;
      literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
    }

    if (!is_strict
        && arguments_number > 0
        && formal_params_number > 0)
    {
      // 8.
      ecma_object_t *map_p = ecma_op_create_object_object_noarg ();

      // 11.c
      for (uint32_t indx = 0;
           indx < formal_params_number;
           indx++)
      {
        // i.
        if (literal_p[indx] == JMEM_CP_NULL)
        {
          continue;
        }

        ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, literal_p[indx]);
        ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 ((uint32_t) indx);

        prop_desc.is_value_defined = true;
        prop_desc.value = ecma_make_string_value (name_p);

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

        completion = ecma_op_object_define_own_property (map_p,
                                                         indx_string_p,
                                                         &prop_desc,
                                                         false);
        JERRY_ASSERT (ecma_is_value_true (completion));

        ecma_deref_ecma_string (indx_string_p);
      }

      // 12.
      ecma_set_object_type (obj_p, ECMA_OBJECT_TYPE_ARGUMENTS);

      /*
       * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_ARGUMENTS type.
       *
       * See also: ecma_object_get_class_name
       */
      ecma_delete_property (obj_p, class_prop_p);

      ecma_property_t *parameters_map_prop_p = ecma_create_internal_property (obj_p,
                                                                              ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
      ECMA_SET_INTERNAL_VALUE_POINTER (ECMA_PROPERTY_VALUE_PTR (parameters_map_prop_p)->value, map_p);

      ecma_property_t *scope_prop_p = ecma_create_internal_property (map_p,
                                                                     ECMA_INTERNAL_PROPERTY_SCOPE);
      ECMA_SET_INTERNAL_VALUE_POINTER (ECMA_PROPERTY_VALUE_PTR (scope_prop_p)->value, lex_env_p);

      ecma_deref_object (map_p);
    }
  }

  // 13.
  if (!is_strict)
  {
    ecma_string_t *callee_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLEE);

    completion = ecma_builtin_helper_def_prop (obj_p,
                                               callee_magic_string_p,
                                               ecma_make_object_value (func_obj_p),
                                               true, /* Writable */
                                               false, /* Enumerable */
                                               true, /* Configurable */
                                               false); /* Failure handling */

    JERRY_ASSERT (ecma_is_value_true (completion));

    ecma_deref_ecma_string (callee_magic_string_p);
  }
  else
  {
    ecma_object_t *thrower_p = ecma_builtin_get (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER);

    // 14.
    prop_desc = ecma_make_empty_property_descriptor ();
    {
      prop_desc.is_get_defined = true;
      prop_desc.get_p = thrower_p;

      prop_desc.is_set_defined = true;
      prop_desc.set_p = thrower_p;

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

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

    ecma_string_t *callee_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLEE);

    completion = ecma_op_object_define_own_property (obj_p,
                                                     callee_magic_string_p,
                                                     &prop_desc,
                                                     false);
    JERRY_ASSERT (ecma_is_value_true (completion));
    ecma_deref_ecma_string (callee_magic_string_p);

    ecma_string_t *caller_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLER);
    completion = ecma_op_object_define_own_property (obj_p,
                                                     caller_magic_string_p,
                                                     &prop_desc,
                                                     false);
    JERRY_ASSERT (ecma_is_value_true (completion));
    ecma_deref_ecma_string (caller_magic_string_p);

    ecma_deref_object (thrower_p);
  }

  ecma_string_t *arguments_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS);

  if (is_strict)
  {
    ecma_op_create_immutable_binding (lex_env_p, arguments_string_p);
    ecma_op_initialize_immutable_binding (lex_env_p,
                                          arguments_string_p,
                                          ecma_make_object_value (obj_p));
  }
  else
  {
    ecma_value_t completion = ecma_op_create_mutable_binding (lex_env_p,
                                                              arguments_string_p,
                                                              false);
    JERRY_ASSERT (ecma_is_value_empty (completion));

    completion = ecma_op_set_mutable_binding (lex_env_p,
                                              arguments_string_p,
                                              ecma_make_object_value (obj_p),
                                              false);

    JERRY_ASSERT (ecma_is_value_empty (completion));
  }

  ecma_deref_ecma_string (arguments_string_p);
  ecma_deref_object (obj_p);
} /* ecma_op_create_arguments_object */
Exemplo n.º 6
0
/**
 * Decrease reference counter of Compact
 * Byte Code or regexp byte code.
 */
void
ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
{
  JERRY_ASSERT (bytecode_p->refs > 0);

  bytecode_p->refs--;

  if (bytecode_p->refs > 0)
  {
    /* Non-zero reference counter. */
    return;
  }

  if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
  {
    jmem_cpointer_t *literal_start_p = NULL;
    uint32_t literal_end;
    uint32_t const_literal_end;

    if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
    {
      uint8_t *byte_p = (uint8_t *) bytecode_p;
      literal_start_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));

      cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_p;
      literal_end = args_p->literal_end;
      const_literal_end = args_p->const_literal_end;
    }
    else
    {
      uint8_t *byte_p = (uint8_t *) bytecode_p;
      literal_start_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));

      cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_p;
      literal_end = args_p->literal_end;
      const_literal_end = args_p->const_literal_end;
    }

    for (uint32_t i = const_literal_end; i < literal_end; i++)
    {
      jmem_cpointer_t bytecode_cpointer = literal_start_p[i];
      ecma_compiled_code_t *bytecode_literal_p = ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t,
                                                                            bytecode_cpointer);

      /* Self references are ignored. */
      if (bytecode_literal_p != bytecode_p)
      {
        ecma_bytecode_deref (bytecode_literal_p);
      }
    }

#ifdef JERRY_DEBUGGER
    if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
        && !(bytecode_p->status_flags & CBC_CODE_FLAGS_DEBUGGER_IGNORE)
        && jerry_debugger_send_function_cp (JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP, bytecode_p))
    {
      /* Delay the byte code free until the debugger client is notified.
       * If the connection is aborted the pointer is still freed by
       * jerry_debugger_close_connection(). */
      jerry_debugger_byte_code_free_t *byte_code_free_p = (jerry_debugger_byte_code_free_t *) bytecode_p;
      jmem_cpointer_t byte_code_free_head = JERRY_CONTEXT (debugger_byte_code_free_head);

      byte_code_free_p->prev_cp = ECMA_NULL_POINTER;

      jmem_cpointer_t byte_code_free_cp;
      JMEM_CP_SET_NON_NULL_POINTER (byte_code_free_cp, byte_code_free_p);

      if (byte_code_free_head == ECMA_NULL_POINTER)
      {
        JERRY_CONTEXT (debugger_byte_code_free_tail) = byte_code_free_cp;
      }
      else
      {
        jerry_debugger_byte_code_free_t *first_byte_code_free_p;

        first_byte_code_free_p = JMEM_CP_GET_NON_NULL_POINTER (jerry_debugger_byte_code_free_t,
                                                               byte_code_free_head);
        first_byte_code_free_p->prev_cp = byte_code_free_cp;
      }

      JERRY_CONTEXT (debugger_byte_code_free_head) = byte_code_free_cp;
      return;
    }
#endif /* JERRY_DEBUGGER */

#ifdef JMEM_STATS
    jmem_stats_free_byte_code_bytes (((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG);
#endif /* JMEM_STATS */
  }
  else
  {
#ifndef CONFIG_DISABLE_REGEXP_BUILTIN
    re_compiled_code_t *re_bytecode_p = (re_compiled_code_t *) bytecode_p;

    ecma_deref_ecma_string (ECMA_GET_NON_NULL_POINTER (ecma_string_t, re_bytecode_p->pattern_cp));
#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
  }

  jmem_heap_free_block (bytecode_p,
                        ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG);
} /* ecma_bytecode_deref */