static void _emit_decode_one (const lcmgen_t *lcm, FILE *f, lcm_struct_t *ls, lcm_member_t *lm, const char *accessor, int indent, const char *sfx) { const char *tn = lm->type->lctypename; const char *mn = lm->membername; const char *sn = lm->type->shortname; if (!strcmp ("string", tn)) { emit (indent, "__%s_len = struct.unpack('>I', buf.read(4))[0]", mn); emit (indent, "%sbuf.read(__%s_len)[:-1].decode('utf-8', 'replace')%s", accessor, mn, sfx); } else if (!strcmp ("byte", tn)) { emit (indent, "%sstruct.unpack('B', buf.read(1))[0]%s", accessor, sfx); } else if (!(strcmp ("boolean", tn))) { emit (indent, "%sbool(struct.unpack('b', buf.read(1))[0])%s", accessor, sfx); } else if (!strcmp ("int8_t", tn)) { emit (indent, "%sstruct.unpack('b', buf.read(1))[0]%s", accessor, sfx); } else if (!strcmp ("int16_t", tn)) { emit (indent, "%sstruct.unpack('>h', buf.read(2))[0]%s", accessor, sfx); } else if (!strcmp ("int32_t", tn)) { emit (indent, "%sstruct.unpack('>i', buf.read(4))[0]%s", accessor, sfx); } else if (!strcmp ("int64_t", tn)) { emit (indent, "%sstruct.unpack('>q', buf.read(8))[0]%s", accessor, sfx); } else if (!strcmp ("float", tn)) { emit (indent, "%sstruct.unpack('>f', buf.read(4))[0]%s", accessor, sfx); } else if (!strcmp ("double", tn)) { emit (indent, "%sstruct.unpack('>d', buf.read(8))[0]%s", accessor, sfx); } else { if (is_same_type (lm->type, ls->structname)) { emit (indent, "%s%s._decode_one(buf)%s", accessor, sn, sfx); } else { emit (indent, "%s%s._decode_one(buf)%s", accessor, tn, sfx); } } }
StoreVariableStatement* NodeBuilder::store_var(VariableSymbol* dst, Expression* src) { if (!is_same_type(dst->get_type(), src->get_result_type())) { trash(dst); trash(src); SUIF_THROW(SuifException(String("Type mismatch in StoreVariableStatement for ") + to_id_string(dst) + " from expression " + to_id_string(src))); } return create_store_variable_statement(_suif_env, dst, src); }
StoreStatement* NodeBuilder::store(Expression* dst_addr, Expression* src_addr) { if (!is_same_type(get_pointed_to_type(dst_addr->get_result_type()), src_addr->get_result_type())) { trash(dst_addr); trash(src_addr); SUIF_THROW(SuifException(String("Type error in StoreStatement from ") + to_id_string(src_addr) + " to " + to_id_string(dst_addr))); } return create_store_statement(_suif_env, src_addr, dst_addr); }
static void emit_python_fingerprint (const lcmgen_t *lcm, FILE *f, lcm_struct_t *ls) { const char *sn = ls->structname->shortname; emit (1, "_hash = None"); emit (1, "def _get_hash_recursive(parents):"); emit (2, "if %s in parents: return 0", sn); for (unsigned int m = 0; m < ls->members->len; m++) { lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m); if (! lcm_is_primitive_type (lm->type->lctypename)) { emit (2, "newparents = parents + [%s]", sn); break; } } emit_start (2, "tmphash = (0x%"PRIx64, ls->hash); for (unsigned int m = 0; m < ls->members->len; m++) { lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m); const char *msn = lm->type->shortname; if (! lcm_is_primitive_type (lm->type->lctypename)) { const char *ghr = "_get_hash_recursive(newparents)"; if (is_same_type (lm->type, ls->structname)) { emit_continue ("+ %s.%s", msn, ghr); } else if (is_same_package (lm->type, ls->structname)) { emit_continue ("+ %s.%s.%s", msn, msn, ghr); } else { emit_continue ("+ %s.%s", lm->type->lctypename, ghr); } } } emit_end (") & 0xffffffffffffffff"); emit (2, "tmphash = (((tmphash<<1)&0xffffffffffffffff) + " "(tmphash>>63)) & 0xffffffffffffffff"); emit (2, "return tmphash"); emit (1, "_get_hash_recursive = staticmethod(_get_hash_recursive)"); emit (1, "_packed_fingerprint = None"); emit (0, ""); emit (1, "def _get_packed_fingerprint():"); emit (2, "if %s._packed_fingerprint is None:", sn); emit (3, "%s._packed_fingerprint = struct.pack(\">Q\", " "%s._get_hash_recursive([]))", sn, sn); emit (2, "return %s._packed_fingerprint", sn); emit (1, "_get_packed_fingerprint = staticmethod(_get_packed_fingerprint)"); fprintf (f, "\n"); }
static void emit_lua_fingerprint (const lcmgen_t *lcm, FILE *f, lcm_struct_t *ls) { const char *sn = ls->structname->shortname; emit(0, "function %s._get_hash_recursive(parents)", sn); emit(0, ""); emit(0, " local newparents = {}"); emit(0, ""); emit(0, " for _, v in ipairs(parents) do"); emit(0, " if v == %s then return lcm._hash.new('0x0') end", sn); emit(0, " table.insert(newparents, v)"); emit(0, " end"); emit(0, ""); emit(0, " table.insert(newparents, %s)", sn); emit(0, ""); emit(0, " local hash = lcm._hash.new('0x%"PRIx64"')", ls->hash); // add all substruct hashes for (unsigned int m = 0; m < ls->members->len; m++) { lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m); const char *msn = lm->type->shortname; if (! lcm_is_primitive_type(lm->type->lctypename)) { const char *ghr = "_get_hash_recursive(newparents)"; // XXX this might need a touch up, not sure about intra-module names if (is_same_type(lm->type, ls->structname)) { emit(0, " + %s.%s", msn, ghr); } else { char *variablename = escape_typename_to_variablename(lm->type->lctypename); emit(0, " + %s.%s", variablename, ghr); g_free(variablename); } } } emit(0, " hash:rotate(1)"); emit(0, ""); emit(0, " return hash"); emit(0, "end"); emit(0, ""); emit(0, "%s._packed_fingerprint = lcm._pack.pack('>X', %s._get_hash_recursive({}))", sn, sn); emit(0, ""); }
static void _emit_decode_one (const lcmgen_t *lcm, FILE *f, lcm_struct_t *ls, lcm_member_t *lm, const char *accessor, int indent) { // XXX probably needs some rework const char *tn = lm->type->lctypename; const char *mn = lm->membername; const char *sn = lm->type->shortname; if (!strcmp ("string", tn)) { emit (indent, "local __%s_tmpstrlen = lcm._pack.unpack('>I', data:read(4))", mn); emit (indent, "%s = lcm._pack.prepare_string(data:read(__%s_tmpstrlen))", accessor, mn); } else if (!strcmp ("byte", tn)) { emit (indent, "%s = lcm._pack.unpack('>B', data:read(1))", accessor); } else if (!strcmp ("int8_t", tn)) { emit (indent, "%s = lcm._pack.unpack('>b', data:read(1))", accessor); } else if (!strcmp ("boolean", tn)) { emit (indent, "%s = lcm._pack.unpack('>?', data:read(1))", accessor); } else if (!strcmp ("int16_t", tn)) { emit (indent, "%s = lcm._pack.unpack('>h', data:read(2))", accessor); } else if (!strcmp ("int32_t", tn)) { emit (indent, "%s = lcm._pack.unpack('>i', data:read(4))", accessor); } else if (!strcmp ("int64_t", tn)) { emit (indent, "%s = lcm._pack.unpack('>q', data:read(8))", accessor); } else if (!strcmp ("float", tn)) { emit (indent, "%s = lcm._pack.unpack('>f', data:read(4))", accessor); } else if (!strcmp ("double", tn)) { emit (indent, "%s = lcm._pack.unpack('>d', data:read(8))", accessor); } else { // XXX not really sure about these... // check if same type if (is_same_type(lm->type, ls->structname)) { emit (indent, "%s = %s._decode_one(data)", accessor, sn); } else { char *variablename = escape_typename_to_variablename(tn); emit (indent, "%s = %s._decode_one(data)", accessor, variablename); g_free(variablename); } } }
static void _emit_encode_one (const lcmgen_t *lcm, FILE *f, lcm_struct_t *ls, lcm_member_t *lm, const char *accessor, int indent) { const char *tn = lm->type->lctypename; const char *mn = lm->membername; if (!strcmp ("string", tn)) { emit (indent, "__%s_encoded = %s.encode('utf-8')", mn, accessor); emit (indent, "buf.write(struct.pack('>I', len(__%s_encoded)+1))", mn); emit (indent, "buf.write(__%s_encoded)", mn); emit (indent, "buf.write(\"\\0\")"); } else if (!strcmp ("byte", tn)) { emit (indent, "buf.write(struct.pack('B', %s))", accessor); } else if (!strcmp ("int8_t", tn) || !strcmp ("boolean", tn)) { emit (indent, "buf.write(struct.pack('b', %s))", accessor); } else if (!strcmp ("int16_t", tn)) { emit (indent, "buf.write(struct.pack('>h', %s))", accessor); } else if (!strcmp ("int32_t", tn)) { emit (indent, "buf.write(struct.pack('>i', %s))", accessor); } else if (!strcmp ("int64_t", tn)) { emit (indent, "buf.write(struct.pack('>q', %s))", accessor); } else if (!strcmp ("float", tn)) { emit (indent, "buf.write(struct.pack('>f', %s))", accessor); } else if (!strcmp ("double", tn)) { emit (indent, "buf.write(struct.pack('>d', %s))", accessor); } else { if(is_same_type(lm->type, ls->structname)) { emit(indent, "assert %s._get_packed_fingerprint() == %s._get_packed_fingerprint()", accessor, lm->type->shortname); } else if(is_same_package(ls->structname, lm->type)) { emit(indent, "assert %s._get_packed_fingerprint() == %s.%s._get_packed_fingerprint()", accessor, lm->type->shortname, lm->type->shortname); } else { emit(indent, "assert %s._get_packed_fingerprint() == %s.%s._get_packed_fingerprint()", accessor, lm->type->lctypename, lm->type->shortname); } emit (indent, "%s._encode_one(buf)", accessor); } }
void test_overloads(T, const char* name) { // // Probe known and suspected problems with the std lib Math functions. // std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" "Math function overload information for type " << name << std::endl; // // Are the math functions overloaded for type T, // or do we just get double versions? // bool r = is_same_type(std::fabs(T(0)), T(0)); r &= is_same_type(std::sqrt(T(0)), T(0)); r &= is_same_type(std::sin(T(0)), T(0)); if(r) std::cout << "The Math functions are overloaded for type " << name << std::endl; else std::cout << "CAUTION: The Math functions are NOT overloaded for type " << name << std::endl; // // Check that a few of the functions work OK, we do this because if these // are implemented as double precision internally then we can get // overflow or underflow when passing arguments of other types. // r = (std::fabs((std::numeric_limits<T>::max)()) == (std::numeric_limits<T>::max)()); r &= (std::fabs(-(std::numeric_limits<T>::max)()) == (std::numeric_limits<T>::max)()); r &= (std::fabs((std::numeric_limits<T>::min)()) == (std::numeric_limits<T>::min)()); r &= (std::fabs(-(std::numeric_limits<T>::min)()) == (std::numeric_limits<T>::min)()); if(r) std::cout << "std::fabs looks OK for type " << name << std::endl; else std::cout << "CAUTION: std::fabs is broken for type " << name << std::endl; // // abs not overloaded for real arguments with VC6 (and others?) // r = (std::abs((std::numeric_limits<T>::max)()) == (std::numeric_limits<T>::max)()); r &= (std::abs(-(std::numeric_limits<T>::max)()) == (std::numeric_limits<T>::max)()); r &= (std::abs((std::numeric_limits<T>::min)()) == (std::numeric_limits<T>::min)()); r &= (std::abs(-(std::numeric_limits<T>::min)()) == (std::numeric_limits<T>::min)()); if(r) std::cout << "std::abs looks OK for type " << name << std::endl; else std::cout << "CAUTION: std::abs is broken for type " << name << std::endl; // // std::sqrt on FreeBSD converts long double arguments to double leading to // overflow/underflow: // r = (std::sqrt((std::numeric_limits<T>::max)()) < (std::numeric_limits<T>::max)()); if(r) std::cout << "std::sqrt looks OK for type " << name << std::endl; else std::cout << "CAUTION: std::sqrt is broken for type " << name << std::endl; // // Sanity check for atan2: verify that it returns arguments in the correct // range and not just atan(x/y). // static const T half_pi = static_cast<T>(1.57079632679489661923132169163975144L); T val = std::atan2(T(-1), T(-1)); r = -half_pi > val; val = std::atan2(T(1), T(-1)); r &= half_pi < val; val = std::atan2(T(1), T(1)); r &= (val > 0) && (val < half_pi); val = std::atan2(T(-1), T(1)); r &= (val < 0) && (val > -half_pi); if(r) std::cout << "std::atan2 looks OK for type " << name << std::endl; else std::cout << "CAUTION: std::atan2 is broken for type " << name << std::endl; }