diff --git a/examples/hello_world/config/BUILD b/examples/hello_world/config/BUILD index 845841a9a77..cdc16591501 100644 --- a/examples/hello_world/config/BUILD +++ b/examples/hello_world/config/BUILD @@ -37,5 +37,5 @@ serialized_config( modules = { "app": "//examples/hello_world/module/cpp:hello_world.wasm", }, - textproto = ":config.textproto", + textproto = ":config_no_translator.textproto", ) diff --git a/examples/hello_world/config/config_no_translator.textproto b/examples/hello_world/config/config_no_translator.textproto new file mode 100644 index 00000000000..40a0bd4bbd9 --- /dev/null +++ b/examples/hello_world/config/config_no_translator.textproto @@ -0,0 +1,18 @@ +node_configs { + name: "app" + wasm_config { + module_bytes: "" + } +} +node_configs { + name: "grpc-server" + grpc_server_config { + address: "[::]:8080" + } +} +node_configs { + name: "log" + log_config {} +} +initial_node_config_name: "app" +initial_entrypoint_name: "grpc_oak_main" diff --git a/examples/hello_world/module/cpp/hello_world.cc b/examples/hello_world/module/cpp/hello_world.cc index faa7398d907..88bfc59adef 100644 --- a/examples/hello_world/module/cpp/hello_world.cc +++ b/examples/hello_world/module/cpp/hello_world.cc @@ -46,8 +46,46 @@ WASM_IMPORT("oak") uint32_t channel_write(uint64_t handle, uint8_t* buff, size_t usize, uint8_t* handle_buff, size_t handle_count); WASM_IMPORT("oak") uint32_t channel_close(uint64_t handle); +WASM_IMPORT("oak") +uint32_t channel_create(uint64_t* write_handle, uint64_t* read_handle, uint8_t* label_buf, + size_t label_size); +WASM_IMPORT("oak") +uint32_t node_create(uint8_t* config_buf, size_t config_size, uint8_t* entrypoint_buf, + size_t entrypoint_size, uint8_t* label_buf, size_t label_size, + uint64_t handle); + +WASM_EXPORT void grpc_oak_main(uint64_t _handle) { + // Create a channel to the gRPC server pseudo-Node. + uint64_t write_handle; + uint64_t read_handle; + uint32_t result = channel_create(&write_handle, &read_handle, nullptr, 0); + if (result != oak::OakStatus::OK) { + return; + } + + // Create a gRPC server pseudo-Node + char config_name[] = "grpc-server"; + result = node_create((uint8_t*)config_name, sizeof(config_name) - 1, nullptr, 0, nullptr, 0, + read_handle); + if (result != oak::OakStatus::OK) { + return; + } + channel_close(read_handle); + + // Create a separate channel for receiving invocations and pass it to the gRPC pseudo-Node. + uint64_t grpc_out_handle; + uint64_t grpc_in_handle; + result = channel_create(&grpc_out_handle, &grpc_in_handle, nullptr, 0); + if (result != oak::OakStatus::OK) { + return; + } + result = channel_write(write_handle, nullptr, 0, (uint8_t*)&grpc_out_handle, 1); + if (result != oak::OakStatus::OK) { + return; + } + channel_close(grpc_out_handle); + channel_close(write_handle); -WASM_EXPORT void oak_main(uint64_t grpc_in_handle) { // TODO(#744): Add C++ helpers for dealing with handle notification space. uint8_t handle_space[9] = { static_cast(grpc_in_handle & 0xff), @@ -62,7 +100,7 @@ WASM_EXPORT void oak_main(uint64_t grpc_in_handle) { }; while (true) { - int32_t result = wait_on_channels(handle_space, 1); + uint32_t result = wait_on_channels(handle_space, 1); if (result != oak::OakStatus::OK) { return; } @@ -87,14 +125,12 @@ WASM_EXPORT void oak_main(uint64_t grpc_in_handle) { // Manually create an encapsulated GrpcResponse protobuf and send it back. // 0a b00001.010 = tag 1 (GrpcResponse.rsp_msg), length-delimited field // 0b length=11 - // 12 b00010.010 = tag 2 (Any.value), length-delimited field - // 09 length=9 - // 0A b00001.010 = tag 1 (HelloResponse.reply), length-delimited field - // 07 length=7 - // 74657374696e67 "testing" + // 0A b00001.010 = tag 1 (HelloResponse.reply), length-delimited field + // 07 length=7 + // 74657374696e67 "testing" // 18 b00011.000 = tag 3 (GrpcResponse.last), varint // 01 true - uint8_t rsp_buf[] = "\x0a\x0b\x12\x09\x0A\x07\x74\x65\x73\x74\x69\x6e\x67\x18\x01"; + uint8_t rsp_buf[] = "\x0a\x0b\x0A\x07\x74\x65\x73\x74\x69\x6e\x67\x18\x01"; // TODO(#422): replace with use of message type and serialization. channel_write(rsp_handle, rsp_buf, sizeof(rsp_buf) - 1, nullptr, 0); channel_close(rsp_handle); diff --git a/scripts/run_examples b/scripts/run_examples index 9e808f5dee0..a456c81fa19 100755 --- a/scripts/run_examples +++ b/scripts/run_examples @@ -34,16 +34,11 @@ while getopts "s:l:h" opt; do esac done -# TODO(#1009): Re-enable C++ examples after supporting them with Rust Oak Loader. -if [[ "${languages}" == "cpp" ]]; then - echo "C++ examples are currently not supported" - exit 1 -fi - # Run all examples. for language in ${languages}; do # TODO(#594): Re-enable rustfmt when upstream rustc internal error is fixed. - examples="$(find examples -mindepth 2 -maxdepth 4 -type d -regex '.*/module.*/'"${language}"'$' | cut -d'/' -f2 | uniq | grep -v rustfmt)" + # TODO(#1009): Re-enable C++ tensorflow example after supporting them with Rust Oak Loader. + examples="$(find examples -mindepth 2 -maxdepth 4 -type d -regex '.*/module.*/'"${language}"'$' | cut -d'/' -f2 | uniq | grep -v rustfmt | grep -v tensorflow)" for example in ${examples}; do if [[ "${example}" == "chat" ]]; then "${SCRIPTS_DIR}/run_example" -s "${server}" -l "${language}" -e chat -- --test