⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hipe_bif0.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 3 页
字号:
	hipe_set_call_trap(pc, address, is_closure);	BIF_RET(am_true);#endif    }#ifdef DEBUG_LINKER    printf("%s: ", __FUNCTION__);    print_mfa(mfa.mod, mfa.fun, mfa.ari);    printf(": no BEAM pc found\r\n");#endif    BIF_RET(am_false);}#if 0 /* XXX: unused *//* * hipe_bifs_address_to_fun(Address) *    - Address is the address of the start of a emu function's code *    - returns {Module, Function, Arity} */BIF_RETTYPE hipe_bifs_address_to_fun_1(BIF_ALIST_1){    Eterm *pc;    Eterm *funcinfo;    Eterm *hp;    pc = term_to_address(BIF_ARG_1);    if( !pc )	BIF_ERROR(BIF_P, BADARG);    funcinfo = find_function_from_pc(pc);    if( !funcinfo )	BIF_RET(am_false);    hp = HAlloc(BIF_P, 4);    hp[0] = make_arityval(3);    hp[1] = funcinfo[0];    hp[2] = funcinfo[1];    hp[3] = make_small(funcinfo[2]);    BIF_RET(make_tuple(hp));}#endifBIF_RETTYPE hipe_bifs_enter_sdesc_1(BIF_ALIST_1){    struct sdesc *sdesc;    sdesc = hipe_decode_sdesc(BIF_ARG_1);    if( !sdesc ) {	fprintf(stderr, "%s: bad sdesc!\r\n", __FUNCTION__);	BIF_ERROR(BIF_P, BADARG);    }    if( hipe_put_sdesc(sdesc) != sdesc ) {	fprintf(stderr, "%s: duplicate entry!\r\n", __FUNCTION__);	BIF_ERROR(BIF_P, BADARG);    }    BIF_RET(NIL);}/* * Hash table mapping {M,F,A} to nbif address. */struct nbif {    HashBucket bucket;    Eterm mod;    Eterm fun;    unsigned arity;    const void *address;};static struct nbif nbifs[BIF_SIZE] = {#define BIF_LIST(MOD,FUN,ARY,CFUN,IX)	\	{ {0,0}, MOD, FUN, ARY, &nbif_##CFUN },#include "erl_bif_list.h"#undef BIF_LIST};#define NBIF_HASH(m,f,a)	((m)*(f)+(a))static Hash nbif_table;static HashValue nbif_hash(struct nbif *x){    return NBIF_HASH(x->mod, x->fun, x->arity);}static int nbif_cmp(struct nbif *x, struct nbif *y){    return !(x->mod == y->mod && x->fun == y->fun && x->arity == y->arity);}static struct nbif *nbif_alloc(struct nbif *x){    return x;	/* pre-allocated */}static void init_nbif_table(void){    HashFunctions f;    int i;    f.hash = (H_FUN) nbif_hash;    f.cmp = (HCMP_FUN) nbif_cmp;    f.alloc = (HALLOC_FUN) nbif_alloc;    f.free = NULL;    hash_init(ERTS_ALC_T_NBIF_TABLE, &nbif_table, "nbif_table", 500, f);    for(i = 0; i < BIF_SIZE; ++i)	hash_put(&nbif_table, &nbifs[i]);}static const void *nbif_address(Eterm mod, Eterm fun, unsigned arity){    struct nbif tmpl;    struct nbif *nbif;    tmpl.mod = mod;    tmpl.fun = fun;    tmpl.arity = arity;    nbif = hash_get(&nbif_table, &tmpl);    return nbif ? nbif->address : NULL;}/* * hipe_bifs_bif_address(M,F,A) -> address or false */BIF_RETTYPE hipe_bifs_bif_address_3(BIF_ALIST_3){    const void *address;    static int init_done = 0;    if( !init_done ) {	init_nbif_table();	init_done = 1;    }    if( is_not_atom(BIF_ARG_1) ||	is_not_atom(BIF_ARG_2) ||	is_not_small(BIF_ARG_3) ||	signed_val(BIF_ARG_3) < 0 )        BIF_RET(am_false);    address = nbif_address(BIF_ARG_1, BIF_ARG_2, unsigned_val(BIF_ARG_3));    if( address )	BIF_RET(address_to_term(address, BIF_P));    BIF_RET(am_false);}/* * Hash table mapping primops to their addresses. */struct primop {    HashBucket bucket;	/* bucket.hvalue == atom_val(name) */    const void *address;#if defined(__arm__)    void *trampoline;#endif};static struct primop primops[] = {#define PRIMOP_LIST(ATOM,ADDRESS)	{ {0,_unchecked_atom_val(ATOM)}, ADDRESS },#include "hipe_primops.h"#undef PRIMOP_LIST};static Hash primop_table;static HashValue primop_hash(void *tmpl){    return ((struct primop*)tmpl)->bucket.hvalue;	/* pre-initialised */}static int primop_cmp(void *tmpl, void *bucket){    return 0;	/* hvalue matched so nothing further to do */}static void *primop_alloc(void *tmpl){    return tmpl;	/* pre-allocated */}static void init_primop_table(void){    HashFunctions f;    int i;    static int init_done = 0;    if (init_done)	return;    init_done = 1;    f.hash = (H_FUN) primop_hash;    f.cmp = (HCMP_FUN) primop_cmp;    f.alloc = (HALLOC_FUN) primop_alloc;    f.free = NULL;    hash_init(ERTS_ALC_T_HIPE, &primop_table, "primop_table", 50, f);    for(i = 0; i < sizeof(primops)/sizeof(primops[0]); ++i)	hash_put(&primop_table, &primops[i]);}static struct primop *primop_table_get(Eterm name){    struct primop tmpl;    init_primop_table();    tmpl.bucket.hvalue = atom_val(name);    return hash_get(&primop_table, &tmpl);}#if defined(__arm__)static struct primop *primop_table_put(Eterm name){    struct primop tmpl;    init_primop_table();    tmpl.bucket.hvalue = atom_val(name);    return hash_put(&primop_table, &tmpl);}void *hipe_primop_get_trampoline(Eterm name){    struct primop *primop = primop_table_get(name);    return primop ? primop->trampoline : NULL;}void hipe_primop_set_trampoline(Eterm name, void *trampoline){    struct primop *primop = primop_table_put(name);    primop->trampoline = trampoline;}#endif/* * hipe_bifs_primop_address(Atom) -> address or false */BIF_RETTYPE hipe_bifs_primop_address_1(BIF_ALIST_1){    const struct primop *primop;    if (is_not_atom(BIF_ARG_1))	BIF_RET(am_false);    primop = primop_table_get(BIF_ARG_1);    if (!primop)	BIF_RET(am_false);    BIF_RET(address_to_term(primop->address, BIF_P));}#if 0 /* XXX: unused *//* * hipe_bifs_gbif_address(F,A) -> address or false */#define GBIF_LIST(ATOM,ARY,CFUN) extern Eterm gbif_##CFUN(void);#include "hipe_gbif_list.h"#undef GBIF_LISTBIF_RETTYPE hipe_bifs_gbif_address_2(BIF_ALIST_2){    Uint arity;    void *address;    if( is_not_atom(BIF_ARG_1) || is_not_small(BIF_ARG_2) )	BIF_RET(am_false);	/* error or false, does it matter? */    arity = signed_val(BIF_ARG_2);    /* XXX: replace with a hash table later */    do { /* trick to let us use 'break' instead of 'goto' */#define GBIF_LIST(ATOM,ARY,CFUN) if(BIF_ARG_1 == ATOM && arity == ARY) { address = CFUN; break; }#include "hipe_gbif_list.h"#undef GBIF_LIST	printf("\r\n%s: guard BIF ", __FUNCTION__);	fflush(stdout);	erts_printf("%T", BIF_ARG_1);	printf("/%lu isn't listed in hipe_gbif_list.h\r\n", arity);	BIF_RET(am_false);    } while(0);    BIF_RET(address_to_term(address, BIF_P));}#endifBIF_RETTYPE hipe_bifs_atom_to_word_1(BIF_ALIST_1){    if( is_not_atom(BIF_ARG_1) )	BIF_ERROR(BIF_P, BADARG);    BIF_RET(Uint_to_term(BIF_ARG_1, BIF_P));}BIF_RETTYPE hipe_bifs_term_to_word_1(BIF_ALIST_1){    BIF_RET(Uint_to_term(BIF_ARG_1, BIF_P));}/* XXX: this is really a primop, not a BIF */BIF_RETTYPE hipe_conv_big_to_float(BIF_ALIST_1){    Eterm res;    Eterm* hp;    FloatDef f;    if( is_not_big(BIF_ARG_1) ) {	BIF_ERROR(BIF_P, BADARG);    }    if( big_to_double(BIF_ARG_1, &f.fd) < 0 ) {	BIF_ERROR(BIF_P, BADARG);    }    hp = HAlloc(BIF_P, FLOAT_SIZE_OBJECT);    res = make_float(hp);    PUT_DOUBLE(f, hp);    BIF_RET(res);}#if 0 /* XXX: unused *//*  At least parts of this should be inlined in native code.  The rest could be made a primop used by both the emulator and  native code...*/BIF_RETTYPE hipe_bifs_make_fun_3(BIF_ALIST_3){  Eterm free_vars;  Eterm mod;  Eterm *tp;  Uint index;  Uint uniq;  Uint num_free;  Eterm tmp_var;  Uint *tmp_ptr;  unsigned needed;  ErlFunThing *funp;  Eterm *hp;  int i;  if (is_not_list(BIF_ARG_1) && is_not_nil(BIF_ARG_1)) {    printf("Not a list\n");    BIF_ERROR(BIF_P, BADARG);  }  free_vars = BIF_ARG_1;  if (is_not_atom(BIF_ARG_2)) {    printf("Not an atom\n");    BIF_ERROR(BIF_P, BADARG);  }  mod = BIF_ARG_2;  if (is_not_tuple(BIF_ARG_3) ||      (arityval(*tuple_val(BIF_ARG_3)) != 3 )) {    printf("Not an good tuple\n");    BIF_ERROR(BIF_P, BADARG);  }  tp = tuple_val(BIF_ARG_3);  if(term_to_Uint(tp[1], &index) == 0) {    printf("Bad index\n");    BIF_ERROR(BIF_P, BADARG);  }  if(term_to_Uint(tp[2], &uniq) == 0){    printf("Bad unique\n");    BIF_ERROR(BIF_P, BADARG);  }  if(term_to_Uint(tp[3], &num_free) == 0){    printf("Bad num_free\n");    BIF_ERROR(BIF_P, BADARG);  }  needed = ERL_FUN_SIZE + num_free;  funp = (ErlFunThing *) HAlloc(BIF_P, needed);  hp = funp->env;  funp->thing_word = HEADER_FUN;  /* Need a ErlFunEntry* fe     fe->refc++;     funp->fe = fe; */  funp->num_free = num_free;  funp->creator = BIF_P->id;  for (i = 0; i < num_free; i++) {    if (is_nil(free_vars)) {      printf("to few free vars\n");      BIF_ERROR(BIF_P, BADARG);    }    tmp_ptr = list_val(free_vars);    tmp_var = CAR(tmp_ptr);    free_vars = CDR(tmp_ptr);    *hp++ = tmp_var;  }  if (is_not_nil(free_vars))  {    printf("to many free vars\n");    BIF_ERROR(BIF_P, BADARG);  }#ifndef HYBRID /* FIND ME! */  funp->next = MSO(BIF_P).funs;  MSO(BIF_P).funs = funp;#endif  BIF_RET(make_fun(funp));}#endifBIF_RETTYPE hipe_bifs_make_fe_3(BIF_ALIST_3){  /*     args: Nativecodeaddress, Module, {Uniq, Index, BeamAddress}   */  Eterm mod;  Uint index;  Uint uniq;  void *beam_address;  ErlFunEntry* fe;  Eterm *tp;  void *native_address;  native_address = term_to_address(BIF_ARG_1);  if( !native_address )    BIF_ERROR(BIF_P, BADARG);  if (is_not_atom(BIF_ARG_2)) {    BIF_ERROR(BIF_P, BADARG);  }  mod = BIF_ARG_2;  if (is_not_tuple(BIF_ARG_3) ||      (arityval(*tuple_val(BIF_ARG_3)) != 3 )) {    BIF_ERROR(BIF_P, BADARG);  }  tp = tuple_val(BIF_ARG_3);  if(term_to_Uint(tp[1], &uniq) == 0){    printf("Bad unique\n");    BIF_ERROR(BIF_P, BADARG);  }  if(term_to_Uint(tp[2], &index) == 0) {    printf("Bad index\n");    BIF_ERROR(BIF_P, BADARG);  }  beam_address = term_to_address(tp[3]);  if( !beam_address )    BIF_ERROR(BIF_P, BADARG);  fe = erts_get_fun_entry(mod, uniq, index);  if (fe == NULL) {    int i = atom_val(mod);    char atom_buf[256];    atom_buf[0] = '\0';    strncat(atom_buf, (char*)atom_tab(i)->name, atom_tab(i)->len);    printf("no fun entry for %s %ld:%ld\n", atom_buf, uniq, index);    BIF_ERROR(BIF_P, BADARG);  }  fe->native_address = native_address;  if (erts_refc_dectest(&fe->refc, 0) == 0)      erts_erase_fun_entry(fe);  BIF_RET(address_to_term((void *)fe, BIF_P));}#if 0 /* XXX: unused */BIF_RETTYPE hipe_bifs_make_native_stub_2(BIF_ALIST_2){    void *beamAddress;    Uint beamArity;    void *stubAddress;    if( (beamAddress = term_to_address(BIF_ARG_1)) == 0 ||	is_not_small(BIF_ARG_2) ||	(beamArity = unsigned_val(BIF_ARG_2)) >= 256 )	BIF_ERROR(BIF_P, BADARG);    stubAddress = hipe_make_native_stub(beamAddress, beamArity);    BIF_RET(address_to_term(stubAddress, BIF_P));}#endif/* * MFA info hash table: * - maps MFA to native code entry point * - the MFAs it calls (refers_to) * - the references to it (referred_from) * - maps MFA to most recent trampoline [if powerpc or arm] */struct hipe_mfa_info {    struct {	unsigned long hvalue;	struct hipe_mfa_info *next;    } bucket;    Eterm m;	/* atom */    Eterm f;	/* atom */    unsigned int a;    void *remote_address;    void *local_address;    Eterm *beam_code;    Uint orig_beam_op;    struct hipe_mfa_info_list *refers_to;    struct ref *referred_from;#if defined(__powerpc__) || defined(__ppc__) || defined(__powerpc64__) || defined(__arm__)    void *trampoline;#endif};static struct {    unsigned int log2size;    unsigned int mask;		/* INV: mask == (1 << log2size)-1 */    unsigned int used;    struct hipe_mfa_info **bucket;} hipe_mfa_info_table;#define HIPE_MFA_HASH(M,F,A)	((M) * (F) + (A))static struct hipe_mfa_info **hipe_mfa_info_table_alloc_bucket(unsigned int size){    unsigned long nbytes = size * sizeof(struct hipe_mfa_info*);    struct hipe_mfa_info **bucket = erts_alloc(ERTS_ALC_T_HIPE, nbytes);    sys_memzero(bucket, nbytes);    return bucket;}static void hipe_mfa_info_table_grow(void){    unsigned int old_size, new_size, new_mask;    struct hipe_mfa_info **old_bucket, **new_bucket;    unsigned int i;    old_size = 1 << hipe_mfa_info_table.log2size;    hipe_mfa_info_table.log2size += 1;    new_size = 1 << hipe_mfa_info_table.log2size;    new_mask = new_size - 1;    hipe_mfa_info_table.mask = new_mask;    old_bucket = hipe_mfa_info_table.bucket;    new_bucket = hipe_mfa_info_table_alloc_bucket(new_size);    hipe_mfa_info_table.bucket = new_bucket;    for(i = 0; i < old_size; ++i) {	struct hipe_mfa_info *b = old_bucket[i];	while( b != NULL ) {	    struct hipe_mfa_info *next = b->bucket.next;	    unsigned int j = b->bucket.hvalue & new_mask;	    b->bucket.next = new_bucket[j];	    new_bucket[j] = b;	    b = next;	}    }    erts_free(ERTS_ALC_T_HIPE, old_bucket);}static struct hipe_mfa_info *hipe_mfa_info_table_alloc(Eterm m, Eterm f, unsigned int arity){    struct hipe_mfa_info *res;    res = (struct hipe_mfa_info*)erts_alloc(ERTS_ALC_T_HIPE, sizeof(*res));    res->m = m;    res->f = f;    res->a = arity;    res->remote_address = NULL;    res->local_address = NULL;    res->beam_code = NULL;    res->orig_beam_op = 0;    res->refers_to = NULL;    res->referred_from = NULL;#if defined(__powerpc__) || defined(__ppc__) || defined(__powerpc64__) || defined(__arm__)    res->trampoline = NULL;#endif    return res;}void hipe_mfa_info_table_init(void){    unsigned int log2size, size;    log2size = 10;    size = 1 << log2size;    hipe_mfa_info_table.log2size = log2size;    hipe_mfa_info_table.mask = size - 1;    hipe_mfa_info_table.used = 0;    hipe_mfa_info_table.bucket = hipe_mfa_info_table_alloc_bucket(size);}static inline struct hipe_mfa_info *hipe_mfa_info_table_get(Eterm m, Eterm f, unsigned int arity){    unsigned long h;    unsigned int i;    struct hipe_mfa_info *p;    h = HIPE_MFA_HASH(m, f, arity);    i = h & hipe_mfa_info_table.mask;    p = hipe_mfa_info_table.bucket[i];    for(; p; p = p->bucket.next)	/* XXX: do we want to compare p->bucket.hvalue as well? */	if (p->m == m && p->f == f && p->a == arity)	    return p;    return NULL;}#if 0 /* XXX: unused */void *hipe_mfa_find_na(Eterm m, Eterm f, unsigned int arity){    const struct hipe_mfa_info *p;    p = hipe_mfa_info_table_get(m, f, arity);    return p ? p->address : NULL;}#endifstatic struct hipe_mfa_info *hipe_mfa_info_table_put(Eterm m, Eterm f, unsigned int arity){    unsigned long h;    unsigned int i;    struct hipe_mfa_info *p;    unsigned int size;    h = HIPE_MFA_HASH(m, f, arity);    i = h & hipe_mfa_info_table.mask;    p = hipe_mfa_info_table.bucket[i];    for(; p; p = p->bucket.next)	/* XXX: do we want to compare p->bucket.hvalue as well? */	if( p->m == m && p->f == f && p->a == arity )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -