parser_flush_cbc (parser_context_t *context_p) /**< context */
{
  uint8_t flags;
  uint16_t last_opcode = context_p->last_cbc_opcode;

  if (last_opcode == PARSER_CBC_UNAVAILABLE)
  {
    return;
  }

  context_p->status_flags |= PARSER_NO_END_LABEL;

  if (PARSER_IS_BASIC_OPCODE (last_opcode))
  {
    cbc_opcode_t opcode = (cbc_opcode_t) last_opcode;

    JERRY_ASSERT (opcode < CBC_END);
    flags = cbc_flags[opcode];

    PARSER_APPEND_TO_BYTE_CODE (context_p, opcode);
    context_p->byte_code_size++;
  }
  else
  {
    cbc_ext_opcode_t opcode = (cbc_ext_opcode_t) PARSER_GET_EXT_OPCODE (last_opcode);

    JERRY_ASSERT (opcode < CBC_EXT_END);
    flags = cbc_ext_flags[opcode];
    parser_emit_two_bytes (context_p, CBC_EXT_OPCODE, (uint8_t) opcode);
    context_p->byte_code_size += 2;
  }

  JERRY_ASSERT ((flags >> CBC_STACK_ADJUST_SHIFT) >= CBC_STACK_ADJUST_BASE
                 || (CBC_STACK_ADJUST_BASE - (flags >> CBC_STACK_ADJUST_SHIFT)) <= context_p->stack_depth);
  PARSER_PLUS_EQUAL_U16 (context_p->stack_depth, CBC_STACK_ADJUST_VALUE (flags));

  if (flags & (CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2))
  {
    uint16_t literal_index = context_p->last_cbc.literal_index;

    parser_emit_two_bytes (context_p,
                           (uint8_t) (literal_index & 0xff),
                           (uint8_t) (literal_index >> 8));
    context_p->byte_code_size += 2;
  }

  if (flags & CBC_HAS_LITERAL_ARG2)
  {
    uint16_t literal_index = context_p->last_cbc.value;

    parser_emit_two_bytes (context_p,
                           (uint8_t) (literal_index & 0xff),
                           (uint8_t) (literal_index >> 8));
    context_p->byte_code_size += 2;

    if (!(flags & CBC_HAS_LITERAL_ARG))
    {
      literal_index = context_p->last_cbc.third_literal_index;

      parser_emit_two_bytes (context_p,
                             (uint8_t) (literal_index & 0xff),
                             (uint8_t) (literal_index >> 8));
      context_p->byte_code_size += 2;
    }
  }

  if (flags & CBC_HAS_BYTE_ARG)
  {
    uint8_t byte_argument = (uint8_t) context_p->last_cbc.value;

    JERRY_ASSERT (context_p->last_cbc.value <= CBC_MAXIMUM_BYTE_VALUE);

    if (flags & CBC_POP_STACK_BYTE_ARG)
    {
      JERRY_ASSERT (context_p->stack_depth >= byte_argument);
      PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, byte_argument);
    }

    PARSER_APPEND_TO_BYTE_CODE (context_p, byte_argument);
    context_p->byte_code_size++;
  }

#if JERRY_PARSER_DUMP_BYTE_CODE
  if (context_p->is_show_opcodes)
  {
    JERRY_DEBUG_MSG ("  [%3d] %s",
                     (int) context_p->stack_depth,
                     PARSER_IS_BASIC_OPCODE (last_opcode) ? cbc_names[last_opcode]
                                                          : cbc_ext_names[PARSER_GET_EXT_OPCODE (last_opcode)]);

    if (flags & (CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2))
    {
      parser_print_literal (context_p, context_p->last_cbc.literal_index);
    }

    if (flags & CBC_HAS_LITERAL_ARG2)
    {
      parser_print_literal (context_p, context_p->last_cbc.value);

      if (!(flags & CBC_HAS_LITERAL_ARG))
      {
        parser_print_literal (context_p, context_p->last_cbc.third_literal_index);
      }
    }

    if (flags & CBC_HAS_BYTE_ARG)
    {
      if (last_opcode == CBC_PUSH_NUMBER_POS_BYTE
          || last_opcode == CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE)
      {
        JERRY_DEBUG_MSG (" number:%d", (int) context_p->last_cbc.value + 1);
      }
      else if (last_opcode == CBC_PUSH_NUMBER_NEG_BYTE
               || last_opcode == CBC_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE)
      {
        JERRY_DEBUG_MSG (" number:%d", -((int) context_p->last_cbc.value + 1));
      }
      else
      {
        JERRY_DEBUG_MSG (" byte_arg:%d", (int) context_p->last_cbc.value);
      }
    }

    JERRY_DEBUG_MSG ("\n");
  }
#endif /* JERRY_PARSER_DUMP_BYTE_CODE */

  if (context_p->stack_depth > context_p->stack_limit)
  {
    context_p->stack_limit = context_p->stack_depth;
    if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT)
    {
      parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED);
    }
  }

  context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
} /* parser_flush_cbc */
parser_flush_cbc (parser_context_t *context_p)  
{
  uint8_t flags;
  uint16_t last_opcode = context_p->last_cbc_opcode;

  if (last_opcode == PARSER_CBC_UNAVAILABLE)
  {
    return;
  }

  context_p->status_flags |= PARSER_NO_END_LABEL;

  if (PARSER_IS_BASIC_OPCODE (last_opcode))
  {
    cbc_opcode_t opcode = (cbc_opcode_t) last_opcode;

    JERRY_ASSERT (opcode < CBC_END);
    flags = cbc_flags[opcode];

    PARSER_APPEND_TO_BYTE_CODE (context_p, opcode);
    context_p->byte_code_size++;
  }
  else
  {
    cbc_ext_opcode_t opcode = (cbc_ext_opcode_t) PARSER_GET_EXT_OPCODE (last_opcode);

    JERRY_ASSERT (opcode < CBC_EXT_END);
    flags = cbc_ext_flags[opcode];
    parser_emit_two_bytes (context_p, CBC_EXT_OPCODE, (uint8_t) opcode);
    context_p->byte_code_size += 2;
  }

  JERRY_ASSERT ((flags >> CBC_STACK_ADJUST_SHIFT) >= CBC_STACK_ADJUST_BASE
                 || (CBC_STACK_ADJUST_BASE - (flags >> CBC_STACK_ADJUST_SHIFT)) <= context_p->stack_depth);
  PARSER_PLUS_EQUAL_U16 (context_p->stack_depth, CBC_STACK_ADJUST_VALUE (flags));

  if (flags & (CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2))
  {
    uint16_t literal_index = context_p->last_cbc.literal_index;

    parser_emit_two_bytes (context_p,
                           (uint8_t) (literal_index & 0xff),
                           (uint8_t) (literal_index >> 8));
    context_p->byte_code_size += 2;
  }

  if (flags & CBC_HAS_LITERAL_ARG2)
  {
    uint16_t literal_index = context_p->last_cbc.value;

    parser_emit_two_bytes (context_p,
                           (uint8_t) (literal_index & 0xff),
                           (uint8_t) (literal_index >> 8));
    context_p->byte_code_size += 2;

    if (!(flags & CBC_HAS_LITERAL_ARG))
    {
      literal_index = context_p->last_cbc.third_literal_index;

      parser_emit_two_bytes (context_p,
                             (uint8_t) (literal_index & 0xff),
                             (uint8_t) (literal_index >> 8));
      context_p->byte_code_size += 2;
    }
  }

  if (flags & CBC_HAS_BYTE_ARG)
  {
    uint8_t byte_argument = (uint8_t) context_p->last_cbc.value;

    JERRY_ASSERT (context_p->last_cbc.value <= CBC_MAXIMUM_BYTE_VALUE);

    if (flags & CBC_POP_STACK_BYTE_ARG)
    {
      JERRY_ASSERT (context_p->stack_depth >= byte_argument);
      PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, byte_argument);
    }

    PARSER_APPEND_TO_BYTE_CODE (context_p, byte_argument);
    context_p->byte_code_size++;
  }

#if JERRY_PARSER_DUMP_BYTE_CODE
  if (context_p->is_show_opcodes)
  {
    JERRY_DEBUG_MSG ("  [%3d] %s",
                     (int) context_p->stack_depth,
                     PARSER_IS_BASIC_OPCODE (last_opcode) ? cbc_names[last_opcode]
                                                          : cbc_ext_names[PARSER_GET_EXT_OPCODE (last_opcode)]);

    if (flags & (CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2))
    {
      parser_print_literal (context_p, context_p->last_cbc.literal_index);
    }

    if (flags & CBC_HAS_LITERAL_ARG2)
    {
      parser_print_literal (context_p, context_p->last_cbc.value);

      if (!(flags & CBC_HAS_LITERAL_ARG))
      {
        parser_print_literal (context_p, context_p->last_cbc.third_literal_index);
      }
    }

    if (flags & CBC_HAS_BYTE_ARG)
    {
      if (last_opcode == CBC_PUSH_NUMBER_POS_BYTE
          || last_opcode == CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE)
      {
        JERRY_DEBUG_MSG (" number:%d", (int) context_p->last_cbc.value + 1);
      }
      else if (last_opcode == CBC_PUSH_NUMBER_NEG_BYTE
               || last_opcode == CBC_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE)
      {
        JERRY_DEBUG_MSG (" number:%d", -((int) context_p->last_cbc.value + 1));
      }
      else
      {
        JERRY_DEBUG_MSG (" byte_arg:%d", (int) context_p->last_cbc.value);
      }
    }

    JERRY_DEBUG_MSG ("\n");
  }
#endif  

  if (context_p->stack_depth > context_p->stack_limit)
  {
    context_p->stack_limit = context_p->stack_depth;
    if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT)
    {
      parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED);
    }
  }

  context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
}  