Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
console.cpp
Go to the documentation of this file.
3#include <fc/uint128.hpp>
4
5namespace sysio { namespace chain { namespace webassembly {
6
7 template <typename Ctx, typename F>
8 inline static void predicated_print(Ctx& context, F&& print_func) {
9 if (UNLIKELY(context.control.contracts_console()))
10 print_func();
11 }
12
13 // Kept as intrinsic rather than implementing on WASM side (using prints_l and strlen) because strlen is faster on native side.
14 // TODO predicate these for ignore
16 predicated_print(context,
17 [&]() { context.console_append( static_cast<const char*>(str.data()) ); });
18 }
19
21 predicated_print(context,
22 [&]() { context.console_append(std::string_view(str.data(), str.size())); });
23 }
24
26 predicated_print(context,
27 [&]() {
28 std::ostringstream oss;
29 oss << val;
30 context.console_append( oss.str() );
31 });
32 }
33
35 predicated_print(context,
36 [&]() {
37 std::ostringstream oss;
38 oss << val;
39 context.console_append( oss.str() );
40 });
41 }
42
44 predicated_print(context,
45 [&]() {
46 bool is_negative = (*val < 0);
47 unsigned __int128 val_magnitude;
48
49 if( is_negative )
50 val_magnitude = static_cast<unsigned __int128>(-*val); // Works even if val is at the lowest possible value of a int128_t
51 else
52 val_magnitude = static_cast<unsigned __int128>(*val);
53
54 fc::uint128 v(val_magnitude>>64, static_cast<uint64_t>(val_magnitude) );
55
56 string s;
57 if( is_negative ) {
58 s += '-';
59 }
60 s += fc::variant(v).get_string();
61
62 context.console_append( s );
63 });
64 }
65
67 predicated_print(context,
68 [&]() {
69 fc::uint128 v(*val>>64, static_cast<uint64_t>(*val) );
70 context.console_append(fc::variant(v).get_string());
71 });
72 }
73
75 predicated_print(context,
76 [&]() {
77 // Assumes float representation on native side is the same as on the WASM side
78 std::ostringstream oss;
79 oss.setf( std::ios::scientific, std::ios::floatfield );
80 oss.precision( std::numeric_limits<float>::digits10 );
81 oss << ::from_softfloat32(val);
82 context.console_append( oss.str() );
83 });
84 }
85
87 predicated_print(context,
88 [&]() {
89 // Assumes double representation on native side is the same as on the WASM side
90 std::ostringstream oss;
91 oss.setf( std::ios::scientific, std::ios::floatfield );
92 oss.precision( std::numeric_limits<double>::digits10 );
93 oss << ::from_softfloat64(val);
94 context.console_append( oss.str() );
95 });
96 }
97
99 /*
100 * Native-side long double uses an 80-bit extended-precision floating-point number.
101 * The easiest solution for now was to use the Berkeley softfloat library to round the 128-bit
102 * quadruple-precision floating-point number to an 80-bit extended-precision floating-point number
103 * (losing precision) which then allows us to simply cast it into a long double for printing purposes.
104 *
105 * Later we might find a better solution to print the full quadruple-precision floating-point number.
106 * Maybe with some compilation flag that turns long double into a quadruple-precision floating-point number,
107 * or maybe with some library that allows us to print out quadruple-precision floating-point numbers without
108 * having to deal with long doubles at all.
109 */
110
111 predicated_print(context,
112 [&]() {
113 std::ostringstream oss;
114 oss.setf( std::ios::scientific, std::ios::floatfield );
115
116#ifdef __x86_64__
117 oss.precision( std::numeric_limits<long double>::digits10 );
118 extFloat80_t val_approx;
119 f128M_to_extF80M(val.get(), &val_approx);
120 long double _val;
121 std::memcpy((char*)&_val, (char*)&val_approx, sizeof(long double));
122 oss << _val;
123#else
124 oss.precision( std::numeric_limits<double>::digits10 );
125 double val_approx = from_softfloat64( f128M_to_f64(val.get()) );
126 oss << val_approx;
127#endif
128 context.console_append( oss.str() );
129 });
130 }
131
133 predicated_print(context, [&]() { context.console_append(value.to_string()); });
134 }
135
137 predicated_print(context, [&]() { context.console_append(fc::to_hex(data.data(), data.size())); });
138 }
139}}} // ns sysio::chain::webassembly
an implementation of 128 bit unsigned integer
Definition uint128.hpp:22
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition variant.hpp:191
const string & get_string() const
Definition variant.cpp:606
void printhex(legacy_span< const char > data)
Definition console.cpp:136
void prints_l(legacy_span< const char > str)
Definition console.cpp:20
void prints(null_terminated_ptr str)
Definition console.cpp:15
void printui128(legacy_ptr< const unsigned __int128 > val)
Definition console.cpp:66
void printi128(legacy_ptr< const __int128 > val)
Definition console.cpp:43
void printqf(legacy_ptr< const float128_t > val)
Definition console.cpp:98
#define UNLIKELY(x)
fc::string to_hex(const char *d, uint32_t s)
Definition hex.cpp:17
#define value
Definition pkcs11.h:157
void f128M_to_extF80M(const float128_t *aPtr, extFloat80_t *zPtr)
float64_t f128M_to_f64(const float128_t *aPtr)
double from_softfloat64(float64_t d)
float from_softfloat32(float32_t f)
signed __int64 int64_t
Definition stdint.h:135
unsigned __int64 uint64_t
Definition stdint.h:136
Immutable except for fc::from_variant.
Definition name.hpp:43
char * s