152 {
153 if(mapping_is_executable == false) {
154 mprotect(code_mapping, code_mapping_size, PROT_EXEC|PROT_READ);
155 mapping_is_executable = true;
156 }
157
161 const wasm_config&
config =
context.control.get_global_properties().wasm_configuration;
164 }
165 stack.
reset(max_call_depth);
166 SYS_ASSERT(code.starting_memory_pages <= (
int)max_pages, wasm_execution_error,
"Initial memory out of range");
167
168
169 if(code.starting_memory_pages > 0 ) {
170 uint64_t initial_page_offset = std::min(
static_cast<std::size_t
>(code.starting_memory_pages), mem.size_of_memory_slice_mapping()/
memory::stride - 1);
171 if(initial_page_offset <
static_cast<uint64_t>(code.starting_memory_pages)) {
172 mprotect(mem.full_page_memory_base() + initial_page_offset * sysio::chain::wasm_constraints::wasm_page_size,
173 (code.starting_memory_pages - initial_page_offset) * sysio::chain::wasm_constraints::wasm_page_size, PROT_READ | PROT_WRITE);
174 }
176 memset(mem.full_page_memory_base(), 0, 64u*1024u*code.starting_memory_pages);
177 }
178 else
179 arch_prctl(ARCH_SET_GS, (
unsigned long*)mem.zero_page_memory_base());
180
181 void* globals;
183 globals_buffer.resize(code.initdata_prologue_size);
184 memcpy(globals_buffer.data(), code_mapping + code.initdata_begin, code.initdata_prologue_size);
188 globals = globals_buffer.data() + globals_buffer.size();
189 } else {
190 memcpy(mem.full_page_memory_base() - code.initdata_prologue_size, code_mapping + code.initdata_begin, code.initdata_size);
191 globals = mem.full_page_memory_base();
192 }
193
195 cb->
magic = signal_sentinel;
196 cb->execution_thread_code_start = (
uintptr_t)code_mapping;
197 cb->execution_thread_code_length = code_mapping_size;
198 cb->execution_thread_memory_start = (
uintptr_t)mem.start_of_memory_slices();
199 cb->execution_thread_memory_length = mem.size_of_memory_slice_mapping();
201 executors_exception_ptr = nullptr;
202 cb->eptr = &executors_exception_ptr;
204 cb->current_linear_memory_pages = code.starting_memory_pages;
206 cb->first_invalid_memory_address = code.starting_memory_pages*64*1024;
207 cb->full_linear_memory_start = (char*)mem.full_page_memory_base();
208 cb->jmp = &executors_sigjmp_buf;
209 cb->bounce_buffers = &executors_bounce_buffers;
210 cb->running_code_base = (
uintptr_t)(code_mapping + code.code_begin);
211 cb->is_running = true;
212 cb->globals = globals;
213
214 context.trx_context.transaction_timer.set_expiration_callback([](
void* user) {
216 syscall(SYS_mprotect,
self->code_mapping,
self->code_mapping_size, PROT_NONE);
217 self->mapping_is_executable =
false;
218 }, this);
219 context.trx_context.checktime();
220
222 cb->is_running = false;
223 cb->bounce_buffers->clear();
224 tt.set_expiration_callback(nullptr, nullptr);
225
226 uint64_t base_pages = mem.size_of_memory_slice_mapping()/memory::stride - 1;
227 if(cb->current_linear_memory_pages > base_pages) {
228 mprotect(mem.full_page_memory_base() + base_pages * sysio::chain::wasm_constraints::wasm_page_size,
229 (cb->current_linear_memory_pages - base_pages) * sysio::chain::wasm_constraints::wasm_page_size, PROT_NONE);
230 }
231 });
232
234
235 switch(sigsetjmp(*cb->jmp, 0)) {
236 case 0:
239 [&](const no_offset&) {},
240 [&](const intrinsic_ordinal& i) {
242 start_func();
243 },
244 [&](const code_offset& offs) {
245 void(*start_func)() = (void(*)())(cb->running_code_base + offs.offset);
246 start_func();
247 }
248 }, code.start);
249 apply_func(
context.get_receiver().to_uint64_t(),
context.get_action().account.to_uint64_t(),
context.get_action().name.to_uint64_t());
250 });
251 break;
252
254 context.trx_context.checktime();
255 break;
257 SYS_ASSERT(
false, wasm_execution_error,
"access violation");
258 break;
260 std::rethrow_exception(*cb->eptr);
261 break;
262 }
263}
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
executor(const code_cache_base &cc)
static constexpr size_t stride
static constexpr uintptr_t first_intrinsic_offset
static constexpr uintptr_t max_prologue_size
scoped_exit< Callback > make_scoped_exit(Callback &&c)
@ SYSVMOC_EXIT_CHECKTIME_FAIL
eos_vm_oc_control_block control_block
constexpr unsigned maximum_linear_memory
constexpr unsigned maximum_call_depth
@ configurable_wasm_limits
overloaded(Ts...) -> overloaded< Ts... >
@ self
the connection is to itself
sysio::client::http::http_context context
_W64 unsigned int uintptr_t
void reset(std::size_t max_call_depth)
memset(pInfo->slotDescription, ' ', 64)
memcpy((char *) pInfo->slotDescription, s, l)