• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
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 
17 #include <emscripten/emscripten.h>
18 
19 #include <cstddef>
20 #include <cstdint>
21 #include <cstring>
22 #include <string>
23 
24 #include "perfetto/ext/base/string_utils.h"
25 #include "src/trace_config_utils/pb_to_txt.h"
26 #include "src/trace_config_utils/txt_to_pb.h"
27 
28 namespace {
29 // The buffer used to exchange input and output arguments. We assume 16MB
30 // is enough to handle trace configs.
31 char wasm_buf[16 * 1024 * 1024];
32 }  // namespace
33 
34 extern "C" {
35 
36 // Returns the pointer to the buffer.
37 void* EMSCRIPTEN_KEEPALIVE trace_config_utils_buf();
trace_config_utils_buf()38 void* trace_config_utils_buf() {
39   return &wasm_buf;
40 }
41 
42 // Returns the size of the buffer, so trace_config_utils_wasm.ts doesn't have
43 // to hardcode the 16MB.
44 uint32_t EMSCRIPTEN_KEEPALIVE trace_config_utils_buf_size();
trace_config_utils_buf_size()45 uint32_t trace_config_utils_buf_size() {
46   return static_cast<uint32_t>(sizeof(wasm_buf));
47 }
48 
49 // Converts a proto-encoded protos.TraceConfig to text.
50 // The caller must memcpy the bytes into the wasm_buf and pass the size of the
51 // copied data into `size`. The returned pbtxt will be written in wasm_buf and
52 // its size returned here.
53 uint32_t EMSCRIPTEN_KEEPALIVE trace_config_pb_to_txt(uint32_t size);
54 
trace_config_pb_to_txt(uint32_t size)55 uint32_t trace_config_pb_to_txt(uint32_t size) {
56   std::string txt = perfetto::TraceConfigPbToTxt(wasm_buf, size);
57   size_t wsize = perfetto::base::SprintfTrunc(wasm_buf, sizeof(wasm_buf), "%s",
58                                               txt.c_str());
59   return static_cast<uint32_t>(wsize);
60 }
61 
62 // Like the above, but converts a pbtxt into proto-encoded bytes.
63 // Because this can fail (the C++ function returns a StatusOr) we write
64 // a success/failure in the first byte to tell the diffrence.
65 uint32_t EMSCRIPTEN_KEEPALIVE trace_config_txt_to_pb(uint32_t size);
66 
trace_config_txt_to_pb(uint32_t size)67 uint32_t trace_config_txt_to_pb(uint32_t size) {
68   auto res = perfetto::TraceConfigTxtToPb(std::string(wasm_buf, size));
69   if (!res.ok()) {
70     wasm_buf[0] = 0;
71     size_t wsize = perfetto::base::SprintfTrunc(
72         &wasm_buf[1], sizeof(wasm_buf) - 1, "%s", res.status().c_message());
73     return static_cast<uint32_t>(wsize);
74   }
75   const size_t resp_size = std::min(res->size(), sizeof(wasm_buf) - 1);
76   wasm_buf[0] = 1;
77   memcpy(&wasm_buf[1], res->data(), resp_size);
78   return static_cast<uint32_t>(resp_size);
79 }
80 }  // extern "C"
81 
82 // This is unused but is needed to keep emscripten happy.
main(int,char **)83 int main(int, char**) {
84   return 0;
85 }
86