// NEEDS TO BE FINISHED WHEN PRIMITIVES ARE REDONE static QualifiedType returnInfoNumericUp(CallExpr* call) { Type* t1 = call->get(1)->typeInfo(); Type* t2 = call->get(2)->typeInfo(); if (is_int_type(t1) && is_real_type(t2)) return QualifiedType(t2, QUAL_VAL); if (is_real_type(t1) && is_int_type(t2)) return QualifiedType(t1, QUAL_VAL); if (is_int_type(t1) && is_bool_type(t2)) return QualifiedType(t1, QUAL_VAL); if (is_bool_type(t1) && is_int_type(t2)) return QualifiedType(t2, QUAL_VAL); return QualifiedType(t1, QUAL_VAL); }
// NEEDS TO BE FINISHED WHEN PRIMITIVES ARE REDONE static Type* returnInfoNumericUp(CallExpr* call) { Type* t1 = call->get(1)->typeInfo(); Type* t2 = call->get(2)->typeInfo(); if (is_int_type(t1) && is_real_type(t2)) return t2; if (is_real_type(t1) && is_int_type(t2)) return t1; if (is_int_type(t1) && is_bool_type(t2)) return t1; if (is_bool_type(t1) && is_int_type(t2)) return t2; return t1; }
IntentTag blankIntentForType(Type* t) { if (isSyncType(t) || isAtomicType(t) || t->symbol->hasFlag(FLAG_ARRAY)) { return INTENT_REF; } else if (is_bool_type(t) || is_int_type(t) || is_uint_type(t) || is_real_type(t) || is_imag_type(t) || is_complex_type(t) || is_enum_type(t) || is_string_type(t) || t == dtStringC || t == dtStringCopy || isClass(t) || isRecord(t) || isUnion(t) || t == dtTaskID || t == dtFile || t == dtTaskList || t == dtNil || t == dtOpaque || t->symbol->hasFlag(FLAG_DOMAIN) || t->symbol->hasFlag(FLAG_DISTRIBUTION) || t->symbol->hasFlag(FLAG_EXTERN)) { return constIntentForType(t); } INT_FATAL(t, "Unhandled type in blankIntentForType()"); return INTENT_BLANK; }
static IntentTag constIntentForType(Type* t) { if (isSyncType(t) || isRecordWrappedType(t) || // domain, array, or distribution isRecord(t) || // may eventually want to decide based on size is_string_type(t)) { return INTENT_CONST_REF; } else if (is_bool_type(t) || is_int_type(t) || is_uint_type(t) || is_real_type(t) || is_imag_type(t) || is_complex_type(t) || is_enum_type(t) || isClass(t) || isUnion(t) || isAtomicType(t) || t == dtOpaque || t == dtTaskID || t == dtFile || t == dtTaskList || t == dtNil || t == dtStringC || t == dtStringCopy || t->symbol->hasFlag(FLAG_EXTERN)) { return INTENT_CONST_IN; } INT_FATAL(t, "Unhandled type in constIntentForType()"); return INTENT_CONST; }
static gboolean iter_func (EggFmtIter *iter, gpointer user_data) { GIOChannel *channel = user_data; gchar *line = NULL; gchar **parts; gboolean result = FALSE; gint i, v_int = 0; GType vtype; if (G_IO_STATUS_NORMAL != g_io_channel_read_line (channel, &line, NULL, NULL, NULL)) return FALSE; g_strstrip (line); parts = g_strsplit (line, "|", iter->n_columns); if (g_strv_length (parts) != iter->n_columns) { result = FALSE; goto cleanup; } for (i = 0; i < iter->n_columns; i++) { vtype = G_VALUE_TYPE (&iter->column_values [i]); if (is_int_type (vtype)) { parse_int (parts [i], &v_int); g_value_set_int (&iter->column_values [i], v_int); } else { g_value_set_string (&iter->column_values [i], parts [i]); } } result = TRUE; cleanup: g_strfreev (parts); g_free (line); return result; }
// Is this type OK to pass by value (e.g. it's reasonably-sized)? static bool passableByVal(Type* type) { if (is_bool_type(type) || is_int_type(type) || is_uint_type(type) || is_real_type(type) || is_imag_type(type) || is_complex_type(type) || is_enum_type(type) || isClass(type) || type == dtTaskID || // For now, allow ranges as a special case, not records in general. type->symbol->hasFlag(FLAG_RANGE) || 0) return true; // TODO: allow reasonably-sized records. NB this-in-taskfns-in-ctors.chpl // TODO: allow reasonably-sized tuples - heterogeneous and homogeneous. return false; }
IntentTag blankIntentForType(Type* t) { IntentTag retval = INTENT_BLANK; if (isSyncType(t) || isAtomicType(t) || t->symbol->hasFlag(FLAG_DEFAULT_INTENT_IS_REF) || t->symbol->hasFlag(FLAG_ARRAY)) { retval = INTENT_REF; } else if (is_bool_type(t) || is_int_type(t) || is_uint_type(t) || is_real_type(t) || is_imag_type(t) || is_complex_type(t) || is_enum_type(t) || t == dtStringC || t == dtStringCopy || t == dtCVoidPtr || t == dtCFnPtr || isClass(t) || isRecord(t) || isUnion(t) || t == dtTaskID || t == dtFile || t == dtNil || t == dtOpaque || t->symbol->hasFlag(FLAG_DOMAIN) || t->symbol->hasFlag(FLAG_DISTRIBUTION) || t->symbol->hasFlag(FLAG_EXTERN)) { retval = constIntentForType(t); } else { INT_FATAL(t, "Unhandled type in blankIntentForType()"); } return retval; }
static MonoInst* emit_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args, const MagicTypeInfo *info) { int i = 0; const char *name = cmethod->name; MonoInst *ins; int type_index, stack_type; if (info->op_index == 2 && cfg->r4fp && SIZEOF_VOID_P == 4) { type_index = 3; stack_type = STACK_R4; } else { type_index = info->op_index; stack_type = info->stack_type; } if (!strcmp ("op_Implicit", name) || !strcmp ("op_Explicit", name)) { int source_size = type_size (cfg, fsig->params [0]); int dest_size = type_size (cfg, fsig->ret); switch (info->big_stack_type) { case STACK_I8: if (!is_int_type (fsig->params [0]) || !is_int_type (fsig->ret)) return NULL; break; case STACK_R8: if (!is_float_type (fsig->params [0]) || !is_float_type (fsig->ret)) return NULL; break; default: g_assert_not_reached (); } //4 -> 4 or 8 -> 8 if (source_size == dest_size) return args [0]; //4 -> 8 if (source_size < dest_size) return emit_widen (cfg, info, args [0]->dreg); //8 -> 4 return emit_narrow (cfg, info, args [0]->dreg); } if (!strcmp (".ctor", name)) { gboolean is_ldaddr = args [0]->opcode == OP_LDADDR; int arg0 = args [1]->dreg; int arg_size = type_size (cfg, fsig->params [0]); if (arg_size > SIZEOF_VOID_P) //8 -> 4 arg0 = emit_narrow (cfg, info, arg0)->dreg; else if (arg_size < SIZEOF_VOID_P) //4 -> 8 arg0 = emit_widen (cfg, info, arg0)->dreg; if (is_ldaddr) { /*Eliminate LDADDR if it's initing a local var*/ int dreg = ((MonoInst*)args [0]->inst_p0)->dreg; NULLIFY_INS (args [0]); EMIT_NEW_UNALU (cfg, ins, info->move, dreg, arg0); cfg->has_indirection = TRUE; } else { EMIT_NEW_STORE_MEMBASE (cfg, ins, info->store_op, args [0]->dreg, 0, arg0); } return ins; } if (!strcmp ("op_Increment", name) || !strcmp ("op_Decrement", name)) { gboolean inc = !strcmp ("op_Increment", name); /* FIXME float inc is too complex to bother with*/ //this is broken with ints too // if (!info->inc_op) return NULL; /* We have IR for inc/dec */ MONO_INST_NEW (cfg, ins, inc ? info->inc_op : info->dec_op); ins->dreg = alloc_dreg (cfg, info->stack_type); ins->sreg1 = args [0]->dreg; ins->inst_imm = 1; ins->type = info->stack_type; MONO_ADD_INS (cfg->cbb, ins); return ins; } for (i = 0; i < sizeof (int_binop) / sizeof (IntIntrisic); ++i) { if (!strcmp (int_binop [i].op_name, name)) { if (!int_binop [i].op_table [info->op_index]) return NULL; g_assert (int_binop [i].op_table [type_index]); MONO_INST_NEW (cfg, ins, int_binop [i].op_table [type_index]); ins->dreg = alloc_dreg (cfg, stack_type); ins->sreg1 = args [0]->dreg; ins->sreg2 = args [1]->dreg; ins->type = stack_type; MONO_ADD_INS (cfg->cbb, ins); return mono_decompose_opcode (cfg, ins); } } for (i = 0; i < sizeof (int_unnop) / sizeof (IntIntrisic); ++i) { if (!strcmp (int_unnop [i].op_name, name)) { g_assert (int_unnop [i].op_table [type_index]); MONO_INST_NEW (cfg, ins, int_unnop [i].op_table [type_index]); ins->dreg = alloc_dreg (cfg, stack_type); ins->sreg1 = args [0]->dreg; ins->type = stack_type; MONO_ADD_INS (cfg->cbb, ins); return ins; } } for (i = 0; i < sizeof (int_cmpop) / sizeof (IntIntrisic); ++i) { if (!strcmp (int_cmpop [i].op_name, name)) { short op_cmp = int_cmpop [i].op_table [type_index]; g_assert (op_cmp); if (info->compare_op) { MONO_INST_NEW (cfg, ins, info->compare_op); ins->dreg = -1; ins->sreg1 = args [0]->dreg; ins->sreg2 = args [1]->dreg; MONO_ADD_INS (cfg->cbb, ins); MONO_INST_NEW (cfg, ins, op_cmp); ins->dreg = alloc_preg (cfg); ins->type = STACK_I4; MONO_ADD_INS (cfg->cbb, ins); } else { MONO_INST_NEW (cfg, ins, op_cmp); guint32 fcmp_dreg = ins->dreg = alloc_ireg (cfg); ins->sreg1 = args [0]->dreg; ins->sreg2 = args [1]->dreg; MONO_ADD_INS (cfg->cbb, ins); if (op_cmp == OP_FCLT_UN || op_cmp == OP_FCGT_UN || op_cmp == OP_RCLT_UN || op_cmp == OP_RCGT_UN) { /* we have to negate the result of this comparison: * - op_GreaterThanOrEqual maps to NOT x OP_FCLT_UN / OP_RCLT_UN * - op_LessThanOrEqual maps to NOT x OP_FCGT_UN / OP_RCGT_UN * * this matches generated bytecode by C# when doing the * same operations on float/double. the `_UN` suffix says * that if an operand is NaN, the result is true. If * OP_FCGE/OP_FCLE is used, it is mapped to instructions * on some architectures that don't detect NaN. For * example, on arm64 the condition `eq` doesn't respect * NaN results of a `fcmp` instruction. */ MONO_INST_NEW (cfg, ins, OP_ICOMPARE_IMM); ins->dreg = -1; ins->sreg1 = fcmp_dreg; ins->inst_imm = 0; MONO_ADD_INS (cfg->cbb, ins); MONO_INST_NEW (cfg, ins, OP_CEQ); ins->dreg = alloc_preg (cfg); ins->type = STACK_I4; MONO_ADD_INS (cfg->cbb, ins); } } return ins; } } return NULL; }
CallExpr* ParamForLoop::foldForResolve() { SymExpr* idxExpr = indexExprGet(); SymExpr* lse = lowExprGet(); SymExpr* hse = highExprGet(); SymExpr* sse = strideExprGet(); if (!lse || !hse || !sse) USR_FATAL(this, "param for loop must be defined over a bounded param range"); VarSymbol* lvar = toVarSymbol(lse->var); VarSymbol* hvar = toVarSymbol(hse->var); VarSymbol* svar = toVarSymbol(sse->var); CallExpr* noop = new CallExpr(PRIM_NOOP); if (!lvar || !hvar || !svar) USR_FATAL(this, "param for loop must be defined over a bounded param range"); if (!lvar->immediate || !hvar->immediate || !svar->immediate) USR_FATAL(this, "param for loop must be defined over a bounded param range"); Symbol* idxSym = idxExpr->var; Symbol* continueSym = continueLabelGet(); Type* idxType = indexType(); IF1_int_type idxSize = (get_width(idxType) == 32) ? INT_SIZE_32 : INT_SIZE_64; // Insert an "insertion marker" for loop unrolling insertAfter(noop); if (is_int_type(idxType)) { int64_t low = lvar->immediate->to_int(); int64_t high = hvar->immediate->to_int(); int64_t stride = svar->immediate->to_int(); if (stride <= 0) { for (int64_t i = high; i >= low; i += stride) { SymbolMap map; map.put(idxSym, new_IntSymbol(i, idxSize)); copyBodyHelper(noop, i, &map, this, continueSym); } } else { for (int64_t i = low; i <= high; i += stride) { SymbolMap map; map.put(idxSym, new_IntSymbol(i, idxSize)); copyBodyHelper(noop, i, &map, this, continueSym); } } } else { INT_ASSERT(is_uint_type(idxType) || is_bool_type(idxType)); uint64_t low = lvar->immediate->to_uint(); uint64_t high = hvar->immediate->to_uint(); int64_t stride = svar->immediate->to_int(); if (stride <= 0) { for (uint64_t i = high; i >= low; i += stride) { SymbolMap map; map.put(idxSym, new_UIntSymbol(i, idxSize)); copyBodyHelper(noop, i, &map, this, continueSym); } } else { for (uint64_t i = low; i <= high; i += stride) { SymbolMap map; map.put(idxSym, new_UIntSymbol(i, idxSize)); copyBodyHelper(noop, i, &map, this, continueSym); } } } // Remove the "insertion marker" noop->remove(); // Replace the paramLoop with the NO-OP replace(noop); return noop; }
static MonoInst* emit_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args, const MagicTypeInfo *info) { int i = 0; const char *name = cmethod->name; MonoInst *ins; int type_index, stack_type; if (info->op_index == 2 && cfg->r4fp && SIZEOF_VOID_P == 4) { type_index = 3; stack_type = STACK_R4; } else { type_index = info->op_index; stack_type = info->stack_type; } if (!strcmp ("op_Implicit", name) || !strcmp ("op_Explicit", name)) { int source_size = type_size (cfg, fsig->params [0]); int dest_size = type_size (cfg, fsig->ret); switch (info->big_stack_type) { case STACK_I8: if (!is_int_type (fsig->params [0]) || !is_int_type (fsig->ret)) return NULL; break; case STACK_R8: if (!is_float_type (fsig->params [0]) || !is_float_type (fsig->ret)) return NULL; break; default: g_assert_not_reached (); } //4 -> 4 or 8 -> 8 if (source_size == dest_size) return args [0]; //4 -> 8 if (source_size < dest_size) return emit_widen (cfg, info, args [0]->dreg); //8 -> 4 return emit_narrow (cfg, info, args [0]->dreg); } if (!strcmp (".ctor", name)) { gboolean is_ldaddr = args [0]->opcode == OP_LDADDR; int arg0 = args [1]->dreg; int arg_size = type_size (cfg, fsig->params [0]); if (arg_size > SIZEOF_VOID_P) //8 -> 4 arg0 = emit_narrow (cfg, info, arg0)->dreg; else if (arg_size < SIZEOF_VOID_P) //4 -> 8 arg0 = emit_widen (cfg, info, arg0)->dreg; if (is_ldaddr) { /*Eliminate LDADDR if it's initing a local var*/ int dreg = ((MonoInst*)args [0]->inst_p0)->dreg; NULLIFY_INS (args [0]); EMIT_NEW_UNALU (cfg, ins, info->move, dreg, arg0); cfg->has_indirection = TRUE; } else { EMIT_NEW_STORE_MEMBASE (cfg, ins, info->store_op, args [0]->dreg, 0, arg0); } return ins; } if (!strcmp ("op_Increment", name) || !strcmp ("op_Decrement", name)) { gboolean inc = !strcmp ("op_Increment", name); /* FIXME float inc is too complex to bother with*/ //this is broken with ints too // if (!info->inc_op) return NULL; /* We have IR for inc/dec */ MONO_INST_NEW (cfg, ins, inc ? info->inc_op : info->dec_op); ins->dreg = alloc_dreg (cfg, info->stack_type); ins->sreg1 = args [0]->dreg; ins->inst_imm = 1; ins->type = info->stack_type; MONO_ADD_INS (cfg->cbb, ins); return ins; } for (i = 0; i < sizeof (int_binop) / sizeof (IntIntrisic); ++i) { if (!strcmp (int_binop [i].op_name, name)) { if (!int_binop [i].op_table [info->op_index]) return NULL; g_assert (int_binop [i].op_table [type_index]); MONO_INST_NEW (cfg, ins, int_binop [i].op_table [type_index]); ins->dreg = alloc_dreg (cfg, stack_type); ins->sreg1 = args [0]->dreg; ins->sreg2 = args [1]->dreg; ins->type = stack_type; MONO_ADD_INS (cfg->cbb, ins); return mono_decompose_opcode (cfg, ins); } } for (i = 0; i < sizeof (int_unnop) / sizeof (IntIntrisic); ++i) { if (!strcmp (int_unnop [i].op_name, name)) { g_assert (int_unnop [i].op_table [type_index]); MONO_INST_NEW (cfg, ins, int_unnop [i].op_table [type_index]); ins->dreg = alloc_dreg (cfg, stack_type); ins->sreg1 = args [0]->dreg; ins->type = stack_type; MONO_ADD_INS (cfg->cbb, ins); return ins; } } for (i = 0; i < sizeof (int_cmpop) / sizeof (IntIntrisic); ++i) { if (!strcmp (int_cmpop [i].op_name, name)) { g_assert (int_cmpop [i].op_table [type_index]); if (info->compare_op) { MONO_INST_NEW (cfg, ins, info->compare_op); ins->dreg = -1; ins->sreg1 = args [0]->dreg; ins->sreg2 = args [1]->dreg; MONO_ADD_INS (cfg->cbb, ins); MONO_INST_NEW (cfg, ins, int_cmpop [i].op_table [type_index]); ins->dreg = alloc_preg (cfg); ins->type = STACK_I4; MONO_ADD_INS (cfg->cbb, ins); } else { MONO_INST_NEW (cfg, ins, int_cmpop [i].op_table [type_index]); ins->dreg = alloc_ireg (cfg); ins->sreg1 = args [0]->dreg; ins->sreg2 = args [1]->dreg; MONO_ADD_INS (cfg->cbb, ins); } return ins; } } return NULL; }
bool DbUtil::runQuery(const char* sql, const Properties& args, SqlResultSet& rows){ rows.clear(); if (!isConnected()) return false; g_debug << "runQuery: " << endl << " sql: '" << sql << "'" << endl; MYSQL_STMT *stmt= mysql_stmt_init(m_mysql); if (mysql_stmt_prepare(stmt, sql, strlen(sql))) { g_err << "Failed to prepare: " << mysql_error(m_mysql) << endl; return false; } uint params= mysql_stmt_param_count(stmt); MYSQL_BIND bind_param[params]; bzero(bind_param, sizeof(bind_param)); for(uint i= 0; i < mysql_stmt_param_count(stmt); i++) { BaseString name; name.assfmt("%d", i); // Parameters are named 0, 1, 2... if (!args.contains(name.c_str())) { g_err << "param " << i << " missing" << endl; assert(false); } PropertiesType t; Uint32 val_i; const char* val_s; args.getTypeOf(name.c_str(), &t); switch(t) { case PropertiesType_Uint32: args.get(name.c_str(), &val_i); bind_param[i].buffer_type= MYSQL_TYPE_LONG; bind_param[i].buffer= (char*)&val_i; g_debug << " param" << name.c_str() << ": " << val_i << endl; break; case PropertiesType_char: args.get(name.c_str(), &val_s); bind_param[i].buffer_type= MYSQL_TYPE_STRING; bind_param[i].buffer= (char*)val_s; bind_param[i].buffer_length= strlen(val_s); g_debug << " param" << name.c_str() << ": " << val_s << endl; break; default: assert(false); break; } } if (mysql_stmt_bind_param(stmt, bind_param)) { g_err << "Failed to bind param: " << mysql_error(m_mysql) << endl; mysql_stmt_close(stmt); return false; } if (mysql_stmt_execute(stmt)) { g_err << "Failed to execute: " << mysql_error(m_mysql) << endl; mysql_stmt_close(stmt); return false; } /* Update max_length, making it possible to know how big buffers to allocate */ my_bool one= 1; mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one); if (mysql_stmt_store_result(stmt)) { g_err << "Failed to store result: " << mysql_error(m_mysql) << endl; mysql_stmt_close(stmt); return false; } uint row= 0; MYSQL_RES* res= mysql_stmt_result_metadata(stmt); if (res != NULL) { MYSQL_FIELD *fields= mysql_fetch_fields(res); uint num_fields= mysql_num_fields(res); MYSQL_BIND bind_result[num_fields]; bzero(bind_result, sizeof(bind_result)); for (uint i= 0; i < num_fields; i++) { if (is_int_type(fields[i].type)){ bind_result[i].buffer_type= MYSQL_TYPE_LONG; bind_result[i].buffer= malloc(sizeof(int)); } else { uint max_length= fields[i].max_length + 1; bind_result[i].buffer_type= MYSQL_TYPE_STRING; bind_result[i].buffer= malloc(max_length); bind_result[i].buffer_length= max_length; } } if (mysql_stmt_bind_result(stmt, bind_result)){ g_err << "Failed to bind result: " << mysql_error(m_mysql) << endl; mysql_stmt_close(stmt); return false; } while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) { Properties curr(true); for (uint i= 0; i < num_fields; i++){ if (is_int_type(fields[i].type)) curr.put(fields[i].name, *(int*)bind_result[i].buffer); else curr.put(fields[i].name, (char*)bind_result[i].buffer); } rows.put("row", row++, &curr); } mysql_free_result(res); for (uint i= 0; i < num_fields; i++) free(bind_result[i].buffer); } // Save stats in result set rows.put("rows", row); rows.put("affected_rows", mysql_affected_rows(m_mysql)); rows.put("mysql_errno", mysql_errno(m_mysql)); rows.put("mysql_error", mysql_error(m_mysql)); rows.put("mysql_sqlstate", mysql_sqlstate(m_mysql)); rows.put("insert_id", mysql_insert_id(m_mysql)); mysql_stmt_close(stmt); return true; }