static int group_net_to_field(type_t type, netid_t nid) { int count = 0; if (type_is_record(type)) { const int nfields = type_fields(type); netid_t first = 0; for (int i = 0; i < nfields; i++) { tree_t field = type_field(type, i); type_t ftype = tree_type(field); const netid_t next = first + type_width(tree_type(field)); if (nid >= first && nid < next) { if (type_is_array(ftype) || type_is_record(ftype)) return count + group_net_to_field(ftype, nid - first); else return count; } first = next; count += type_width(ftype); } fatal_trace("group_net_to_field failed to find field for nid=%d type=%s", nid, type_pp(type)); } else if (type_is_array(type)) { type_t elem = type_elem(type); const int width = type_width(elem); if (type_is_record(elem)) return (nid / width) * width + group_net_to_field(elem, nid % width); else return group_net_to_field(elem, nid % width); } else return 0; }
static void check_main_prototype(struct symbol *main) { int argc = type_function_argc(main->type); if (argc != 0 && argc != 2 && argc != 3) { display_main_proto(); return; } const struct type *returnv = type_function_return(main->type); if (returnv != type_void && returnv != type_int) { display_main_proto(); return; } const struct list *l = type_function_argv(main->type); const struct type *t1, *t2, *t3; switch (argc) { case 2: t1 = ((struct symbol*)list_get(l, 1))->type; t2 = ((struct symbol*)list_get(l, 2))->type; if (t1 != type_int) { display_main_proto(); return; } if (!type_is_array(t2) || type_array_values(t2) != type_string) { display_main_proto(); return; } break; case 3: t1 = ((struct symbol*)list_get(l, 1))->type; t2 = ((struct symbol*)list_get(l, 2))->type; t3 = ((struct symbol*)list_get(l, 2))->type; if (t1 != type_int) { display_main_proto(); return; } if (!type_is_array(t3) || type_array_values(t3) != type_string) { display_main_proto(); return; } if (!type_is_array(t3) || type_array_values(t3) != type_string) { display_main_proto(); return; } break; default: break; } }
bool type_is_array(type_t t) { assert(t != NULL); if (t->kind == T_SUBTYPE) return type_is_array(type_base(t)); else return (t->kind == T_CARRAY || t->kind == T_UARRAY); }
static bool group_contains_record(type_t type) { if (type_is_record(type)) return true; else if (type_is_array(type)) return group_contains_record(type_elem(type)); else return false; }
static int shell_cmd_watch(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { const char *help = "watch - Trace changes to a signal\n" "\n" "Usage: watch SIGNALS...\n" "\n" "Prints a message every time an update occurs to a signal listed." "\n" "Examples:\n" " watch [signals {clk}] Trace updates to all signals named clk\n"; if (show_help(objc, objv, help)) return TCL_OK; if (objc == 1) { warnf("nothing to watch (try -help for usage)"); return TCL_OK; } hash_t *decl_hash = (hash_t *)cd; for (int i = 1; i < objc; i++) { int length; if (Tcl_ListObjLength(interp, objv[i], &length) != TCL_OK) return TCL_ERROR; for (int j = 0; j < length; j++) { Tcl_Obj *obj; if (Tcl_ListObjIndex(interp, objv[i], j, &obj) != TCL_OK) return TCL_ERROR; const char *str = Tcl_GetString(obj); tree_t t = hash_get(decl_hash, ident_new(str)); if (t == NULL) return tcl_error(interp, "object not found: %s", str); if (t == NULL) return tcl_error(interp, "object not found: %s", str); else if (tree_kind(t) != T_SIGNAL_DECL) return tcl_error(interp, "not a signal: %s", str); else if (type_is_array(tree_type(t))) return tcl_error(interp, "only scalar signals may be watched"); // TODO: make this work for arrays slave_watch_msg_t msg = { .index = tree_index(t) }; slave_post_msg(SLAVE_WATCH, &msg, sizeof(msg)); } } return TCL_OK; }
/** * Convert postgres Datum into a ConcreteValue object. */ AbstractValueSPtr AbstractPGValue::DatumToValue(bool inMemoryIsWritable, Oid inTypeID, Datum inDatum) const { // First check if datum is rowtype if (type_is_rowtype(inTypeID)) { HeapTupleHeader pgTuple = DatumGetHeapTupleHeader(inDatum); return AbstractValueSPtr(new PGValue<HeapTupleHeader>(pgTuple)); } else if (type_is_array(inTypeID)) { ArrayType *pgArray = DatumGetArrayTypeP(inDatum); if (ARR_NDIM(pgArray) != 1) throw std::invalid_argument("Multidimensional arrays not yet supported"); if (ARR_HASNULL(pgArray)) throw std::invalid_argument("Arrays with NULLs not yet supported"); switch (ARR_ELEMTYPE(pgArray)) { case FLOAT8OID: { MemHandleSPtr memoryHandle(new PGArrayHandle(pgArray)); if (inMemoryIsWritable) { return AbstractValueSPtr( new ConcreteValue<Array<double> >( Array<double>(memoryHandle, boost::extents[ ARR_DIMS(pgArray)[0] ]) ) ); } else { return AbstractValueSPtr( new ConcreteValue<Array_const<double> >( Array_const<double>(memoryHandle, boost::extents[ ARR_DIMS(pgArray)[0] ]) ) ); } } } } switch (inTypeID) { case BOOLOID: return AbstractValueSPtr( new ConcreteValue<bool>( DatumGetBool(inDatum) )); case INT2OID: return AbstractValueSPtr( new ConcreteValue<int16_t>( DatumGetInt16(inDatum) )); case INT4OID: return AbstractValueSPtr( new ConcreteValue<int32_t>( DatumGetInt32(inDatum) )); case INT8OID: return AbstractValueSPtr( new ConcreteValue<int64_t>( DatumGetInt64(inDatum) )); case FLOAT4OID: return AbstractValueSPtr( new ConcreteValue<float>( DatumGetFloat4(inDatum) )); case FLOAT8OID: return AbstractValueSPtr( new ConcreteValue<double>( DatumGetFloat8(inDatum) )); } return AbstractValueSPtr(); }
int expr_must_lvalue(expr *e, const char *desc) { int lval = (expr_is_lval(e) == LVALUE_USER_ASSIGNABLE); if(!lval || type_is_array(e->tree_type)){ fold_had_error = 1; warn_at_print_error(&e->where, "%s to %s - %s", desc, type_to_str(e->tree_type), lval ? "arrays not assignable" : "not an lvalue"); return 0; } return 1; }
/* build an array in reverse order i.e: given values = array< 10, array< 3, int > > and size = 42 (42 must be wrapped inside an expression) return array< 10, array< 3, array< 42, int > > > --> it nest the newly created array inside the one it is given keeping the same basic type */ const struct type * type_new_array_type_reversed(const struct type *values, const struct expression *array_size) { struct type *ty = type_new(TYPE_ARRAY); if (!type_is_array(values)) { ty->array_type.values = values; ty->array_type.array_size = array_size; return ty; } ty->array_type.array_size = type_array_size(values); ty->array_type.values = type_new_array_type(type_array_values(values), array_size); return ty; }
int expr_is_lval(expr *e) { if(!e->f_lea) return 0; /* special case: * (a = b) = c * ^~~~~~~ not an lvalue, but internally we handle it as one */ if(expr_kind(e, assign) && type_is_s_or_u(e->tree_type)) return 0; if(type_is_array(e->tree_type)) return 0; return 1; }
enum type_str_type type_str_type(type *r) { type *t = type_is_array(r); if(!t) t = type_is_ptr(r); t = type_is_primitive(t, type_unknown); switch(t ? t->bits.type->primitive : type_unknown){ case type_schar: case type_nchar: case type_uchar: return type_str_char; case type_int: return type_str_wchar; default: return type_str_no; } }
unsigned type_width(type_t type) { if (type_is_array(type)) { const unsigned elem_w = type_width(type_elem(type)); unsigned w = 1; const int ndims = type_dims(type); for (int i = 0; i < ndims; i++) { int64_t low, high; range_bounds(type_dim(type, i), &low, &high); w *= MAX(high - low + 1, 0) * elem_w; } return w; } else if (type_is_record(type)) { type_t base = type_base_recur(type); unsigned w = 0; const int nfields = type_fields(base); for (int i = 0; i < nfields; i++) w += type_width(tree_type(type_field(base, i))); return w; } else return 1; }
static void vcd_process_signal(tree_t d, int *next_key) { type_t type = tree_type(d); type_t base = type_base_recur(type); vcd_data_t *data = xmalloc(sizeof(vcd_data_t)); memset(data, '\0', sizeof(vcd_data_t)); int msb = 0, lsb = 0; if (type_is_array(type)) { if (type_dims(type) > 1) { warn_at(tree_loc(d), "cannot represent multidimensional arrays " "in VCD format"); free(data); return; } range_t r = type_dim(type, 0); int64_t low, high; range_bounds(r, &low, &high); data->dir = r.kind; data->size = high - low + 1; msb = assume_int(r.left); lsb = assume_int(r.right); type_t elem = type_elem(type); if (!vcd_can_fmt_chars(elem, data)) { warn_at(tree_loc(d), "cannot represent arrays of type %s " "in VCD format", type_pp(elem)); free(data); return; } } else { switch (type_kind(base)) { case T_INTEGER: { int64_t low, high; range_bounds(type_dim(type, 0), &low, &high); data->size = ilog2(high - low + 1); data->fmt = vcd_fmt_int; } break; case T_ENUM: if (vcd_can_fmt_chars(type, data)) { data->size = 1; break; } // Fall-through default: warn_at(tree_loc(d), "cannot represent type %s in VCD format", type_pp(type)); free(data); return; } } const char *name_base = strrchr(istr(tree_ident(d)), ':') + 1; const size_t base_len = strlen(name_base); char name[base_len + 64]; strncpy(name, name_base, base_len + 64); if (type_is_array(type)) snprintf(name + base_len, 64, "[%d:%d]\n", msb, lsb); tree_add_attr_ptr(d, vcd_data_i, data); data->watch = rt_set_event_cb(d, vcd_event_cb, data, true); vcd_key_fmt(*next_key, data->key); fprintf(vcd_file, "$var reg %d %s %s $end\n", (int)data->size, data->key, name); ++(*next_key); }
void lxt_restart(void) { if (trace == NULL) return; lt_set_timescale(trace, -15); lt_symbol_bracket_stripping(trace, 0); lt_set_clock_compress(trace); const int ndecls = tree_decls(lxt_top); for (int i = 0; i < ndecls; i++) { tree_t d = tree_decl(lxt_top, i); if (tree_kind(d) != T_SIGNAL_DECL) continue; else if (!wave_should_dump(d)) continue; type_t type = tree_type(d); int rows, msb, lsb; if (type_is_array(type)) { rows = type_dims(type) - 1; if ((rows > 0) || type_is_array(type_elem(type))) { warn_at(tree_loc(d), "cannot emit arrays of greater than one " "dimension or arrays of arrays in LXT yet"); continue; } range_t r = type_dim(type, 0); msb = assume_int(r.left); lsb = assume_int(r.right); } else { rows = 0; msb = lsb = -1; } lxt_data_t *data = xmalloc(sizeof(lxt_data_t)); memset(data, '\0', sizeof(lxt_data_t)); int flags = 0; if (type_is_array(type)) { // Only arrays of CHARACTER, BIT, STD_ULOGIC are supported type_t elem = type_base_recur(type_elem(type)); if ((type_kind(elem) != T_ENUM) || !lxt_can_fmt_enum_chars(elem, data, &flags)) { warn_at(tree_loc(d), "cannot represent arrays of type %s " "in LXT format", type_pp(elem)); free(data); continue; } data->dir = type_dim(type, 0).kind; } else { type_t base = type_base_recur(type); switch (type_kind(base)) { case T_INTEGER: data->fmt = lxt_fmt_int; flags = LT_SYM_F_INTEGER; break; case T_ENUM: if (!lxt_can_fmt_enum_chars(base, data, &flags)) { data->fmt = lxt_fmt_enum; flags = LT_SYM_F_STRING; } break; default: warn_at(tree_loc(d), "cannot represent type %s in LXT format", type_pp(type)); free(data); continue; } } char *name = lxt_fmt_name(d); data->sym = lt_symbol_add(trace, name, rows, msb, lsb, flags); free(name); tree_add_attr_ptr(d, lxt_data_i, data); watch_t *w = rt_set_event_cb(d, lxt_event_cb, data, true); (*data->fmt)(d, w, data); } last_time = (lxttime_t)-1; }
/* * Given the result tuple descriptor for a function with OUT parameters, * replace any polymorphic columns (ANYELEMENT etc) with correct data types * deduced from the input arguments. Returns TRUE if able to deduce all types, * FALSE if not. */ static bool resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, Node *call_expr) { int natts = tupdesc->natts; int nargs = declared_args->dim1; bool have_anyelement_result = false; bool have_anyarray_result = false; bool have_anynonarray = false; bool have_anyenum = false; Oid anyelement_type = InvalidOid; Oid anyarray_type = InvalidOid; Oid anycollation; int i; /* See if there are any polymorphic outputs; quick out if not */ for (i = 0; i < natts; i++) { switch (tupdesc->attrs[i]->atttypid) { case ANYELEMENTOID: have_anyelement_result = true; break; case ANYARRAYOID: have_anyarray_result = true; break; case ANYNONARRAYOID: have_anyelement_result = true; have_anynonarray = true; break; case ANYENUMOID: have_anyelement_result = true; have_anyenum = true; break; default: break; } } if (!have_anyelement_result && !have_anyarray_result) return true; /* * Otherwise, extract actual datatype(s) from input arguments. (We assume * the parser already validated consistency of the arguments.) */ if (!call_expr) return false; /* no hope */ for (i = 0; i < nargs; i++) { switch (declared_args->values[i]) { case ANYELEMENTOID: case ANYNONARRAYOID: case ANYENUMOID: if (!OidIsValid(anyelement_type)) anyelement_type = get_call_expr_argtype(call_expr, i); break; case ANYARRAYOID: if (!OidIsValid(anyarray_type)) anyarray_type = get_call_expr_argtype(call_expr, i); break; default: break; } } /* If nothing found, parser messed up */ if (!OidIsValid(anyelement_type) && !OidIsValid(anyarray_type)) return false; /* If needed, deduce one polymorphic type from the other */ if (have_anyelement_result && !OidIsValid(anyelement_type)) anyelement_type = resolve_generic_type(ANYELEMENTOID, anyarray_type, ANYARRAYOID); if (have_anyarray_result && !OidIsValid(anyarray_type)) anyarray_type = resolve_generic_type(ANYARRAYOID, anyelement_type, ANYELEMENTOID); /* Enforce ANYNONARRAY if needed */ if (have_anynonarray && type_is_array(anyelement_type)) return false; /* Enforce ANYENUM if needed */ if (have_anyenum && !type_is_enum(anyelement_type)) return false; /* * Identify the collation to use for polymorphic OUT parameters. (It'll * necessarily be the same for both anyelement and anyarray.) */ anycollation = get_typcollation(OidIsValid(anyelement_type) ? anyelement_type : anyarray_type); if (OidIsValid(anycollation)) { /* * The types are collatable, so consider whether to use a nondefault * collation. We do so if we can identify the input collation used * for the function. */ Oid inputcollation = exprInputCollation(call_expr); if (OidIsValid(inputcollation)) anycollation = inputcollation; } /* And finally replace the tuple column types as needed */ for (i = 0; i < natts; i++) { switch (tupdesc->attrs[i]->atttypid) { case ANYELEMENTOID: case ANYNONARRAYOID: case ANYENUMOID: TupleDescInitEntry(tupdesc, i + 1, NameStr(tupdesc->attrs[i]->attname), anyelement_type, -1, 0); TupleDescInitEntryCollation(tupdesc, i + 1, anycollation); break; case ANYARRAYOID: TupleDescInitEntry(tupdesc, i + 1, NameStr(tupdesc->attrs[i]->attname), anyarray_type, -1, 0); TupleDescInitEntryCollation(tupdesc, i + 1, anycollation); break; default: break; } } return true; }
/* * Given the result tuple descriptor for a function with OUT parameters, * replace any polymorphic columns (ANYELEMENT etc) with correct data types * deduced from the input arguments. Returns TRUE if able to deduce all types, * FALSE if not. */ static bool resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, Node *call_expr) { int natts = tupdesc->natts; int nargs = declared_args->dim1; bool have_anyelement_result = false; bool have_anyarray_result = false; bool have_anynonarray = false; bool have_anyenum = false; Oid anyelement_type = InvalidOid; Oid anyarray_type = InvalidOid; int i; /* See if there are any polymorphic outputs; quick out if not */ for (i = 0; i < natts; i++) { switch (tupdesc->attrs[i]->atttypid) { case ANYELEMENTOID: have_anyelement_result = true; break; case ANYARRAYOID: have_anyarray_result = true; break; case ANYNONARRAYOID: have_anyelement_result = true; have_anynonarray = true; break; case ANYENUMOID: have_anyelement_result = true; have_anyenum = true; break; default: break; } } if (!have_anyelement_result && !have_anyarray_result) return true; /* * Otherwise, extract actual datatype(s) from input arguments. (We assume * the parser already validated consistency of the arguments.) */ if (!call_expr) return false; /* no hope */ for (i = 0; i < nargs; i++) { switch (declared_args->values[i]) { case ANYELEMENTOID: case ANYNONARRAYOID: case ANYENUMOID: if (!OidIsValid(anyelement_type)) anyelement_type = get_call_expr_argtype(call_expr, i); break; case ANYARRAYOID: if (!OidIsValid(anyarray_type)) anyarray_type = get_call_expr_argtype(call_expr, i); break; default: break; } } /* If nothing found, parser messed up */ if (!OidIsValid(anyelement_type) && !OidIsValid(anyarray_type)) return false; /* If needed, deduce one polymorphic type from the other */ if (have_anyelement_result && !OidIsValid(anyelement_type)) anyelement_type = resolve_generic_type(ANYELEMENTOID, anyarray_type, ANYARRAYOID); if (have_anyarray_result && !OidIsValid(anyarray_type)) anyarray_type = resolve_generic_type(ANYARRAYOID, anyelement_type, ANYELEMENTOID); /* Enforce ANYNONARRAY if needed */ if (have_anynonarray && type_is_array(anyelement_type)) return false; /* Enforce ANYENUM if needed */ if (have_anyenum && !type_is_enum(anyelement_type)) return false; /* And finally replace the tuple column types as needed */ for (i = 0; i < natts; i++) { switch (tupdesc->attrs[i]->atttypid) { case ANYELEMENTOID: case ANYNONARRAYOID: case ANYENUMOID: TupleDescInitEntry(tupdesc, i + 1, NameStr(tupdesc->attrs[i]->attname), anyelement_type, -1, 0); break; case ANYARRAYOID: TupleDescInitEntry(tupdesc, i + 1, NameStr(tupdesc->attrs[i]->attname), anyarray_type, -1, 0); break; default: break; } } return true; }
static void fst_process_signal(tree_t d) { type_t type = tree_type(d); type_t base = type_base_recur(type); fst_data_t *data = xmalloc(sizeof(fst_data_t)); memset(data, '\0', sizeof(fst_data_t)); int msb = 0, lsb = 0; enum fstVarType vt; enum fstSupplementalDataType sdt; if (type_is_array(type)) { if (type_dims(type) > 1) { warn_at(tree_loc(d), "cannot represent multidimensional arrays " "in FST format"); free(data); return; } range_t r = type_dim(type, 0); int64_t low, high; range_bounds(r, &low, &high); data->dir = r.kind; data->size = high - low + 1; msb = assume_int(r.left); lsb = assume_int(r.right); type_t elem = type_elem(type); if (!fst_can_fmt_chars(elem, data, &vt, &sdt)) { warn_at(tree_loc(d), "cannot represent arrays of type %s " "in FST format", type_pp(elem)); free(data); return; } else { ident_t ident = type_ident(base); if (ident == unsigned_i) sdt = FST_SDT_VHDL_UNSIGNED; else if (ident == signed_i) sdt = FST_SDT_VHDL_SIGNED; } } else { switch (type_kind(base)) { case T_INTEGER: { ident_t ident = type_ident(type); if (ident == natural_i) sdt = FST_SDT_VHDL_NATURAL; else if (ident == positive_i) sdt = FST_SDT_VHDL_POSITIVE; else sdt = FST_SDT_VHDL_INTEGER; int64_t low, high; range_bounds(type_dim(type, 0), &low, &high); vt = FST_VT_VCD_INTEGER; data->size = ilog2(high - low + 1); data->fmt = fst_fmt_int; } break; case T_ENUM: if (!fst_can_fmt_chars(type, data, &vt, &sdt)) { ident_t ident = type_ident(base); if (ident == std_bool_i) sdt = FST_SDT_VHDL_BOOLEAN; else if (ident == std_char_i) sdt = FST_SDT_VHDL_CHARACTER; else sdt = FST_SDT_NONE; vt = FST_VT_GEN_STRING; data->size = 0; data->fmt = fst_fmt_enum; } else data->size = 1; break; case T_PHYSICAL: { sdt = FST_SDT_NONE; vt = FST_VT_GEN_STRING; data->size = 0; data->type.units = fst_make_unit_map(type); data->fmt = fst_fmt_physical; } break; default: warn_at(tree_loc(d), "cannot represent type %s in FST format", type_pp(type)); free(data); return; } } enum fstVarDir dir = FST_VD_IMPLICIT; switch (tree_attr_int(d, fst_dir_i, -1)) { case PORT_IN: dir = FST_VD_INPUT; break; case PORT_OUT: dir = FST_VD_OUTPUT; break; case PORT_INOUT: dir = FST_VD_INOUT; break; case PORT_BUFFER: dir = FST_VD_BUFFER; break; } const char *name_base = strrchr(istr(tree_ident(d)), ':') + 1; const size_t base_len = strlen(name_base); char name[base_len + 64]; strncpy(name, name_base, base_len + 64); if (type_is_array(type)) snprintf(name + base_len, 64, "[%d:%d]\n", msb, lsb); data->handle = fstWriterCreateVar2( fst_ctx, vt, dir, data->size, name, 0, type_pp(type), FST_SVT_VHDL_SIGNAL, sdt); tree_add_attr_ptr(d, fst_data_i, data); data->watch = rt_set_event_cb(d, fst_event_cb, data, true); }
/** * @brief Convert postgres Datum into a ConcreteValue object. */ AbstractValueSPtr PGAbstractValue::DatumToValue(bool inMemoryIsWritable, Oid inTypeID, Datum inDatum) const { bool isTuple; bool isArray; HeapTupleHeader pgTuple; ArrayType *pgArray; bool errorOccurred = false; PG_TRY(); { isTuple = type_is_rowtype(inTypeID); isArray = type_is_array(inTypeID); if (isTuple) pgTuple = DatumGetHeapTupleHeader(inDatum); else if (isArray) pgArray = DatumGetArrayTypeP(inDatum); } PG_CATCH(); { errorOccurred = true; } PG_END_TRY(); BOOST_ASSERT_MSG(errorOccurred == false, "An exception occurred while " "converting a PostgreSQL datum to DBAL object."); // First check if datum is rowtype if (isTuple) { return AbstractValueSPtr(new PGValue<HeapTupleHeader>(pgTuple)); } else if (isArray) { if (ARR_NDIM(pgArray) != 1) throw std::invalid_argument("Multidimensional arrays not yet supported"); if (ARR_HASNULL(pgArray)) throw std::invalid_argument("Arrays with NULLs not yet supported"); switch (ARR_ELEMTYPE(pgArray)) { case FLOAT8OID: { MemHandleSPtr memoryHandle(new PGArrayHandle(pgArray)); if (inMemoryIsWritable) { return AbstractValueSPtr( new ConcreteValue<Array<double> >( Array<double>(memoryHandle, boost::extents[ ARR_DIMS(pgArray)[0] ]) ) ); } else { return AbstractValueSPtr( new ConcreteValue<Array_const<double> >( Array_const<double>(memoryHandle, boost::extents[ ARR_DIMS(pgArray)[0] ]) ) ); } } // FIXME: Default case } } switch (inTypeID) { case BOOLOID: return AbstractValueSPtr( new ConcreteValue<bool>( DatumGetBool(inDatum) )); case INT2OID: return AbstractValueSPtr( new ConcreteValue<int16_t>( DatumGetInt16(inDatum) )); case INT4OID: return AbstractValueSPtr( new ConcreteValue<int32_t>( DatumGetInt32(inDatum) )); case INT8OID: return AbstractValueSPtr( new ConcreteValue<int64_t>( DatumGetInt64(inDatum) )); case FLOAT4OID: return AbstractValueSPtr( new ConcreteValue<float>( DatumGetFloat4(inDatum) )); case FLOAT8OID: return AbstractValueSPtr( new ConcreteValue<double>( DatumGetFloat8(inDatum) )); } return AbstractValueSPtr(); }
static int shell_cmd_show(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { const char *help = "show - Display simulation objects\n" "\n" "Usage: show LIST...\n" "\n" "Prints a representation of each simulation object in LIST. Typically\n" "this will be a list of signal names and the output will show their\n" "current value.\n" "\n" "Examples:\n" " show {:top:foo} Print value of signal :top_foo\n" " show [signals] Print value of all signals\n"; if (show_help(objc, objv, help)) return TCL_OK; if (objc == 1) { warnf("nothing to show (try -help for usage)"); return TCL_OK; } hash_t *decl_hash = (hash_t *)cd; for (int i = 1; i < objc; i++) { int length; if (Tcl_ListObjLength(interp, objv[i], &length) != TCL_OK) return TCL_ERROR; for (int j = 0; j < length; j++) { Tcl_Obj *obj; if (Tcl_ListObjIndex(interp, objv[i], j, &obj) != TCL_OK) return TCL_ERROR; const char *str = Tcl_GetString(obj); tree_t t = hash_get(decl_hash, ident_new(str)); if (t == NULL) return tcl_error(interp, "object not found: %s", str); tree_kind_t kind = tree_kind(t); switch (kind) { case T_SIGNAL_DECL: { size_t len = 1; type_t type = tree_type(t); while (type_is_array(type)) { int64_t low = 0, high = 0; range_bounds(type_dim(type, 0), &low, &high); len *= (high - low + 1); type = type_elem(type); } slave_read_signal_msg_t msg = { .index = tree_index(t), .len = len }; slave_post_msg(SLAVE_READ_SIGNAL, &msg, sizeof(msg)); const size_t rsz = sizeof(reply_read_signal_msg_t) + (msg.len * sizeof(uint64_t)); reply_read_signal_msg_t *reply = xmalloc(rsz); slave_get_reply(REPLY_READ_SIGNAL, reply, rsz); const char *type_str = type_pp(type); const char *short_name = strrchr(type_str, '.'); printf("%-30s%-20s%s\n", str, (short_name != NULL ? short_name + 1 : type_str), pprint(t, reply->values, msg.len)); free(reply); } break; default: return tcl_error(interp, "cannot show tree kind %s", tree_kind_str(kind)); } } } return TCL_OK; }
Variant mono_object_to_variant(MonoObject *p_obj) { if (!p_obj) return Variant(); GDMonoClass *tclass = GDMono::get_singleton()->get_class(mono_object_get_class(p_obj)); ERR_FAIL_COND_V(!tclass, Variant()); MonoType *raw_type = tclass->get_mono_type(); ManagedType type; type.type_encoding = mono_type_get_type(raw_type); type.type_class = tclass; switch (type.type_encoding) { case MONO_TYPE_BOOLEAN: return (bool)unbox<MonoBoolean>(p_obj); case MONO_TYPE_I1: return unbox<int8_t>(p_obj); case MONO_TYPE_I2: return unbox<int16_t>(p_obj); case MONO_TYPE_I4: return unbox<int32_t>(p_obj); case MONO_TYPE_I8: return unbox<int64_t>(p_obj); case MONO_TYPE_U1: return unbox<uint8_t>(p_obj); case MONO_TYPE_U2: return unbox<uint16_t>(p_obj); case MONO_TYPE_U4: return unbox<uint32_t>(p_obj); case MONO_TYPE_U8: return unbox<uint64_t>(p_obj); case MONO_TYPE_R4: return unbox<float>(p_obj); case MONO_TYPE_R8: return unbox<double>(p_obj); case MONO_TYPE_STRING: { if (p_obj == NULL) return Variant(); // NIL return mono_string_to_godot_not_null((MonoString *)p_obj); } break; case MONO_TYPE_VALUETYPE: { GDMonoClass *tclass = type.type_class; if (tclass == CACHED_CLASS(Vector2)) RETURN_UNBOXED_STRUCT(Vector2, p_obj); if (tclass == CACHED_CLASS(Rect2)) RETURN_UNBOXED_STRUCT(Rect2, p_obj); if (tclass == CACHED_CLASS(Transform2D)) RETURN_UNBOXED_STRUCT(Transform2D, p_obj); if (tclass == CACHED_CLASS(Vector3)) RETURN_UNBOXED_STRUCT(Vector3, p_obj); if (tclass == CACHED_CLASS(Basis)) RETURN_UNBOXED_STRUCT(Basis, p_obj); if (tclass == CACHED_CLASS(Quat)) RETURN_UNBOXED_STRUCT(Quat, p_obj); if (tclass == CACHED_CLASS(Transform)) RETURN_UNBOXED_STRUCT(Transform, p_obj); if (tclass == CACHED_CLASS(AABB)) RETURN_UNBOXED_STRUCT(AABB, p_obj); if (tclass == CACHED_CLASS(Color)) RETURN_UNBOXED_STRUCT(Color, p_obj); if (tclass == CACHED_CLASS(Plane)) RETURN_UNBOXED_STRUCT(Plane, p_obj); if (mono_class_is_enum(tclass->get_mono_ptr())) return unbox<int32_t>(p_obj); } break; case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { MonoArrayType *array_type = mono_type_get_array_type(type.type_class->get_mono_type()); if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) return mono_array_to_Array((MonoArray *)p_obj); if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) return mono_array_to_PoolByteArray((MonoArray *)p_obj); if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) return mono_array_to_PoolIntArray((MonoArray *)p_obj); if (array_type->eklass == REAL_T_MONOCLASS) return mono_array_to_PoolRealArray((MonoArray *)p_obj); if (array_type->eklass == CACHED_CLASS_RAW(String)) return mono_array_to_PoolStringArray((MonoArray *)p_obj); if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) return mono_array_to_PoolVector2Array((MonoArray *)p_obj); if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) return mono_array_to_PoolVector3Array((MonoArray *)p_obj); if (array_type->eklass == CACHED_CLASS_RAW(Color)) return mono_array_to_PoolColorArray((MonoArray *)p_obj); ERR_EXPLAIN(String() + "Attempted to convert a managed array of unmarshallable element type to Variant."); ERR_FAIL_V(Variant()); } break; case MONO_TYPE_CLASS: { GDMonoClass *type_class = type.type_class; // GodotObject if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { Object *ptr = unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_obj)); return ptr ? Variant(ptr) : Variant(); } if (CACHED_CLASS(NodePath) == type_class) { NodePath *ptr = unbox<NodePath *>(CACHED_FIELD(NodePath, ptr)->get_value(p_obj)); return ptr ? Variant(*ptr) : Variant(); } if (CACHED_CLASS(RID) == type_class) { RID *ptr = unbox<RID *>(CACHED_FIELD(RID, ptr)->get_value(p_obj)); return ptr ? Variant(*ptr) : Variant(); } if (CACHED_CLASS(Array) == type_class) { MonoException *exc = NULL; GDMonoUtils::Array_GetPtr get_ptr = CACHED_METHOD_THUNK(Array, GetPtr); Array *ptr = get_ptr(p_obj, (MonoObject **)&exc); UNLIKELY_UNHANDLED_EXCEPTION(exc); return ptr ? Variant(*ptr) : Variant(); } if (CACHED_CLASS(Dictionary) == type_class) { MonoException *exc = NULL; GDMonoUtils::Dictionary_GetPtr get_ptr = CACHED_METHOD_THUNK(Dictionary, GetPtr); Dictionary *ptr = get_ptr(p_obj, (MonoObject **)&exc); UNLIKELY_UNHANDLED_EXCEPTION(exc); return ptr ? Variant(*ptr) : Variant(); } } break; case MONO_TYPE_GENERICINST: { MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, type.type_class->get_mono_type()); MonoException *exc = NULL; GDMonoUtils::IsDictionaryGenericType type_is_dict = CACHED_METHOD_THUNK(MarshalUtils, IsDictionaryGenericType); MonoBoolean is_dict = type_is_dict((MonoObject *)reftype, (MonoObject **)&exc); UNLIKELY_UNHANDLED_EXCEPTION(exc); if (is_dict) { MonoException *exc = NULL; MonoObject *ret = type.type_class->get_method("GetPtr")->invoke(p_obj, &exc); UNLIKELY_UNHANDLED_EXCEPTION(exc); return *unbox<Dictionary *>(ret); } exc = NULL; GDMonoUtils::IsArrayGenericType type_is_array = CACHED_METHOD_THUNK(MarshalUtils, IsArrayGenericType); MonoBoolean is_array = type_is_array((MonoObject *)reftype, (MonoObject **)&exc); UNLIKELY_UNHANDLED_EXCEPTION(exc); if (is_array) { MonoException *exc = NULL; MonoObject *ret = type.type_class->get_method("GetPtr")->invoke(p_obj, &exc); UNLIKELY_UNHANDLED_EXCEPTION(exc); return *unbox<Array *>(ret); } } break; } ERR_EXPLAIN(String() + "Attempted to convert an unmarshallable managed type to Variant. Name: \'" + type.type_class->get_name() + "\' Encoding: " + itos(type.type_encoding)); ERR_FAIL_V(Variant()); }
MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_type) { switch (p_type.type_encoding) { case MONO_TYPE_BOOLEAN: { MonoBoolean val = p_var->operator bool(); return BOX_BOOLEAN(val); } case MONO_TYPE_I1: { char val = p_var->operator signed char(); return BOX_INT8(val); } case MONO_TYPE_I2: { short val = p_var->operator signed short(); return BOX_INT16(val); } case MONO_TYPE_I4: { int val = p_var->operator signed int(); return BOX_INT32(val); } case MONO_TYPE_I8: { int64_t val = p_var->operator int64_t(); return BOX_INT64(val); } case MONO_TYPE_U1: { char val = p_var->operator unsigned char(); return BOX_UINT8(val); } case MONO_TYPE_U2: { short val = p_var->operator unsigned short(); return BOX_UINT16(val); } case MONO_TYPE_U4: { int val = p_var->operator unsigned int(); return BOX_UINT32(val); } case MONO_TYPE_U8: { uint64_t val = p_var->operator uint64_t(); return BOX_UINT64(val); } case MONO_TYPE_R4: { float val = p_var->operator float(); return BOX_FLOAT(val); } case MONO_TYPE_R8: { double val = p_var->operator double(); return BOX_DOUBLE(val); } case MONO_TYPE_STRING: { return (MonoObject *)mono_string_from_godot(p_var->operator String()); } break; case MONO_TYPE_VALUETYPE: { GDMonoClass *tclass = p_type.type_class; if (tclass == CACHED_CLASS(Vector2)) RETURN_BOXED_STRUCT(Vector2, p_var); if (tclass == CACHED_CLASS(Rect2)) RETURN_BOXED_STRUCT(Rect2, p_var); if (tclass == CACHED_CLASS(Transform2D)) RETURN_BOXED_STRUCT(Transform2D, p_var); if (tclass == CACHED_CLASS(Vector3)) RETURN_BOXED_STRUCT(Vector3, p_var); if (tclass == CACHED_CLASS(Basis)) RETURN_BOXED_STRUCT(Basis, p_var); if (tclass == CACHED_CLASS(Quat)) RETURN_BOXED_STRUCT(Quat, p_var); if (tclass == CACHED_CLASS(Transform)) RETURN_BOXED_STRUCT(Transform, p_var); if (tclass == CACHED_CLASS(AABB)) RETURN_BOXED_STRUCT(AABB, p_var); if (tclass == CACHED_CLASS(Color)) RETURN_BOXED_STRUCT(Color, p_var); if (tclass == CACHED_CLASS(Plane)) RETURN_BOXED_STRUCT(Plane, p_var); if (mono_class_is_enum(tclass->get_mono_ptr())) { int val = p_var->operator signed int(); return BOX_ENUM(tclass->get_mono_ptr(), val); } } break; case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type()); if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) return (MonoObject *)Array_to_mono_array(p_var->operator Array()); if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) return (MonoObject *)PoolByteArray_to_mono_array(p_var->operator PoolByteArray()); if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) return (MonoObject *)PoolIntArray_to_mono_array(p_var->operator PoolIntArray()); if (array_type->eklass == REAL_T_MONOCLASS) return (MonoObject *)PoolRealArray_to_mono_array(p_var->operator PoolRealArray()); if (array_type->eklass == CACHED_CLASS_RAW(String)) return (MonoObject *)PoolStringArray_to_mono_array(p_var->operator PoolStringArray()); if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) return (MonoObject *)PoolVector2Array_to_mono_array(p_var->operator PoolVector2Array()); if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) return (MonoObject *)PoolVector3Array_to_mono_array(p_var->operator PoolVector3Array()); if (array_type->eklass == CACHED_CLASS_RAW(Color)) return (MonoObject *)PoolColorArray_to_mono_array(p_var->operator PoolColorArray()); ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed array of unmarshallable element type."); ERR_FAIL_V(NULL); } break; case MONO_TYPE_CLASS: { GDMonoClass *type_class = p_type.type_class; // GodotObject if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *()); } if (CACHED_CLASS(NodePath) == type_class) { return GDMonoUtils::create_managed_from(p_var->operator NodePath()); } if (CACHED_CLASS(RID) == type_class) { return GDMonoUtils::create_managed_from(p_var->operator RID()); } if (CACHED_CLASS(Dictionary) == type_class) { return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary)); } if (CACHED_CLASS(Array) == type_class) { return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array)); } } break; case MONO_TYPE_OBJECT: { // Variant switch (p_var->get_type()) { case Variant::BOOL: { MonoBoolean val = p_var->operator bool(); return BOX_BOOLEAN(val); } case Variant::INT: { int val = p_var->operator signed int(); return BOX_INT32(val); } case Variant::REAL: { #ifdef REAL_T_IS_DOUBLE double val = p_var->operator double(); return BOX_DOUBLE(val); #else float val = p_var->operator float(); return BOX_FLOAT(val); #endif } case Variant::STRING: return (MonoObject *)mono_string_from_godot(p_var->operator String()); case Variant::VECTOR2: RETURN_BOXED_STRUCT(Vector2, p_var); case Variant::RECT2: RETURN_BOXED_STRUCT(Rect2, p_var); case Variant::VECTOR3: RETURN_BOXED_STRUCT(Vector3, p_var); case Variant::TRANSFORM2D: RETURN_BOXED_STRUCT(Transform2D, p_var); case Variant::PLANE: RETURN_BOXED_STRUCT(Plane, p_var); case Variant::QUAT: RETURN_BOXED_STRUCT(Quat, p_var); case Variant::AABB: RETURN_BOXED_STRUCT(AABB, p_var); case Variant::BASIS: RETURN_BOXED_STRUCT(Basis, p_var); case Variant::TRANSFORM: RETURN_BOXED_STRUCT(Transform, p_var); case Variant::COLOR: RETURN_BOXED_STRUCT(Color, p_var); case Variant::NODE_PATH: return GDMonoUtils::create_managed_from(p_var->operator NodePath()); case Variant::_RID: return GDMonoUtils::create_managed_from(p_var->operator RID()); case Variant::OBJECT: { return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *()); } case Variant::DICTIONARY: return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary)); case Variant::ARRAY: return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array)); case Variant::POOL_BYTE_ARRAY: return (MonoObject *)PoolByteArray_to_mono_array(p_var->operator PoolByteArray()); case Variant::POOL_INT_ARRAY: return (MonoObject *)PoolIntArray_to_mono_array(p_var->operator PoolIntArray()); case Variant::POOL_REAL_ARRAY: return (MonoObject *)PoolRealArray_to_mono_array(p_var->operator PoolRealArray()); case Variant::POOL_STRING_ARRAY: return (MonoObject *)PoolStringArray_to_mono_array(p_var->operator PoolStringArray()); case Variant::POOL_VECTOR2_ARRAY: return (MonoObject *)PoolVector2Array_to_mono_array(p_var->operator PoolVector2Array()); case Variant::POOL_VECTOR3_ARRAY: return (MonoObject *)PoolVector3Array_to_mono_array(p_var->operator PoolVector3Array()); case Variant::POOL_COLOR_ARRAY: return (MonoObject *)PoolColorArray_to_mono_array(p_var->operator PoolColorArray()); default: return NULL; } break; case MONO_TYPE_GENERICINST: { MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, p_type.type_class->get_mono_type()); MonoException *exc = NULL; GDMonoUtils::IsDictionaryGenericType type_is_dict = CACHED_METHOD_THUNK(MarshalUtils, IsDictionaryGenericType); MonoBoolean is_dict = type_is_dict((MonoObject *)reftype, (MonoObject **)&exc); UNLIKELY_UNHANDLED_EXCEPTION(exc); if (is_dict) { return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), p_type.type_class); } exc = NULL; GDMonoUtils::IsArrayGenericType type_is_array = CACHED_METHOD_THUNK(MarshalUtils, IsArrayGenericType); MonoBoolean is_array = type_is_array((MonoObject *)reftype, (MonoObject **)&exc); UNLIKELY_UNHANDLED_EXCEPTION(exc); if (is_array) { return GDMonoUtils::create_managed_from(p_var->operator Array(), p_type.type_class); } } break; } break; } ERR_EXPLAIN(String() + "Attempted to convert Variant to an unmarshallable managed type. Name: \'" + p_type.type_class->get_name() + "\' Encoding: " + itos(p_type.type_encoding)); ERR_FAIL_V(NULL); }
void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_value) { #define SET_FROM_STRUCT(m_type) \ { \ GDMonoMarshal::M_##m_type from = MARSHALLED_OUT(m_type, p_value.operator ::m_type()); \ mono_field_set_value(p_object, mono_field, &from); \ } #define SET_FROM_ARRAY(m_type) \ { \ MonoArray *managed = GDMonoMarshal::m_type##_to_mono_array(p_value.operator ::m_type()); \ mono_field_set_value(p_object, mono_field, &managed); \ } switch (type.type_encoding) { case MONO_TYPE_BOOLEAN: { MonoBoolean val = p_value.operator bool(); mono_field_set_value(p_object, mono_field, &val); } break; case MONO_TYPE_CHAR: { int16_t val = p_value.operator unsigned short(); mono_field_set_value(p_object, mono_field, &val); } break; case MONO_TYPE_I1: { int8_t val = p_value.operator signed char(); mono_field_set_value(p_object, mono_field, &val); } break; case MONO_TYPE_I2: { int16_t val = p_value.operator signed short(); mono_field_set_value(p_object, mono_field, &val); } break; case MONO_TYPE_I4: { int32_t val = p_value.operator signed int(); mono_field_set_value(p_object, mono_field, &val); } break; case MONO_TYPE_I8: { int64_t val = p_value.operator int64_t(); mono_field_set_value(p_object, mono_field, &val); } break; case MONO_TYPE_U1: { uint8_t val = p_value.operator unsigned char(); mono_field_set_value(p_object, mono_field, &val); } break; case MONO_TYPE_U2: { uint16_t val = p_value.operator unsigned short(); mono_field_set_value(p_object, mono_field, &val); } break; case MONO_TYPE_U4: { uint32_t val = p_value.operator unsigned int(); mono_field_set_value(p_object, mono_field, &val); } break; case MONO_TYPE_U8: { uint64_t val = p_value.operator uint64_t(); mono_field_set_value(p_object, mono_field, &val); } break; case MONO_TYPE_R4: { float val = p_value.operator float(); mono_field_set_value(p_object, mono_field, &val); } break; case MONO_TYPE_R8: { double val = p_value.operator double(); mono_field_set_value(p_object, mono_field, &val); } break; case MONO_TYPE_STRING: { MonoString *mono_string = GDMonoMarshal::mono_string_from_godot(p_value); mono_field_set_value(p_object, mono_field, mono_string); } break; case MONO_TYPE_VALUETYPE: { GDMonoClass *tclass = type.type_class; if (tclass == CACHED_CLASS(Vector2)) { SET_FROM_STRUCT(Vector2); break; } if (tclass == CACHED_CLASS(Rect2)) { SET_FROM_STRUCT(Rect2); break; } if (tclass == CACHED_CLASS(Transform2D)) { SET_FROM_STRUCT(Transform2D); break; } if (tclass == CACHED_CLASS(Vector3)) { SET_FROM_STRUCT(Vector3); break; } if (tclass == CACHED_CLASS(Basis)) { SET_FROM_STRUCT(Basis); break; } if (tclass == CACHED_CLASS(Quat)) { SET_FROM_STRUCT(Quat); break; } if (tclass == CACHED_CLASS(Transform)) { SET_FROM_STRUCT(Transform); break; } if (tclass == CACHED_CLASS(AABB)) { SET_FROM_STRUCT(AABB); break; } if (tclass == CACHED_CLASS(Color)) { SET_FROM_STRUCT(Color); break; } if (tclass == CACHED_CLASS(Plane)) { SET_FROM_STRUCT(Plane); break; } if (mono_class_is_enum(tclass->get_mono_ptr())) { MonoType *enum_basetype = mono_class_enum_basetype(tclass->get_mono_ptr()); switch (mono_type_get_type(enum_basetype)) { case MONO_TYPE_BOOLEAN: { MonoBoolean val = p_value.operator bool(); mono_field_set_value(p_object, mono_field, &val); break; } case MONO_TYPE_CHAR: { uint16_t val = p_value.operator unsigned short(); mono_field_set_value(p_object, mono_field, &val); break; } case MONO_TYPE_I1: { int8_t val = p_value.operator signed char(); mono_field_set_value(p_object, mono_field, &val); break; } case MONO_TYPE_I2: { int16_t val = p_value.operator signed short(); mono_field_set_value(p_object, mono_field, &val); break; } case MONO_TYPE_I4: { int32_t val = p_value.operator signed int(); mono_field_set_value(p_object, mono_field, &val); break; } case MONO_TYPE_I8: { int64_t val = p_value.operator int64_t(); mono_field_set_value(p_object, mono_field, &val); break; } case MONO_TYPE_U1: { uint8_t val = p_value.operator unsigned char(); mono_field_set_value(p_object, mono_field, &val); break; } case MONO_TYPE_U2: { uint16_t val = p_value.operator unsigned short(); mono_field_set_value(p_object, mono_field, &val); break; } case MONO_TYPE_U4: { uint32_t val = p_value.operator unsigned int(); mono_field_set_value(p_object, mono_field, &val); break; } case MONO_TYPE_U8: { uint64_t val = p_value.operator uint64_t(); mono_field_set_value(p_object, mono_field, &val); break; } default: { ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed enum value of unmarshallable base type."); ERR_FAIL(); } } break; } ERR_EXPLAIN(String() + "Attempted to set the value of a field of unmarshallable type: " + tclass->get_name()); ERR_FAIL(); } break; case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { MonoArrayType *array_type = mono_type_get_array_type(type.type_class->get_mono_type()); if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) { SET_FROM_ARRAY(Array); break; } if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) { SET_FROM_ARRAY(PoolByteArray); break; } if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) { SET_FROM_ARRAY(PoolIntArray); break; } if (array_type->eklass == REAL_T_MONOCLASS) { SET_FROM_ARRAY(PoolRealArray); break; } if (array_type->eklass == CACHED_CLASS_RAW(String)) { SET_FROM_ARRAY(PoolStringArray); break; } if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) { SET_FROM_ARRAY(PoolVector2Array); break; } if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) { SET_FROM_ARRAY(PoolVector3Array); break; } if (array_type->eklass == CACHED_CLASS_RAW(Color)) { SET_FROM_ARRAY(PoolColorArray); break; } ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed array of unmarshallable element type."); ERR_FAIL(); } break; case MONO_TYPE_CLASS: { GDMonoClass *type_class = type.type_class; // GodotObject if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { MonoObject *managed = GDMonoUtils::unmanaged_get_managed(p_value.operator Object *()); mono_field_set_value(p_object, mono_field, managed); break; } if (CACHED_CLASS(NodePath) == type_class) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath()); mono_field_set_value(p_object, mono_field, managed); break; } if (CACHED_CLASS(RID) == type_class) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator RID()); mono_field_set_value(p_object, mono_field, managed); break; } if (CACHED_CLASS(Dictionary) == type_class) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary)); mono_field_set_value(p_object, mono_field, managed); break; } if (CACHED_CLASS(Array) == type_class) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array)); mono_field_set_value(p_object, mono_field, managed); break; } ERR_EXPLAIN(String() + "Attempted to set the value of a field of unmarshallable type: " + type_class->get_name()); ERR_FAIL(); } break; case MONO_TYPE_OBJECT: { // Variant switch (p_value.get_type()) { case Variant::BOOL: { MonoBoolean val = p_value.operator bool(); mono_field_set_value(p_object, mono_field, &val); } break; case Variant::INT: { int32_t val = p_value.operator signed int(); mono_field_set_value(p_object, mono_field, &val); } break; case Variant::REAL: { #ifdef REAL_T_IS_DOUBLE double val = p_value.operator double(); mono_field_set_value(p_object, mono_field, &val); #else float val = p_value.operator float(); mono_field_set_value(p_object, mono_field, &val); #endif } break; case Variant::STRING: { MonoString *mono_string = GDMonoMarshal::mono_string_from_godot(p_value); mono_field_set_value(p_object, mono_field, mono_string); } break; case Variant::VECTOR2: { SET_FROM_STRUCT(Vector2); } break; case Variant::RECT2: { SET_FROM_STRUCT(Rect2); } break; case Variant::VECTOR3: { SET_FROM_STRUCT(Vector3); } break; case Variant::TRANSFORM2D: { SET_FROM_STRUCT(Transform2D); } break; case Variant::PLANE: { SET_FROM_STRUCT(Plane); } break; case Variant::QUAT: { SET_FROM_STRUCT(Quat); } break; case Variant::AABB: { SET_FROM_STRUCT(AABB); } break; case Variant::BASIS: { SET_FROM_STRUCT(Basis); } break; case Variant::TRANSFORM: { SET_FROM_STRUCT(Transform); } break; case Variant::COLOR: { SET_FROM_STRUCT(Color); } break; case Variant::NODE_PATH: { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath()); mono_field_set_value(p_object, mono_field, managed); } break; case Variant::_RID: { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator RID()); mono_field_set_value(p_object, mono_field, managed); } break; case Variant::OBJECT: { MonoObject *managed = GDMonoUtils::unmanaged_get_managed(p_value.operator Object *()); mono_field_set_value(p_object, mono_field, managed); break; } case Variant::DICTIONARY: { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary)); mono_field_set_value(p_object, mono_field, managed); } break; case Variant::ARRAY: { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array)); mono_field_set_value(p_object, mono_field, managed); } break; case Variant::POOL_BYTE_ARRAY: { SET_FROM_ARRAY(PoolByteArray); } break; case Variant::POOL_INT_ARRAY: { SET_FROM_ARRAY(PoolIntArray); } break; case Variant::POOL_REAL_ARRAY: { SET_FROM_ARRAY(PoolRealArray); } break; case Variant::POOL_STRING_ARRAY: { SET_FROM_ARRAY(PoolStringArray); } break; case Variant::POOL_VECTOR2_ARRAY: { SET_FROM_ARRAY(PoolVector2Array); } break; case Variant::POOL_VECTOR3_ARRAY: { SET_FROM_ARRAY(PoolVector3Array); } break; case Variant::POOL_COLOR_ARRAY: { SET_FROM_ARRAY(PoolColorArray); } break; default: break; } } break; case MONO_TYPE_GENERICINST: { MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, type.type_class->get_mono_type()); MonoException *exc = NULL; GDMonoUtils::IsDictionaryGenericType type_is_dict = CACHED_METHOD_THUNK(MarshalUtils, IsDictionaryGenericType); MonoBoolean is_dict = type_is_dict((MonoObject *)reftype, (MonoObject **)&exc); UNLIKELY_UNHANDLED_EXCEPTION(exc); if (is_dict) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), type.type_class); mono_field_set_value(p_object, mono_field, managed); break; } exc = NULL; GDMonoUtils::IsArrayGenericType type_is_array = CACHED_METHOD_THUNK(MarshalUtils, IsArrayGenericType); MonoBoolean is_array = type_is_array((MonoObject *)reftype, (MonoObject **)&exc); UNLIKELY_UNHANDLED_EXCEPTION(exc); if (is_array) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), type.type_class); mono_field_set_value(p_object, mono_field, managed); break; } } break; default: { ERR_PRINTS(String() + "Attempted to set the value of a field of unexpected type encoding: " + itos(type.type_encoding)); } break; } #undef SET_FROM_ARRAY_AND_BREAK #undef SET_FROM_STRUCT_AND_BREAK }
const struct type *type_array_values(const struct type *ty) { assert(type_is_array(ty)); return ty->array_type.values; }
static tree_t elab_signal_port(tree_t arch, tree_t formal, tree_t param, map_list_t **maps) { assert(tree_kind(param) == T_PARAM); tree_t actual = tree_value(param); // NULL name means associate the whole port tree_t name = NULL; if (tree_subkind(param) == P_NAMED) { tree_t n = tree_name(param); if (tree_kind(n) != T_REF) name = n; } const bool partial_map = name != NULL; switch (tree_kind(actual)) { case T_REF: case T_ARRAY_REF: case T_ARRAY_SLICE: case T_RECORD_REF: { // Replace the formal port with a signal and connect its nets to // those of the actual tree_t ref = actual; tree_kind_t ref_kind; while ((ref_kind = tree_kind(ref)) != T_REF) { if ((ref_kind == T_AGGREGATE) || (ref_kind == T_LITERAL)) return actual; else ref = tree_value(ref); } tree_t decl = tree_ref(ref); tree_kind_t decl_kind = tree_kind(decl); if (decl_kind == T_SIGNAL_DECL) { tree_t s = elab_port_to_signal(arch, formal, actual); if (partial_map) tree_add_attr_int(s, partial_map_i, 1); map_list_t *m = xmalloc(sizeof(map_list_t)); m->next = *maps; m->formal = formal; m->actual = actual; m->signal = s; m->name = name; *maps = m; return s; } else if (decl_kind == T_PORT_DECL) return NULL; // Port was OPEN at a higher level else return actual; } case T_LITERAL: case T_AGGREGATE: { type_t formal_type = tree_type(formal); if (!type_is_unconstrained(formal_type)) tree_set_type(actual, formal_type); return actual; } case T_OPEN: return NULL; case T_TYPE_CONV: // Only allow simple array type conversions for now { type_t to_type = tree_type(actual); type_t from_type = tree_type(tree_value(tree_param(actual, 0))); if (type_is_array(to_type) && type_is_array(from_type)) return actual; else fatal_at(tree_loc(actual), "sorry, this form of type conversion " "is not supported as an actual"); } default: fatal_at(tree_loc(actual), "tree %s not supported as actual", tree_kind_str(tree_kind(actual))); } }
const struct expression *type_array_size(const struct type *ty) { assert(type_is_array(ty)); return ty->array_type.array_size; }