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

📄 erl_db_util.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 5 页
字号:
    },    {	am_is_function,	&is_function_1,	1,	DBIF_ALL    },    {	am_is_record,	&is_record_3,	3,	DBIF_ALL    },    {	am_abs,	&abs_1,	1,	DBIF_ALL    },    {	am_element,	&element_2,	2,	DBIF_ALL    },    {	am_hd,	&hd_1,	1,	DBIF_ALL    },    {	am_length,	&length_1,	1,	DBIF_ALL    },    {	am_node,	&node_1,	1,	DBIF_ALL    },    {	am_node,	&node_0,	0,	DBIF_ALL    },    {	am_round,	&round_1,	1,	DBIF_ALL    },    {	am_size,	&size_1,	1,	DBIF_ALL    },    {	am_bitsize,	&bitsize_1,	1,	DBIF_ALL    },    {	am_tl,	&tl_1,	1,	DBIF_ALL    },    {	am_trunc,	&trunc_1,	1,	DBIF_ALL    },    {	am_float,	&float_1,	1,	DBIF_ALL    },    {	am_Plus,	&splus_1,	1,	DBIF_ALL    },    {	am_Minus,	&sminus_1,	1,	DBIF_ALL    },    {	am_Plus,	&splus_2,	2,	DBIF_ALL    },    {	am_Minus,	&sminus_2,	2,	DBIF_ALL    },    {	am_Times,	&stimes_2,	2,	DBIF_ALL    },    {	am_Div,	&div_2,	2,	DBIF_ALL    },    {	am_div,	&intdiv_2,	2,	DBIF_ALL    },    {	am_rem,	&rem_2,	2,	DBIF_ALL    },    {	am_band,	&band_2,	2,	DBIF_ALL    },    {	am_bor,	&bor_2,	2,	DBIF_ALL    },    {	am_bxor,	&bxor_2,	2,	DBIF_ALL    },    {	am_bnot,	&bnot_1,	1,	DBIF_ALL    },    {	am_bsl,	&bsl_2,	2,	DBIF_ALL    },    {	am_bsr,	&bsr_2,	2,	DBIF_ALL    },    {	am_Gt,	&sgt_2,	2,	DBIF_ALL    },    {	am_Ge,	&sge_2,	2,	DBIF_ALL    },    {	am_Lt,	&slt_2,	2,	DBIF_ALL    },    {	am_Le,	&sle_2,	2,	DBIF_ALL    },    {	am_Eq,	&seq_2,	2,	DBIF_ALL    },    {	am_Eqeq,	&seqeq_2,	2,	DBIF_ALL    },    {	am_Neq,	&sneq_2,	2,	DBIF_ALL    },    {	am_Neqeq,	&sneqeq_2,	2,	DBIF_ALL    },    {	am_not,	&not_1,	1,	DBIF_ALL    },    {	am_xor,	&xor_2,	2,	DBIF_ALL    },    {	am_get_tcw,	&db_get_trace_control_word_0,	0,	DBIF_TRACE_GUARD | DBIF_TRACE_BODY    },    {	am_set_tcw,	&db_set_trace_control_word_1,	1,	DBIF_TRACE_BODY    },    {	am_set_tcw_fake,	&db_set_trace_control_word_fake_1,	1,	DBIF_TRACE_BODY    }};/*** Exported*/Eterm db_am_eot;                /* Atom '$end_of_table' *//*** Forward decl's*//*** ... forwards for compiled matches*//* Utility code */static DMCGuardBif *dmc_lookup_bif(Eterm t, int arity);#ifdef DMC_DEBUGstatic Eterm dmc_lookup_bif_reversed(void *f);#endifstatic int cmp_uint(void *a, void *b);static int cmp_guard_bif(void *a, void *b);static int match_compact(ErlHeapFragment *expr, DMCErrInfo *err_info);static Uint my_size_object(Eterm t);static Eterm my_copy_struct(Eterm t, Eterm **hp, ErlOffHeap* off_heap);static Binary *allocate_magic_binary(size_t size);/* Guard compilation */static void do_emit_constant(DMCContext *context, DMC_STACK_TYPE(Uint) *text,			     Eterm t);static DMCRet dmc_list(DMCContext *context,		       DMCHeap *heap,		       DMC_STACK_TYPE(Uint) *text,		       Eterm t,		       int *constant);static DMCRet dmc_tuple(DMCContext *context,		       DMCHeap *heap,		       DMC_STACK_TYPE(Uint) *text,		       Eterm t,		       int *constant);static DMCRet dmc_variable(DMCContext *context,			   DMCHeap *heap,			   DMC_STACK_TYPE(Uint) *text,			   Eterm t,			   int *constant);static DMCRet dmc_fun(DMCContext *context,		      DMCHeap *heap,		      DMC_STACK_TYPE(Uint) *text,		      Eterm t,		      int *constant);static DMCRet dmc_expr(DMCContext *context,		       DMCHeap *heap,		       DMC_STACK_TYPE(Uint) *text,		       Eterm t,		       int *constant);static DMCRet compile_guard_expr(DMCContext *context,				    DMCHeap *heap,				    DMC_STACK_TYPE(Uint) *text,				    Eterm t);/* match expression subroutine */static DMCRet dmc_one_term(DMCContext *context, 			   DMCHeap *heap,			   DMC_STACK_TYPE(Eterm) *stack,			   DMC_STACK_TYPE(Uint) *text,			   Eterm c);#ifdef DMC_DEBUGstatic int test_disassemble_next = 0;static void db_match_dis(Binary *prog);#define TRACE erts_fprintf(stderr,"Trace: %s:%d\n",__FILE__,__LINE__)#define FENCE_PATTERN_SIZE 1#define FENCE_PATTERN 0xDEADBEEFUL#else#define TRACE /* Nothing */#define FENCE_PATTERN_SIZE 0#endifstatic void add_dmc_err(DMCErrInfo *err_info, 			   char *str,			   int variable,			   Eterm term,			   DMCErrorSeverity severity);static Eterm dpm_array_to_list(Process *psp, Eterm *arr, int arity);static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace);static Eterm seq_trace_fake(Process *p, Eterm arg1);/*** Interface routines.*//*** Pseudo BIF:s to be callable from the PAM VM.*/BIF_RETTYPE db_get_trace_control_word_0(Process *p) {    Uint32 tcw = (Uint32) erts_smp_atomic_read(&trace_control_word);    BIF_RET(erts_make_integer((Uint) tcw, p));}BIF_RETTYPE db_set_trace_control_word_1(Process *p, Eterm new) {    Uint val;    Uint32 old_tcw;    if (!term_to_Uint(new, &val))	BIF_ERROR(p, BADARG);    if (val != ((Uint32)val))	BIF_ERROR(p, BADARG);        old_tcw = (Uint32) erts_smp_atomic_xchg(&trace_control_word, (long) val);    BIF_RET(erts_make_integer((Uint) old_tcw, p));}static Eterm db_set_trace_control_word_fake_1(Process *p, Eterm new) {    Uint val;    if (!term_to_Uint(new, &val))	BIF_ERROR(p, BADARG);    if (val != ((Uint32)val))	BIF_ERROR(p, BADARG);    BIF_RET(db_get_trace_control_word_0(p));}/*** The API used by the tracer (declared in global.h):*//*** Matchexpr is a list of tuples containing match-code, i e:**** Matchexpr = [{Pattern, Guards, Body}, ...]** Pattern = [ PatternExpr , ...]** PatternExpr = Constant | PatternTuple | PatternList | Variable** Constant = Any erlang term** PatternTuple = { PatternExpr ... }** PatternList = [ PatternExpr ]** Variable = '$' ++ <number>** Guards = [Guard ...]** Guard = {GuardFunc, GuardExpr, ...}** GuardExpr = BoundVariable | Guard | GuardList | GuardTuple | ConstExpr** BoundVariable = Variable (existing in Pattern)  ** GuardList = [ GuardExpr , ... ]** GuardTuple = {{ GuardExpr, ... }}** ConstExpr = {const, Constant}** GuardFunc = is_list | .... | element | ...** Body = [ BodyExpr, ... ]** BodyExpr = GuardExpr | { BodyFunc, GuardExpr, ... }** BodyFunc = return_trace | seq_trace | trace | ...** - or something like that...*/Eterm erts_match_set_get_source(Binary *mpsp){    MatchProg *prog = Binary2MatchProg(mpsp);    return prog->saved_program;}/* This one is for the tracing */Binary *erts_match_set_compile(Process *p, Eterm matchexpr) {    Binary *bin;    Uint sz;    Eterm *hp;        bin = db_match_set_compile(p, matchexpr, DCOMP_TRACE);    if (bin != NULL) {	MatchProg *prog = Binary2MatchProg(bin);	sz = size_object(matchexpr);	prog->saved_program_buf = new_message_buffer(sz);	hp = prog->saved_program_buf->mem;	prog->saved_program = 	    copy_struct(matchexpr, sz, &hp, 			&(prog->saved_program_buf->off_heap));    }    return bin;}Binary *db_match_set_compile(Process *p, Eterm matchexpr, 			     Uint flags) {    Eterm l;    Eterm t;    Eterm l2;    Eterm *tp;    Eterm *hp;    int n = 0;    int num_heads;    int i;    Binary *mps = NULL;    int compiled = 0;    Eterm *matches,*guards, *bodies;    Eterm *buff;    Eterm sbuff[15];    if (!is_list(matchexpr))	return NULL;    num_heads = 0;    for (l = matchexpr; is_list(l); l = CDR(list_val(l)))	++num_heads;    if (l != NIL) /* proper list... */	return NULL;    if (num_heads > 5) {	buff = erts_alloc(ERTS_ALC_T_DB_TMP,			  sizeof(Eterm) * num_heads * 3);    } else {	buff = sbuff;    }    matches = buff;    guards = buff + num_heads;    bodies = buff + (num_heads * 2);    i = 0;    for (l = matchexpr; is_list(l); l = CDR(list_val(l))) {	t = CAR(list_val(l));	if (!is_tuple(t) || arityval((tp = tuple_val(t))[0]) != 3) {	    goto error;	}	if (!(flags & DCOMP_TRACE) || (!is_list(tp[1]) && 					!is_nil(tp[1]))) {	    t = tp[1];	} else {	    /* This is when tracing, the parameter is a list,	       that I convert to a tuple and that is matched 	       against an array (strange, but gives the semantics	       of matching against a parameter list) */	    n = 0;	    for (l2 = tp[1]; is_list(l2); l2 = CDR(list_val(l2))) {		++n;	    }	    if (l2 != NIL) {		goto error;	    }	    hp = HAlloc(p, n + 1);	    t = make_tuple(hp);	    *hp++ = make_arityval((Uint) n);	    l2 = tp[1];	    while (n--) {		*hp++ = CAR(list_val(l2));		l2 = CDR(list_val(l2));	    }	}	matches[i] = t;	guards[i] = tp[2];	bodies[i] = tp[3];	++i;    }    if ((mps = db_match_compile(matches, guards, bodies,				num_heads,				flags,				NULL)) == NULL) {	goto error;    }    compiled = 1;    if (buff != sbuff) {	erts_free(ERTS_ALC_T_DB_TMP, buff);    }    return mps;error:    if (compiled) {	erts_match_set_free(mps);    }    if (buff != sbuff) {	erts_free(ERTS_ALC_T_DB_TMP, buff);    }    return NULL;}/* This is used when tracing */Eterm erts_match_set_lint(Process *p, Eterm matchexpr) {    return db_match_set_lint(p, matchexpr, DCOMP_TRACE);}Eterm db_match_set_lint(Process *p, Eterm matchexpr, Uint flags) {    Eterm l;    Eterm t;    Eterm l2;    Eterm *tp;    Eterm *hp;    DMCErrInfo *err_info = db_new_dmc_err_info();    Eterm ret;    int n = 0;    int num_heads;    Binary *mp;    Eterm *matches,*guards, *bodies;    Eterm sbuff[15];    Eterm *buff = sbuff;    int i;    if (!is_list(matchexpr)) {	add_dmc_err(err_info, "Match programs are not in a list.", 		    -1, 0UL, dmcError);	goto done;    }    num_heads = 0;    for (l = matchexpr; is_list(l); l = CDR(list_val(l)))	++num_heads;    if (l != NIL)  { /* proper list... */	add_dmc_err(err_info, "Match programs are not in a proper "		    "list.", 		    -1, 0UL, dmcError);	goto done;    }    if (num_heads > 5) {

⌨️ 快捷键说明

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