marine/host_imports/logger/
log_utf8_string_impl.rs

1/*
2 * Copyright 2020 Fluence Labs Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17use marine_wasm_backend_traits::AsContextMut;
18use marine_wasm_backend_traits::ImportCallContext;
19use marine_wasm_backend_traits::WasmBackend;
20
21use it_memory_traits::Memory;
22use it_memory_traits::MemoryReadable;
23
24pub(crate) fn log_utf8_string_closure<WB: WasmBackend>(
25    logging_mask: i32,
26    module: String,
27) -> impl Fn(<WB as WasmBackend>::ImportCallContext<'_>, i32, i32, i32, i32) {
28    move |ctx, level, target, msg_offset, msg_size| {
29        if target == 0 || target & logging_mask != 0 {
30            log_utf8_string::<WB>(&module, ctx, level, msg_offset, msg_size)
31        }
32    }
33}
34
35pub(crate) fn log_utf8_string<WB: WasmBackend>(
36    module: &str,
37    mut ctx: <WB as WasmBackend>::ImportCallContext<'_>,
38    level: i32,
39    msg_offset: i32,
40    msg_size: i32,
41) {
42    let level = level_from_i32(level);
43    let msg = read_string::<WB>(&mut ctx, msg_offset, msg_size);
44
45    match msg {
46        Some(msg) => log::logger().log(
47            &log::Record::builder()
48                .args(format_args!("{}", msg))
49                .level(level)
50                .module_path(module.into())
51                .target(module)
52                .build(),
53        ),
54        None => log::warn!("logger: incorrect UTF8 string's been supplied to logger"),
55    }
56}
57
58#[inline]
59fn read_string<WB: WasmBackend>(
60    ctx: &mut <WB as WasmBackend>::ImportCallContext<'_>,
61    offset: i32,
62    size: i32,
63) -> Option<String> {
64    let view = ctx.memory(0).unwrap().view(); // TODO handle error
65    let bytes = view.read_vec(&mut ctx.as_context_mut(), offset as u32, size as u32);
66    String::from_utf8(bytes).ok()
67}
68
69#[inline]
70fn level_from_i32(level: i32) -> log::Level {
71    match level {
72        1 => log::Level::Error,
73        2 => log::Level::Warn,
74        3 => log::Level::Info,
75        4 => log::Level::Debug,
76        5 => log::Level::Trace,
77        _ => log::Level::max(),
78    }
79}