Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

530 lines (476 sloc) 18.176 kb
/*
* Copyright (C) 2002-2009, Parrot Foundation.
*/
#ifndef PARROT_IMCC_SYMREG_H_GUARD
#define PARROT_IMCC_SYMREG_H_GUARD
/* types */
#define VARTYPE_BIT(n) ((UINTVAL)1 << (n))
enum VARTYPE { /* variable type can be */
VTCONST = VARTYPE_BIT(0), /* constant */
VTREG = VARTYPE_BIT(1), /* register */
VTIDENTIFIER = VARTYPE_BIT(2), /* identifier */
VTADDRESS = VARTYPE_BIT(3), /* address */
VTREGKEY = VARTYPE_BIT(4), /* parrot [key;key..]), including registers */
VTPASM = VARTYPE_BIT(5), /* parrot register), colored from .emit */
VT_CONSTP = VARTYPE_BIT(6), /* pointer to constant value */
VT_PCC_SUB = VARTYPE_BIT(7), /* PCC subroutine call */
VT_FLAT = VARTYPE_BIT(8), /* var :flat */
VT_OPTIONAL = VARTYPE_BIT(9), /* var :optional */
/* include/parrot/packfile.h */
VT_ENCODED = VARTYPE_BIT(16), /* unicode string constant */
VT_OPT_FLAG = VARTYPE_BIT(17), /* var :opt_flag */
VT_NAMED = VARTYPE_BIT(18), /* var :named(name) */
VT_CALL_SIG = VARTYPE_BIT(19)
};
#undef VARTYPE_BIT
/* this VARTYPE needs register allocation and such */
#define VTREGISTER (VTREG | VTIDENTIFIER | VTREGKEY | VTPASM)
#define REG_NEEDS_ALLOC(r) ((r)->type & VTREGISTER)
enum USAGE {
U_KEYED = 1 << 0, /* array, hash, keyed */
U_NEW = 1 << 1, /* PMC was inited */
U_GLOBAL = 1 << 3, /* symbol is global (fixup) */
U_LEXICAL = 1 << 4, /* symbol is lexical */
U_FIXUP = 1 << 5, /* maybe not global, force fixup */
U_SUBID_LOOKUP = 1 << 6, /* .const 'Sub' lookup is done by subid */
U_LEXINFO_LOOKUP = 1 << 7 /* .const 'LexInfo' lookup is done by subid */
};
typedef struct _SymReg {
char *name;
struct _SymReg *subid;
struct _SymReg *nextkey; /* keys */
struct _SymReg *reg; /* key->register for VTREGKEYs */
struct pcc_sub_t *pcc_sub; /* PCC subroutine */
struct _SymReg *used; /* used register in invoke */
struct _SymReg *next; /* used in the symbols hash */
struct _Instruction *first_ins; /* first and last instruction */
struct _Instruction *last_ins; /* this symbol is in */
INTVAL type; /* Variable type */
INTVAL usage; /* s. USAGE above */
int set; /* parent register set/file */
int want_regno; /* wanted register number */
INTVAL color; /* Color: parrot register number
* and const table index of VTCONST */
int offset; /* used for label fixup */
int use_count; /* How often this symbol is used */
int lhs_use_count; /* Frequency of writing to this symbol*/
int pmc_type; /* class enum */
} SymReg;
typedef struct _SymHash {
SymReg **data;
unsigned int size;
unsigned int entries;
} SymHash;
/* namespaces */
typedef struct ident_t Identifier;
struct ident_t {
char *name;
Identifier *next;
};
typedef struct namespace_t Namespace;
struct namespace_t {
Namespace *parent;
char *name;
Identifier *idents;
};
typedef enum {
P_NONE = 0x00, /* 0<<0 */
P_NEED_LEX = 0x01, /* 1<<0 */
P_VTABLE = SUB_COMP_FLAG_VTABLE, /* 1<<1 0x2 */
P_METHOD = SUB_COMP_FLAG_METHOD, /* 1<<2 0x4 */
P_ANON = SUB_FLAG_PF_ANON, /* 1<<3 0x8 - private3 */
P_MAIN = SUB_FLAG_PF_MAIN, /* 1<<4 0x10 - private4 */
P_LOAD = SUB_FLAG_PF_LOAD, /* 1<<5 0x20 - private5 */
P_IMMEDIATE = SUB_FLAG_PF_IMMEDIATE, /* 1<<6 0x40 - private6 */
P_POSTCOMP = SUB_FLAG_PF_POSTCOMP, /* 1<<7 0x80 - private7 */
P_INIT = SUB_COMP_FLAG_PF_INIT, /* 1<<10 0x400 - 10 */
P_NSENTRY = SUB_COMP_FLAG_NSENTRY /* 1<<11 0x800 - 11 */
} pragma_enum_t;
typedef struct pcc_sub_t {
SymReg *sub;
SymReg *cc;
SymReg **args;
SymReg **multi;
SymReg **ret;
SymReg *object;
SymReg **flags; /* "load", "init", etc */
int *arg_flags; /* :slurpy, :optional, ... */
int *ret_flags; /* :slurpy, :optional, ... */
int nargs;
int nret;
int nmulti;
int nflags;
int yield;
int tailcall;
int label;
INTVAL pragma;
} pcc_sub_t;
enum uniq_t {
U_add_once,
U_add_uniq_label,
U_add_uniq_sub,
U_add_all
};
/* functions */
/* HEADERIZER BEGIN: compilers/imcc/symreg.c */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
PARROT_CAN_RETURN_NULL
PARROT_WARN_UNUSED_RESULT
SymReg * _find_sym(
ARGMOD(imc_info_t * imcc),
ARGIN_NULLOK(const Namespace *nspace),
ARGIN(const SymHash *hsh),
ARGIN(const char *name))
__attribute__nonnull__(1)
__attribute__nonnull__(3)
__attribute__nonnull__(4)
FUNC_MODIFIES(* imcc);
PARROT_CAN_RETURN_NULL
PARROT_WARN_UNUSED_RESULT
SymReg * _get_sym(ARGIN(const SymHash *hsh), ARGIN(const char *name))
__attribute__nonnull__(1)
__attribute__nonnull__(2);
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
SymReg * _mk_address(
ARGMOD(imc_info_t * imcc),
ARGMOD(SymHash *hsh),
ARGIN(const char *name),
int uniq)
__attribute__nonnull__(1)
__attribute__nonnull__(2)
__attribute__nonnull__(3)
FUNC_MODIFIES(* imcc)
FUNC_MODIFIES(*hsh);
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
SymReg * _mk_const(
ARGMOD(imc_info_t * imcc),
ARGMOD(SymHash *hsh),
ARGIN(const char *name),
int t)
__attribute__nonnull__(1)
__attribute__nonnull__(2)
__attribute__nonnull__(3)
FUNC_MODIFIES(* imcc)
FUNC_MODIFIES(*hsh);
void _store_symreg(
ARGMOD(imc_info_t * imcc),
ARGMOD(SymHash *hsh),
ARGMOD(SymReg *r))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
__attribute__nonnull__(3)
FUNC_MODIFIES(* imcc)
FUNC_MODIFIES(*hsh)
FUNC_MODIFIES(*r);
void add_namespace(ARGMOD(imc_info_t * imcc), ARGMOD(IMC_Unit *unit))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc)
FUNC_MODIFIES(*unit);
void add_pcc_arg(
ARGMOD(imc_info_t * imcc),
ARGMOD(SymReg *r),
ARGMOD(SymReg *arg))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
__attribute__nonnull__(3)
FUNC_MODIFIES(* imcc)
FUNC_MODIFIES(*r)
FUNC_MODIFIES(*arg);
void add_pcc_cc(ARGMOD(SymReg *r), ARGIN(SymReg *arg))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(*r);
void add_pcc_flag_str(
ARGMOD(imc_info_t * imcc),
ARGMOD(SymReg * r),
ARGIN(SymReg * arg))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
__attribute__nonnull__(3)
FUNC_MODIFIES(* imcc)
FUNC_MODIFIES(* r);
void add_pcc_multi(
ARGMOD(imc_info_t * imcc),
ARGMOD(SymReg *r),
ARGIN_NULLOK(SymReg *arg))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc)
FUNC_MODIFIES(*r);
void add_pcc_result(
ARGMOD(imc_info_t * imcc),
ARGMOD(SymReg *r),
ARGMOD(SymReg *arg))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
__attribute__nonnull__(3)
FUNC_MODIFIES(* imcc)
FUNC_MODIFIES(*r)
FUNC_MODIFIES(*arg);
void add_pcc_sub(ARGMOD(SymReg *r), ARGIN(SymReg *arg))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(*r);
void clear_globals(ARGMOD(imc_info_t * imcc))
__attribute__nonnull__(1)
FUNC_MODIFIES(* imcc);
void clear_locals(ARGIN_NULLOK(IMC_Unit *unit));
void clear_sym_hash(ARGMOD(SymHash *hsh))
__attribute__nonnull__(1)
FUNC_MODIFIES(*hsh);
void create_symhash(ARGMOD(imc_info_t * imcc), ARGOUT(SymHash *hash))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc)
FUNC_MODIFIES(*hash);
PARROT_MALLOC
PARROT_CANNOT_RETURN_NULL
SymReg * dup_sym(ARGMOD(imc_info_t * imcc), ARGIN(const SymReg *r))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc);
PARROT_CAN_RETURN_NULL
PARROT_WARN_UNUSED_RESULT
SymReg * find_sym(ARGMOD(imc_info_t * imcc), ARGIN(const char *name))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc);
void free_pcc_sub(ARGMOD(pcc_sub_t *sub))
__attribute__nonnull__(1)
FUNC_MODIFIES(*sub);
void free_sym(ARGMOD(SymReg *r))
__attribute__nonnull__(1)
FUNC_MODIFIES(*r);
PARROT_CAN_RETURN_NULL
PARROT_WARN_UNUSED_RESULT
SymReg * get_sym(ARGMOD(imc_info_t * imcc), ARGIN(const char *name))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc);
PARROT_PURE_FUNCTION
unsigned int hash_str(ARGIN(const char *str))
__attribute__nonnull__(1);
PARROT_MALLOC
PARROT_CANNOT_RETURN_NULL
SymReg * link_keys(
ARGMOD(imc_info_t * imcc),
int nargs,
ARGMOD(SymReg **keys),
int force)
__attribute__nonnull__(1)
__attribute__nonnull__(3)
FUNC_MODIFIES(* imcc)
FUNC_MODIFIES(*keys);
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
SymReg * mk_const(ARGMOD(imc_info_t * imcc), ARGIN(const char *name), int t)
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc);
PARROT_CANNOT_RETURN_NULL
PARROT_IGNORABLE_RESULT
SymReg * mk_const_ident(
ARGMOD(imc_info_t * imcc),
ARGIN(const char *name),
int t,
ARGMOD(SymReg *val),
int global)
__attribute__nonnull__(1)
__attribute__nonnull__(2)
__attribute__nonnull__(4)
FUNC_MODIFIES(* imcc)
FUNC_MODIFIES(*val);
PARROT_CANNOT_RETURN_NULL
PARROT_IGNORABLE_RESULT
SymReg * mk_ident(
ARGMOD(imc_info_t * imcc),
ARGIN(const char *name),
int t,
INTVAL type)
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc);
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
SymReg * mk_label_address(
ARGMOD(imc_info_t * imcc),
ARGIN(const char *name))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc);
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
SymReg * mk_local_label(ARGMOD(imc_info_t * imcc), ARGIN(const char *name))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc);
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
SymReg * mk_pasm_reg(ARGMOD(imc_info_t * imcc), ARGIN(const char *name))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc);
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
SymReg * mk_pcc_sub(
ARGMOD(imc_info_t * imcc),
ARGIN(const char *name),
int proto)
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc);
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
SymReg * mk_sub_address(ARGMOD(imc_info_t * imcc), ARGIN(const char *name))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc);
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
SymReg * mk_sub_label(ARGMOD(imc_info_t * imcc), ARGIN(const char *name))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc);
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
SymReg * mk_symreg(
ARGMOD(imc_info_t * imcc),
ARGIN(const char *name),
int t)
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc);
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
SymReg * mk_temp_reg(ARGMOD(imc_info_t * imcc), int t)
__attribute__nonnull__(1)
FUNC_MODIFIES(* imcc);
void store_symreg(ARGMOD(imc_info_t * imcc), ARGMOD(SymReg *r))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
FUNC_MODIFIES(* imcc)
FUNC_MODIFIES(*r);
PARROT_MALLOC
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
char * symreg_to_str(ARGIN(const SymReg *s))
__attribute__nonnull__(1);
#define ASSERT_ARGS__find_sym __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(hsh) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS__get_sym __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(hsh) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS__mk_address __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(hsh) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS__mk_const __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(hsh) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS__store_symreg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(hsh) \
, PARROT_ASSERT_ARG(r))
#define ASSERT_ARGS_add_namespace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(unit))
#define ASSERT_ARGS_add_pcc_arg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(r) \
, PARROT_ASSERT_ARG(arg))
#define ASSERT_ARGS_add_pcc_cc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(r) \
, PARROT_ASSERT_ARG(arg))
#define ASSERT_ARGS_add_pcc_flag_str __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(r) \
, PARROT_ASSERT_ARG(arg))
#define ASSERT_ARGS_add_pcc_multi __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(r))
#define ASSERT_ARGS_add_pcc_result __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(r) \
, PARROT_ASSERT_ARG(arg))
#define ASSERT_ARGS_add_pcc_sub __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(r) \
, PARROT_ASSERT_ARG(arg))
#define ASSERT_ARGS_clear_globals __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc))
#define ASSERT_ARGS_clear_locals __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
#define ASSERT_ARGS_clear_sym_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(hsh))
#define ASSERT_ARGS_create_symhash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(hash))
#define ASSERT_ARGS_dup_sym __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(r))
#define ASSERT_ARGS_find_sym __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS_free_pcc_sub __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(sub))
#define ASSERT_ARGS_free_sym __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(r))
#define ASSERT_ARGS_get_sym __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS_hash_str __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(str))
#define ASSERT_ARGS_link_keys __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(keys))
#define ASSERT_ARGS_mk_const __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS_mk_const_ident __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(name) \
, PARROT_ASSERT_ARG(val))
#define ASSERT_ARGS_mk_ident __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS_mk_label_address __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS_mk_local_label __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS_mk_pasm_reg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS_mk_pcc_sub __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS_mk_sub_address __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS_mk_sub_label __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS_mk_symreg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(name))
#define ASSERT_ARGS_mk_temp_reg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc))
#define ASSERT_ARGS_store_symreg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(imcc) \
, PARROT_ASSERT_ARG(r))
#define ASSERT_ARGS_symreg_to_str __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(s))
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: compilers/imcc/symreg.c */
#endif /* PARROT_IMCC_SYMREG_H_GUARD */
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/
Jump to Line
Something went wrong with that request. Please try again.