92 lines
3.5 KiB
C

/* Copyright 2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef JSP_LABEL_H
#define JSP_LABEL_H
#include "lexer.h"
#include "opcodes.h"
/** \addtogroup jsparser ECMAScript parser
* @{
*
* \addtogroup labels Jump labels
* @{
*/
/**
* Label types
*/
typedef enum
{
JSP_LABEL_TYPE_NAMED = (1 << 0), /**< label for breaks and continues with identifiers */
JSP_LABEL_TYPE_UNNAMED_BREAKS = (1 << 1), /**< label for breaks without identifiers */
JSP_LABEL_TYPE_UNNAMED_CONTINUES = (1 << 2) /**< label for continues without identifiers */
} jsp_label_type_flag_t;
/**
* Descriptor of a jump label (See also: ECMA-262 v5, 12.12, Labelled statements)
*
* Note:
* Jump instructions with target identified by some specific label,
* are linked into singly-linked list.
*
* Pointer to a next element of the list is represented with opcode counter.
* stored in instructions linked into the list.
*
*/
typedef struct jsp_label_t
{
jsp_label_type_flag_t type_mask; /**< label type mask */
token id; /**< label name (TOK_NAME), if type is LABEL_NAMED */
opcode_counter_t continue_tgt_oc; /**< target opcode counter for continues on the label */
opcode_counter_t breaks_list_oc; /**< opcode counter of first 'break' instruction in the list
* of instructions with the target identified by the label */
opcode_counter_t breaks_number; /**< number of 'break' instructions in the list */
opcode_counter_t continues_list_oc; /**< opcode counter of first 'continue' instruction in the list
* of instructions with the target identified by the label */
opcode_counter_t continues_number; /**< number of 'continue' instructions in the list */
jsp_label_t *next_label_p; /**< next label in current label set stack */
bool is_nested_jumpable_border : 1; /**< flag, indicating that this and outer labels
* are not currently accessible with simple jumps,
* and so should be targetted with nested jumps only */
} jsp_label_t;
extern void jsp_label_init (void);
extern void jsp_label_finalize (void);
extern void jsp_label_remove_all_labels (void);
extern void jsp_label_push (jsp_label_t *out_label_p, jsp_label_type_flag_t type_mask, token id);
extern void jsp_label_rewrite_jumps_and_pop (jsp_label_t *label_p, opcode_counter_t break_tgt_oc);
extern jsp_label_t *jsp_label_find (jsp_label_type_flag_t type_mask, token id, bool *out_is_simply_jumpable_p);
extern void jsp_label_add_jump (jsp_label_t *label_p, bool is_simply_jumpable, bool is_break);
extern void jsp_label_setup_continue_target (jsp_label_t *outermost_label_p, opcode_counter_t tgt_oc);
extern void jsp_label_raise_nested_jumpable_border (void);
extern void jsp_label_remove_nested_jumpable_border (void);
extern jsp_label_t *jsp_label_mask_set (void);
extern void jsp_label_restore_set (jsp_label_t *masked_label_set_list_p);
/**
* @}
* @}
*/
#endif /* !JSP_LABEL_H */