Skip to content

Commit 58da519

Browse files
committed
runtime: Use link! for store.get, allow eth call in start
1 parent b58d3f6 commit 58da519

File tree

2 files changed

+61
-52
lines changed

2 files changed

+61
-52
lines changed

runtime/wasm/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ maybe-owned = { git = "https://github.com/rustonaut/maybe-owned", branch = "mast
2828
# We need patch in order to be able to call host exports when initializing globals.
2929
#
3030
# By this conversation, wasmtime does not want to upstream this, pointing out that there is an
31-
# incompatibility between the way AS does things and the direction wasmtime wants to take:
31+
# incompatibility between the way AS does things and the direction wasmtime wants to take.
32+
# See:
3233
# https://bytecodealliance.zulipchat.com/#narrow/stream/206238-general/topic/Host.20functions.20in.20start
33-
#
34+
# https://github.com/AssemblyScript/assemblyscript/issues/1333
3435
# See also 3a23f045-eb9d-4b12-8c7c-3a4c2e34bea1
3536
wasmtime = { git = "https://github.com/graphprotocol/wasmtime", branch = "master" }
3637

runtime/wasm/src/module/mod.rs

Lines changed: 58 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -328,31 +328,6 @@ impl WasmInstance {
328328
};
329329
}
330330

331-
let modules = valid_module
332-
.import_name_to_modules
333-
.get("store.get")
334-
.into_iter()
335-
.flatten();
336-
337-
for module in modules {
338-
let func_shared_ctx = Rc::downgrade(&shared_ctx);
339-
linker.func(module, "store.get", move |entity_ptr: u32, id_ptr: u32| {
340-
let start = Instant::now();
341-
let instance = func_shared_ctx.upgrade().unwrap();
342-
let mut instance = instance.borrow_mut();
343-
let instance = instance.as_mut().expect("called store.get in a global");
344-
let stopwatch = &instance.host_metrics.stopwatch;
345-
let _section = stopwatch.start_section("host_export_store_get");
346-
let ret = instance
347-
.store_get(entity_ptr.into(), id_ptr.into())?
348-
.wasm_ptr();
349-
instance
350-
.host_metrics
351-
.observe_host_fn_execution_time(start.elapsed().as_secs_f64(), "store_get");
352-
Ok(ret)
353-
})?;
354-
}
355-
356331
let modules = valid_module
357332
.import_name_to_modules
358333
.get("ethereum.call")
@@ -361,32 +336,59 @@ impl WasmInstance {
361336

362337
for module in modules {
363338
let func_shared_ctx = Rc::downgrade(&shared_ctx);
364-
linker.func(module, "ethereum.call", move |call_ptr: u32| {
365-
let start = Instant::now();
366-
let instance = func_shared_ctx.upgrade().unwrap();
367-
let mut instance = instance.borrow_mut();
368-
let instance = instance.as_mut().expect("called ethereum.call in a global");
369-
let stopwatch = &instance.host_metrics.stopwatch;
370-
let _section = stopwatch.start_section("host_export_ethereum_call");
371-
372-
// For apiVersion >= 0.0.4 the call passed from the mapping includes the
373-
// function signature; subgraphs using an apiVersion < 0.0.4 don't pass
374-
// the the signature along with the call.
375-
let arg = if instance.ctx.host_exports.api_version >= Version::new(0, 0, 4) {
376-
instance.asc_get::<_, AscUnresolvedContractCall_0_0_4>(call_ptr.into())
377-
} else {
378-
instance.asc_get::<_, AscUnresolvedContractCall>(call_ptr.into())
379-
};
380-
381-
let ret = instance.ethereum_call(arg)?.wasm_ptr();
382-
instance
383-
.host_metrics
384-
.observe_host_fn_execution_time(start.elapsed().as_secs_f64(), "ethereum_call");
385-
Ok(ret)
386-
})?;
339+
let valid_module = valid_module.cheap_clone();
340+
let host_metrics = host_metrics.cheap_clone();
341+
let timeout_stopwatch = timeout_stopwatch.cheap_clone();
342+
let ctx = ctx.cheap_clone();
343+
linker.func(
344+
module,
345+
"ethereum.call",
346+
move |caller: wasmtime::Caller, call_ptr: u32| {
347+
let start = Instant::now();
348+
let instance = func_shared_ctx.upgrade().unwrap();
349+
let mut instance = instance.borrow_mut();
350+
351+
// Happens when calling a host fn in Wasm start.
352+
if instance.is_none() {
353+
*instance = Some(
354+
WasmInstanceContext::from_caller(
355+
caller,
356+
ctx.borrow_mut().take().unwrap(),
357+
valid_module.cheap_clone(),
358+
host_metrics.cheap_clone(),
359+
timeout,
360+
timeout_stopwatch.cheap_clone(),
361+
)
362+
.unwrap(),
363+
)
364+
}
365+
366+
let instance = instance.as_mut().unwrap();
367+
let stopwatch = &instance.host_metrics.stopwatch;
368+
let _section = stopwatch.start_section("host_export_ethereum_call");
369+
370+
// For apiVersion >= 0.0.4 the call passed from the mapping includes the
371+
// function signature; subgraphs using an apiVersion < 0.0.4 don't pass
372+
// the the signature along with the call.
373+
let arg = if instance.ctx.host_exports.api_version >= Version::new(0, 0, 4) {
374+
instance.asc_get::<_, AscUnresolvedContractCall_0_0_4>(call_ptr.into())
375+
} else {
376+
instance.asc_get::<_, AscUnresolvedContractCall>(call_ptr.into())
377+
};
378+
379+
let ret = instance.ethereum_call(arg)?.wasm_ptr();
380+
instance.host_metrics.observe_host_fn_execution_time(
381+
start.elapsed().as_secs_f64(),
382+
"ethereum_call",
383+
);
384+
Ok(ret)
385+
},
386+
)?;
387387
}
388388

389389
link!("abort", abort, message_ptr, file_name_ptr, line, column);
390+
391+
link!("store.get", store_get, "host_export_store_get", entity, id);
390392
link!(
391393
"store.set",
392394
store_set,
@@ -672,14 +674,15 @@ impl WasmInstanceContext {
672674
entity_ptr: AscPtr<AscString>,
673675
id_ptr: AscPtr<AscString>,
674676
) -> Result<AscPtr<AscEntity>, Trap> {
677+
let start = Instant::now();
675678
let entity_ptr = self.asc_get(entity_ptr);
676679
let id_ptr = self.asc_get(id_ptr);
677680
let entity_option =
678681
self.ctx
679682
.host_exports
680683
.store_get(&mut self.ctx.state, entity_ptr, id_ptr)?;
681684

682-
Ok(match entity_option {
685+
let ret = Ok(match entity_option {
683686
Some(entity) => {
684687
let _section = self
685688
.host_metrics
@@ -688,7 +691,12 @@ impl WasmInstanceContext {
688691
self.asc_new(&entity)
689692
}
690693
None => AscPtr::null(),
691-
})
694+
});
695+
696+
self.host_metrics
697+
.observe_host_fn_execution_time(start.elapsed().as_secs_f64(), "store_get");
698+
699+
ret
692700
}
693701

694702
/// function ethereum.call(call: SmartContractCall): Array<Token> | null

0 commit comments

Comments
 (0)