Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
sys-vm.cpp
Go to the documentation of this file.
7//sys-vm includes
8#include <sysio/vm/backend.hpp>
10#ifdef SYSIO_SYS_VM_OC_RUNTIME_ENABLED
12#endif
13#include <boost/hana/string.hpp>
14#include <boost/hana/equal.hpp>
15
16namespace sysio { namespace chain { namespace webassembly { namespace eos_vm_runtime {
17
18using namespace sysio::vm;
19
21
22namespace {
23
24 struct checktime_watchdog {
25 checktime_watchdog(transaction_checktime_timer& timer) : _timer(timer) {}
26 template<typename F>
27 struct guard {
28 guard(transaction_checktime_timer& timer, F&& func)
29 : _timer(timer), _func(static_cast<F&&>(func)) {
30 _timer.set_expiration_callback(&callback, this);
31 if(_timer.expired) {
32 _func(); // it's harmless if _func is invoked twice
33 }
34 }
35 ~guard() {
36 _timer.set_expiration_callback(nullptr, nullptr);
37 }
38 static void callback(void* data) {
39 guard* self = static_cast<guard*>(data);
40 self->_func();
41 }
44 };
45 template<typename F>
46 guard<F> scoped_run(F&& func) {
47 return guard{_timer, static_cast<F&&>(func)};
48 }
50 };
51}
52
53// Used on setcode. Must not reject anything that WAVM accepts
54// For the moment, this runs after WAVM validation, as I am not
55// sure that sys-vm will replicate WAVM's parsing exactly.
57 static constexpr bool forbid_export_mutable_globals = false;
58 static constexpr bool allow_code_after_function_end = true;
59 static constexpr bool allow_u32_limits_flags = true;
60 static constexpr bool allow_invalid_empty_local_set = true;
61 static constexpr bool allow_zero_blocktype = true;
62};
63
64void validate(const bytes& code, const whitelisted_intrinsics_type& intrinsics) {
65 wasm_code_ptr code_ptr((uint8_t*)code.data(), code.size());
66 try {
67 eos_vm_null_backend_t<setcode_options> bkend(code_ptr, code.size(), nullptr);
68 // check import signatures
70 // check that the imports are all currently enabled
71 const auto& imports = bkend.get_module().imports;
72 for(std::uint32_t i = 0; i < imports.size(); ++i) {
73 SYS_ASSERT(std::string_view((char*)imports[i].module_str.raw(), imports[i].module_str.size()) == "env" &&
74 is_intrinsic_whitelisted(intrinsics, std::string_view((char*)imports[i].field_str.raw(), imports[i].field_str.size())),
75 wasm_serialization_error, "${module}.${fn} unresolveable",
76 ("module", std::string((char*)imports[i].module_str.raw(), imports[i].module_str.size()))
77 ("fn", std::string((char*)imports[i].field_str.raw(), imports[i].field_str.size())));
78 }
79 } catch(vm::exception& e) {
80 SYS_THROW(wasm_serialization_error, e.detail());
81 }
82}
83
84void validate( const bytes& code, const wasm_config& cfg, const whitelisted_intrinsics_type& intrinsics ) {
85 SYS_ASSERT(code.size() <= cfg.max_module_bytes, wasm_serialization_error, "Code too large");
86 wasm_code_ptr code_ptr((uint8_t*)code.data(), code.size());
87 try {
88 eos_vm_null_backend_t<wasm_config> bkend(code_ptr, code.size(), nullptr, cfg);
89 // check import signatures
91 // check that the imports are all currently enabled
92 const auto& imports = bkend.get_module().imports;
93 for(std::uint32_t i = 0; i < imports.size(); ++i) {
94 SYS_ASSERT(std::string_view((char*)imports[i].module_str.raw(), imports[i].module_str.size()) == "env" &&
95 is_intrinsic_whitelisted(intrinsics, std::string_view((char*)imports[i].field_str.raw(), imports[i].field_str.size())),
96 wasm_serialization_error, "${module}.${fn} unresolveable",
97 ("module", std::string((char*)imports[i].module_str.raw(), imports[i].module_str.size()))
98 ("fn", std::string((char*)imports[i].field_str.raw(), imports[i].field_str.size())));
99 }
100 // check apply
101 uint32_t apply_idx = bkend.get_module().get_exported_function("apply");
102 SYS_ASSERT(apply_idx < std::numeric_limits<uint32_t>::max(), wasm_serialization_error, "apply not exported");
103 const vm::func_type& apply_type = bkend.get_module().get_function_type(apply_idx);
104 SYS_ASSERT((apply_type == vm::host_function{{vm::i64, vm::i64, vm::i64}, {}}), wasm_serialization_error, "apply has wrong type");
105 } catch(vm::exception& e) {
106 SYS_THROW(wasm_serialization_error, e.detail());
107 }
108}
109
110// Be permissive on apply.
112 std::uint32_t max_pages = wasm_constraints::maximum_linear_memory/wasm_constraints::wasm_page_size;
114 static constexpr bool forbid_export_mutable_globals = false;
115 static constexpr bool allow_code_after_function_end = false;
116 static constexpr bool allow_u32_limits_flags = true;
117 static constexpr bool allow_invalid_empty_local_set = true;
118 static constexpr bool allow_zero_blocktype = true;
119};
120
121template<typename Impl>
124 public:
125
126 eos_vm_instantiated_module(eos_vm_runtime<Impl>* runtime, std::unique_ptr<backend_t> mod) :
127 _runtime(runtime),
128 _instantiated_module(std::move(mod)) {}
129
130 void apply(apply_context& context) override {
131 _instantiated_module->set_wasm_allocator(&context.control.get_wasm_allocator());
132 _runtime->_bkend = _instantiated_module.get();
133 apply_options opts;
134 if(context.control.is_builtin_activated(builtin_protocol_feature_t::configurable_wasm_limits)) {
135 const wasm_config& config = context.control.get_global_properties().wasm_configuration;
136 opts = {config.max_pages, config.max_call_depth};
137 }
138 auto fn = [&]() {
140 _runtime->_bkend->initialize(&iface, opts);
141 _runtime->_bkend->call(
142 iface, "env", "apply",
143 context.get_receiver().to_uint64_t(),
144 context.get_action().account.to_uint64_t(),
145 context.get_action().name.to_uint64_t());
146 };
147 try {
148 checktime_watchdog wd(context.trx_context.transaction_timer);
149 _runtime->_bkend->timed_run(wd, fn);
150 } catch(sysio::vm::timeout_exception&) {
151 context.trx_context.checktime();
152 } catch(sysio::vm::wasm_memory_exception& e) {
153 FC_THROW_EXCEPTION(wasm_execution_error, "access violation");
154 } catch(sysio::vm::exception& e) {
155 FC_THROW_EXCEPTION(wasm_execution_error, "sys-vm system failure");
156 }
157 _runtime->_bkend = nullptr;
158 }
159
160 private:
161 eos_vm_runtime<Impl>* _runtime;
162 std::unique_ptr<backend_t> _instantiated_module;
163};
164
165#ifdef __x86_64__
166class eos_vm_profiling_module : public wasm_instantiated_module_interface {
168 public:
169 eos_vm_profiling_module(std::unique_ptr<backend_t> mod, const char * code, std::size_t code_size) :
170 _instantiated_module(std::move(mod)),
171 _original_code(code, code + code_size) {}
172
173
174 void apply(apply_context& context) override {
175 _instantiated_module->set_wasm_allocator(&context.control.get_wasm_allocator());
176 apply_options opts;
177 if(context.control.is_builtin_activated(builtin_protocol_feature_t::configurable_wasm_limits)) {
178 const wasm_config& config = context.control.get_global_properties().wasm_configuration;
179 opts = {config.max_pages, config.max_call_depth};
180 }
181 auto fn = [&]() {
183 _instantiated_module->initialize(&iface, opts);
184 _instantiated_module->call(
185 iface, "env", "apply",
186 context.get_receiver().to_uint64_t(),
187 context.get_action().account.to_uint64_t(),
188 context.get_action().name.to_uint64_t());
189 };
190 profile_data* prof = start(context);
191 try {
192 scoped_profile profile_runner(prof);
193 checktime_watchdog wd(context.trx_context.transaction_timer);
194 _instantiated_module->timed_run(wd, fn);
195 } catch(sysio::vm::timeout_exception&) {
196 context.trx_context.checktime();
197 } catch(sysio::vm::wasm_memory_exception& e) {
198 FC_THROW_EXCEPTION(wasm_execution_error, "access violation");
199 } catch(sysio::vm::exception& e) {
200 FC_THROW_EXCEPTION(wasm_execution_error, "sys-vm system failure");
201 }
202 }
203
204 void fast_shutdown() override {
205 _prof.clear();
206 }
207
209 name account = context.get_receiver();
210 if(!context.control.is_profiling(account)) return nullptr;
211 if(auto it = _prof.find(account); it != _prof.end()) {
212 return it->second.get();
213 } else {
214 auto code_sequence = context.control.db().get<account_metadata_object, by_name>(account).code_sequence;
215 std::string basename = account.to_string() + "." + std::to_string(code_sequence);
216 auto prof = std::make_unique<profile_data>(basename + ".profile", *_instantiated_module);
217 auto [pos,_] = _prof.insert(std::pair{ account, std::move(prof)});
218 std::ofstream outfile(basename + ".wasm");
219 outfile.write(_original_code.data(), _original_code.size());
220 return pos->second.get();
221 }
222 return nullptr;
223 }
224
225 private:
226
227 std::unique_ptr<backend_t> _instantiated_module;
228 boost::container::flat_map<name, std::unique_ptr<profile_data>> _prof;
229 std::vector<char> _original_code;
230};
231#endif
232
233template<typename Impl>
235
236template<typename Impl>
240
241template<typename Impl>
242std::unique_ptr<wasm_instantiated_module_interface> eos_vm_runtime<Impl>::instantiate_module(const char* code_bytes, size_t code_size, std::vector<uint8_t>,
243 const digest_type&, const uint8_t&, const uint8_t&) {
244
246 try {
247 wasm_code_ptr code((uint8_t*)code_bytes, code_size);
248 apply_options options = { .max_pages = 65536,
249 .max_call_depth = 0 };
250 std::unique_ptr<backend_t> bkend = std::make_unique<backend_t>(code, code_size, nullptr, options);
252 return std::make_unique<eos_vm_instantiated_module<Impl>>(this, std::move(bkend));
253 } catch(sysio::vm::exception& e) {
254 FC_THROW_EXCEPTION(wasm_execution_error, "Error building sys-vm interp: ${e}", ("e", e.what()));
255 }
256}
257
259#ifdef __x86_64__
260template class eos_vm_runtime<sysio::vm::jit>;
261
263
265 throw wasm_exit{};
266}
267
268std::unique_ptr<wasm_instantiated_module_interface> eos_vm_profile_runtime::instantiate_module(const char* code_bytes, size_t code_size, std::vector<uint8_t>,
269 const digest_type&, const uint8_t&, const uint8_t&) {
270
272 try {
273 wasm_code_ptr code((uint8_t*)code_bytes, code_size);
274 apply_options options = { .max_pages = 65536,
275 .max_call_depth = 0 };
276 std::unique_ptr<backend_t> bkend = std::make_unique<backend_t>(code, code_size, nullptr, options);
278 return std::make_unique<eos_vm_profiling_module>(std::move(bkend), code_bytes, code_size);
279 } catch(sysio::vm::exception& e) {
280 FC_THROW_EXCEPTION(wasm_execution_error, "Error building sys-vm interp: ${e}", ("e", e.what()));
281 }
282}
283#endif
284
285}
286
287template <auto HostFunction, typename... Preconditions>
289 template <typename Mod, typename Name>
290 constexpr host_function_registrator(Mod mod_name, Name fn_name) {
292 rhf_t::add<HostFunction, Preconditions...>(mod_name.c_str(), fn_name.c_str());
293#ifdef SYSIO_SYS_VM_OC_RUNTIME_ENABLED
294 constexpr bool is_injected = (Mod() == BOOST_HANA_STRING(SYSIO_INJECTED_MODULE_NAME));
295 eosvmoc::register_eosvm_oc<HostFunction, is_injected, std::tuple<Preconditions...>>(
296 mod_name + BOOST_HANA_STRING(".") + fn_name);
297#endif
298 }
299};
300
301#define REGISTER_INJECTED_HOST_FUNCTION(NAME, ...) \
302 static host_function_registrator<&interface::NAME, ##__VA_ARGS__> NAME##_registrator_impl() { \
303 return {BOOST_HANA_STRING(SYSIO_INJECTED_MODULE_NAME), BOOST_HANA_STRING(#NAME)}; \
304 } \
305 inline static auto NAME##_registrator = NAME##_registrator_impl();
306
307#define REGISTER_HOST_FUNCTION(NAME, ...) \
308 static host_function_registrator<&interface::NAME, core_precondition, context_aware_check, ##__VA_ARGS__> \
309 NAME##_registrator_impl() { \
310 return {BOOST_HANA_STRING("env"), BOOST_HANA_STRING(#NAME)}; \
311 } \
312 inline static auto NAME##_registrator = NAME##_registrator_impl();
313
314#define REGISTER_CF_HOST_FUNCTION(NAME, ...) \
315 static host_function_registrator<&interface::NAME, core_precondition, ##__VA_ARGS__> NAME##_registrator_impl() { \
316 return {BOOST_HANA_STRING("env"), BOOST_HANA_STRING(#NAME)}; \
317 } \
318 inline static auto NAME##_registrator = NAME##_registrator_impl();
319
320#define REGISTER_LEGACY_HOST_FUNCTION(NAME, ...) \
321 static host_function_registrator<&interface::NAME, legacy_static_check_wl_args, context_aware_check, ##__VA_ARGS__> \
322 NAME##_registrator_impl() { \
323 return {BOOST_HANA_STRING("env"), BOOST_HANA_STRING(#NAME)}; \
324 } \
325 inline static auto NAME##_registrator = NAME##_registrator_impl();
326
327#define REGISTER_LEGACY_CF_HOST_FUNCTION(NAME, ...) \
328 static host_function_registrator<&interface::NAME, legacy_static_check_wl_args, ##__VA_ARGS__> \
329 NAME##_registrator_impl() { \
330 return {BOOST_HANA_STRING("env"), BOOST_HANA_STRING(#NAME)}; \
331 } \
332 inline static auto NAME##_registrator = NAME##_registrator_impl();
333
334#define REGISTER_LEGACY_CF_ONLY_HOST_FUNCTION(NAME, ...) \
335 static host_function_registrator<&interface::NAME, legacy_static_check_wl_args, context_free_check, ##__VA_ARGS__> \
336 NAME##_registrator_impl() { \
337 return {BOOST_HANA_STRING("env"), BOOST_HANA_STRING(#NAME)}; \
338 } \
339 inline static auto NAME##_registrator = NAME##_registrator_impl();
340
341// context free api
342REGISTER_LEGACY_CF_ONLY_HOST_FUNCTION(get_context_free_data)
343
344// privileged api
345REGISTER_HOST_FUNCTION(is_feature_active, privileged_check);
346REGISTER_HOST_FUNCTION(activate_feature, privileged_check);
348REGISTER_HOST_FUNCTION(set_resource_limits, privileged_check);
349REGISTER_LEGACY_HOST_FUNCTION(get_resource_limits, privileged_check);
350REGISTER_HOST_FUNCTION(get_parameters_packed, privileged_check);
351REGISTER_HOST_FUNCTION(set_parameters_packed, privileged_check);
352REGISTER_HOST_FUNCTION(get_wasm_parameters_packed, privileged_check);
353REGISTER_HOST_FUNCTION(set_wasm_parameters_packed, privileged_check);
354REGISTER_LEGACY_HOST_FUNCTION(set_proposed_producers, privileged_check);
355REGISTER_LEGACY_HOST_FUNCTION(set_proposed_producers_ex, privileged_check);
356REGISTER_LEGACY_HOST_FUNCTION(get_blockchain_parameters_packed, privileged_check);
357REGISTER_LEGACY_HOST_FUNCTION(set_blockchain_parameters_packed, privileged_check);
358REGISTER_HOST_FUNCTION(is_privileged, privileged_check);
359REGISTER_HOST_FUNCTION(set_privileged, privileged_check);
360
361// softfloat api
404REGISTER_INJECTED_HOST_FUNCTION(_sysio_f32_trunc_i32s);
405REGISTER_INJECTED_HOST_FUNCTION(_sysio_f64_trunc_i32s);
406REGISTER_INJECTED_HOST_FUNCTION(_sysio_f32_trunc_i32u);
407REGISTER_INJECTED_HOST_FUNCTION(_sysio_f64_trunc_i32u);
408REGISTER_INJECTED_HOST_FUNCTION(_sysio_f32_trunc_i64s);
409REGISTER_INJECTED_HOST_FUNCTION(_sysio_f64_trunc_i64s);
410REGISTER_INJECTED_HOST_FUNCTION(_sysio_f32_trunc_i64u);
411REGISTER_INJECTED_HOST_FUNCTION(_sysio_f64_trunc_i64u);
420
421// producer api
422REGISTER_LEGACY_HOST_FUNCTION(get_active_producers);
423
424// crypto api
435
436// permission api
437REGISTER_LEGACY_HOST_FUNCTION(check_transaction_authorization);
438REGISTER_LEGACY_HOST_FUNCTION(check_permission_authorization);
439REGISTER_HOST_FUNCTION(get_permission_last_used);
440REGISTER_HOST_FUNCTION(get_account_creation_time);
441
442// authorization api
446REGISTER_HOST_FUNCTION(require_recipient);
449
450// system api
452REGISTER_HOST_FUNCTION(publication_time);
453REGISTER_LEGACY_HOST_FUNCTION(is_feature_activated);
455
456// context-free system api
459REGISTER_LEGACY_CF_HOST_FUNCTION(sysio_assert_message)
460REGISTER_CF_HOST_FUNCTION(sysio_assert_code)
462
463// action api
467REGISTER_HOST_FUNCTION(set_action_return_value);
468
469// console api
481
482// database api
483// primary index api
491REGISTER_HOST_FUNCTION(db_lowerbound_i64);
492REGISTER_HOST_FUNCTION(db_upperbound_i64);
494
495// uint64_t secondary index api
498REGISTER_HOST_FUNCTION(db_idx64_remove);
499REGISTER_LEGACY_HOST_FUNCTION(db_idx64_find_secondary);
500REGISTER_LEGACY_HOST_FUNCTION(db_idx64_find_primary);
501REGISTER_LEGACY_HOST_FUNCTION(db_idx64_lowerbound);
502REGISTER_LEGACY_HOST_FUNCTION(db_idx64_upperbound);
506
507// uint128_t secondary index api
510REGISTER_HOST_FUNCTION(db_idx128_remove);
511REGISTER_LEGACY_HOST_FUNCTION(db_idx128_find_secondary);
512REGISTER_LEGACY_HOST_FUNCTION(db_idx128_find_primary);
513REGISTER_LEGACY_HOST_FUNCTION(db_idx128_lowerbound);
514REGISTER_LEGACY_HOST_FUNCTION(db_idx128_upperbound);
518
519// 256-bit secondary index api
522REGISTER_HOST_FUNCTION(db_idx256_remove);
523REGISTER_LEGACY_HOST_FUNCTION(db_idx256_find_secondary);
524REGISTER_LEGACY_HOST_FUNCTION(db_idx256_find_primary);
525REGISTER_LEGACY_HOST_FUNCTION(db_idx256_lowerbound);
526REGISTER_LEGACY_HOST_FUNCTION(db_idx256_upperbound);
530
531// double secondary index api
532REGISTER_LEGACY_HOST_FUNCTION(db_idx_double_store, is_nan_check);
533REGISTER_LEGACY_HOST_FUNCTION(db_idx_double_update, is_nan_check);
534REGISTER_HOST_FUNCTION(db_idx_double_remove);
535REGISTER_LEGACY_HOST_FUNCTION(db_idx_double_find_secondary, is_nan_check);
536REGISTER_LEGACY_HOST_FUNCTION(db_idx_double_find_primary);
537REGISTER_LEGACY_HOST_FUNCTION(db_idx_double_lowerbound, is_nan_check);
538REGISTER_LEGACY_HOST_FUNCTION(db_idx_double_upperbound, is_nan_check);
539REGISTER_HOST_FUNCTION(db_idx_double_end);
541REGISTER_LEGACY_HOST_FUNCTION(db_idx_double_previous);
542
543// long double secondary index api
544REGISTER_LEGACY_HOST_FUNCTION(db_idx_long_double_store, is_nan_check);
545REGISTER_LEGACY_HOST_FUNCTION(db_idx_long_double_update, is_nan_check);
546REGISTER_HOST_FUNCTION(db_idx_long_double_remove);
547REGISTER_LEGACY_HOST_FUNCTION(db_idx_long_double_find_secondary, is_nan_check);
548REGISTER_LEGACY_HOST_FUNCTION(db_idx_long_double_find_primary);
549REGISTER_LEGACY_HOST_FUNCTION(db_idx_long_double_lowerbound, is_nan_check);
550REGISTER_LEGACY_HOST_FUNCTION(db_idx_long_double_upperbound, is_nan_check);
551REGISTER_HOST_FUNCTION(db_idx_long_double_end);
552REGISTER_LEGACY_HOST_FUNCTION(db_idx_long_double_next);
553REGISTER_LEGACY_HOST_FUNCTION(db_idx_long_double_previous);
554
555// memory api
560
561// transaction api
563REGISTER_LEGACY_HOST_FUNCTION(send_context_free_inline);
566
567// context-free transaction api
572REGISTER_CF_HOST_FUNCTION(tapos_block_prefix);
574
575// compiler builtins api
619
620// get_block_num protocol feature
622
623// crypto_primitives protocol feature
631
632} // namespace webassembly
633} // namespace chain
634} // namespace sysio
#define SYS_THROW(exc_type, FORMAT,...)
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
Definition exceptions.hpp:7
eos_vm_instantiated_module(eos_vm_runtime< Impl > *runtime, std::unique_ptr< backend_t > mod)
Definition sys-vm.cpp:126
std::unique_ptr< wasm_instantiated_module_interface > instantiate_module(const char *code_bytes, size_t code_size, std::vector< uint8_t >, const digest_type &code_hash, const uint8_t &vm_type, const uint8_t &vm_version) override
std::unique_ptr< wasm_instantiated_module_interface > instantiate_module(const char *code_bytes, size_t code_size, std::vector< uint8_t >, const digest_type &code_hash, const uint8_t &vm_type, const uint8_t &vm_version) override
Definition sys-vm.cpp:242
module & get_module()
Definition backend.hpp:248
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
backend_t bkend(hello_wasm, ehm, &wa)
watchdog wd
#define SYSIO_INJECTED_MODULE_NAME
Definition common.hpp:16
#define _(str)
Definition localize.hpp:7
std::vector< char > bytes
Definition alt_bn128.hpp:10
std::variant< alt_bn128_error, bytes > alt_bn128_add(const bytes &op1, const bytes &op2)
std::variant< k1_recover_error, bytes > k1_recover(const bytes &signature, const bytes &digest)
std::variant< alt_bn128_error, bytes > alt_bn128_mul(const bytes &g1_point, const bytes &scalar)
std::variant< alt_bn128_error, bool > alt_bn128_pair(const bytes &g1_g2_pairs, const yield_function_t &yield)
Definition name.hpp:106
void validate(const bytes &code, const whitelisted_intrinsics_type &intrinsics)
Definition sys-vm.cpp:64
bool is_intrinsic_whitelisted(const whitelisted_intrinsics_type &whitelisted_intrinsics, std::string_view name)
sysio::vm::registered_host_functions< webassembly::interface, sysio::vm::execution_interface, sysio::chain::type_converter > eos_vm_host_functions_t
Definition common.hpp:118
shared_flat_multimap< uint64_t, shared_string > whitelisted_intrinsics_type
@ self
the connection is to itself
Definition protocol.hpp:48
void apply(uint64_t, uint64_t, uint64_t)
unsigned int uint32_t
Definition stdint.h:126
unsigned char uint8_t
Definition stdint.h:124
Immutable except for fc::from_variant.
Definition name.hpp:43
std::uint32_t max_module_bytes
constexpr host_function_registrator(Mod mod_name, Name fn_name)
Definition sys-vm.cpp:290
virtual const char * what() const =0
virtual const char * detail() const =0
uint32_t get_exported_function(const std::string_view str)
Definition types.hpp:227
guarded_vector< import_entry > imports
Definition types.hpp:170
auto & get_function_type(uint32_t index) const
Definition types.hpp:221
static void add(const std::string &mod, const std::string &name)
#define REGISTER_CF_HOST_FUNCTION(NAME,...)
Definition sys-vm.cpp:314
#define REGISTER_LEGACY_HOST_FUNCTION(NAME,...)
Definition sys-vm.cpp:320
#define REGISTER_LEGACY_CF_ONLY_HOST_FUNCTION(NAME,...)
Definition sys-vm.cpp:334
transaction_checktime_timer & _timer
Definition sys-vm.cpp:42
#define REGISTER_LEGACY_CF_HOST_FUNCTION(NAME,...)
Definition sys-vm.cpp:327
#define REGISTER_HOST_FUNCTION(NAME,...)
Definition sys-vm.cpp:307
#define REGISTER_INJECTED_HOST_FUNCTION(NAME,...)
Definition sys-vm.cpp:301
F _func
Definition sys-vm.cpp:43
memset(pInfo->slotDescription, ' ', 64)
memcpy((char *) pInfo->slotDescription, s, l)