Skip to content

Commit 197504c

Browse files
author
Guy Bedford
authored
feat!: compute runtime component build (#326)
1 parent e7386b7 commit 197504c

24 files changed

+5571
-676
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ node_modules/
1212
/rusturl/
1313
# compiler_flags
1414
/js-compute-runtime.wasm
15+
/c-dependencies/js-compute-runtime/obj
1516
tests/wpt-harness/wpt-test-runner.js
1617
wpt-runtime.wasm
1718
docs-app/bin/main.wasm

c-dependencies/js-compute-runtime/Makefile

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,22 @@ SM_OBJ += $(SM_SRC)lib/*.a
2525
FSM_SRC := $(ROOT_SRC)/js-compute-runtime/
2626

2727
WASI_CXX ?= $(WASI_SDK)/bin/clang++
28+
WASI_CC ?= $(WASI_SDK)/bin/clang
29+
30+
WIT_BINDGEN := $(shell which wit-bindgen)
31+
32+
ifndef WIT_BINDGEN
33+
WIT_BINDGEN = $(error No wit-bindgen in PATH, consider doing cargo install --git https://github.com/bytecodealliance/wit-bindgen wit-bindgen-cli)
34+
endif
2835

2936
CXX_FLAGS := -std=gnu++17 -Wall -Werror -Qunused-arguments
3037
CXX_FLAGS += -fno-sized-deallocation -fno-aligned-new -mthread-model single
3138
CXX_FLAGS += -fPIC -fno-rtti -fno-exceptions -fno-math-errno -pipe
3239
CXX_FLAGS += -fno-omit-frame-pointer -funwind-tables -I$(FSM_SRC)
3340
CXX_FLAGS += --sysroot=$(WASI_SDK)/share/wasi-sysroot
3441

42+
CFLAGS := -Wall -Werror -Wno-unknown-attributes -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast
43+
3544
LD_FLAGS := -Wl,-z,noexecstack -Wl,-z,text -Wl,-z,relro -Wl,-z,nocopyreloc
3645
LD_FLAGS += -Wl,-z,stack-size=1048576 -Wl,--stack-first -lwasi-emulated-getpid
3746

@@ -54,9 +63,10 @@ WASM_STRIP = wasm-opt --strip-debug -o $1 $1
5463
endif
5564
endif
5665

66+
OBJ_DIR := obj/
5767
FSM_CPP := $(wildcard $(FSM_SRC)*.cpp) $(wildcard $(FSM_SRC)builtins/*.cpp)
58-
FSM_DEP := $(patsubst $(FSM_SRC)%.cpp,$(OBJDIR)%.d,$(FSM_CPP))
59-
FSM_OBJ := $(patsubst $(FSM_SRC)%.cpp,$(OBJDIR)%.o,$(FSM_CPP))
68+
FSM_DEP := $(patsubst $(FSM_SRC)%.cpp,$(OBJ_DIR)%.d,$(FSM_CPP))
69+
FSM_OBJ := $(patsubst $(FSM_SRC)%.cpp,$(OBJ_DIR)%.o,$(FSM_CPP))
6070
RUST_URL_SRC := $(FSM_SRC)rust-url
6171
RUST_URL_RS_FILES := $(shell find $(RUST_URL_SRC)/src -name '*.rs')
6272
RUST_URL_LIB := rusturl/wasm32-wasi/$(MODE)/librust_url.a
@@ -67,27 +77,43 @@ $(RUST_URL_LIB): $(RUST_URL_RS_FILES) $(RUST_URL_SRC)/Cargo.toml $(RUST_URL_SRC)
6777
cd $(RUST_URL_SRC) && cbindgen --output rust-url.h
6878
cargo build --manifest-path $(RUST_URL_SRC)/Cargo.toml --target-dir ./rusturl --target=wasm32-wasi $(CARGO_FLAG)
6979

70-
%.o: $(FSM_SRC)%.cpp $(FSM_SRC)Makefile $(RUST_URL_LIB) compiler_flags
80+
obj:
81+
$Q mkdir -p $(OBJ_DIR)builtins $(OBJ_DIR)xqd-world
82+
83+
$(OBJ_DIR)%.o: $(FSM_SRC)%.cpp $(FSM_SRC)Makefile $(RUST_URL_LIB) compiler_flags | obj
84+
$(WASI_CXX) $(CXX_FLAGS) $(CXX_OPT) $(DEFINES) -I $(SM_SRC)include -MMD -MP -c -o $@ $<
85+
86+
$(OBJ_DIR)builtins/%.o: $(FSM_SRC)builtins/%.cpp $(FSM_SRC)Makefile $(RUST_URL_LIB) compiler_flags | obj
7187
$(WASI_CXX) $(CXX_FLAGS) $(CXX_OPT) $(DEFINES) -I $(SM_SRC)include -MMD -MP -c -o $@ $<
7288

73-
builtins:
74-
$Q mkdir -p builtins
89+
$(OBJ_DIR)xqd-world/xqd_world.o: $(FSM_SRC)xqd-world/xqd_world.c $(FSM_SRC)Makefile compiler_flags
90+
$(WASI_CC) $(CFLAGS) $(CXX_OPT) $(DEFINES) -I $(SM_SRC)include -MMD -MP -c -o $@ $<
7591

76-
builtins/%.o: $(FSM_SRC)builtins/%.cpp $(FSM_SRC)Makefile $(RUST_URL_LIB) compiler_flags | builtins
92+
$(OBJ_DIR)xqd-world/xqd_world_adapter.o: $(FSM_SRC)xqd-world/xqd_world_adapter.cpp $(FSM_SRC)Makefile compiler_flags
7793
$(WASI_CXX) $(CXX_FLAGS) $(CXX_OPT) $(DEFINES) -I $(SM_SRC)include -MMD -MP -c -o $@ $<
7894

79-
js-compute-runtime.wasm: $(FSM_OBJ) $(SM_OBJ) $(RUST_URL_LIB)
95+
$(OBJ_DIR)xqd-world/xqd_world_adapter_component.o: $(FSM_SRC)xqd-world/xqd_world_adapter.cpp $(FSM_SRC)Makefile compiler_flags
96+
$(WASI_CXX) $(CXX_FLAGS) $(CXX_OPT) $(DEFINES) -DCOMPONENT -I $(SM_SRC)include -MMD -MP -c -o $@ $<
97+
98+
js-compute-runtime.wasm: $(FSM_OBJ) $(SM_OBJ) $(OBJ_DIR)xqd-world/xqd_world.o $(OBJ_DIR)xqd-world/xqd_world_adapter.o $(RUST_URL_LIB)
99+
$(WASI_CXX) $(CXX_FLAGS) $(CXX_OPT) $(DEFINES) $(LD_FLAGS) -o $@ $^
100+
$(call WASM_STRIP,$@)
101+
102+
js-compute-runtime-component.wasm: $(FSM_OBJ) $(OBJ_DIR)xqd-world/xqd_world.o $(OBJ_DIR)xqd-world/xqd_world_adapter_component.o $(SM_OBJ) $(RUST_URL_LIB)
80103
$(WASI_CXX) $(CXX_FLAGS) $(CXX_OPT) $(DEFINES) $(LD_FLAGS) -o $@ $^
81104
$(call WASM_STRIP,$@)
82105

83106
install: js-compute-runtime.wasm
84107
install -m 444 -Dt $(DESTDIR)/dist js-compute-runtime.wasm
85108

109+
regenerate-world:
110+
$(WIT_BINDGEN) guest c xqd.wit --no-helpers --out-dir xqd-world
111+
86112
clean:
87-
$(RM) compile_commands.json $(FSM_OBJ)
113+
$(RM) compile_commands.json $(FSM_OBJ) xqd-world/xqd_world_component_type.o
88114

89115
distclean: clean
90-
$(RM) $(FSM_DEP) compiler_flags
116+
$(RM) $(FSM_DEP) $(FSM_DEP_COMPONENT) $(OBJ_DIR)xqd-world/*.o compiler_flags
91117

92118
.PHONY: compile_commands.json
93119
compile_commands.json:

c-dependencies/js-compute-runtime/builtins/backend.cpp

Lines changed: 53 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -120,138 +120,110 @@ namespace builtins {
120120
JS::Result<mozilla::Ok> Backend::register_dynamic_backend(JSContext *cx, JS::HandleObject backend) {
121121
MOZ_ASSERT(is_instance(backend));
122122

123-
DynamicBackendConfig definition;
124-
std::memset(&definition, 0, sizeof(definition));
123+
xqd_world_string_t name_str;
124+
JS::RootedString name(cx, JS::GetReservedSlot(backend, Backend::Slots::Name).toString());
125+
JS::UniqueChars nameChars = encode(cx, name, &name_str.len);
126+
name_str.ptr = nameChars.get();
127+
128+
xqd_world_string_t target_str;
129+
JS::RootedString target(cx, JS::GetReservedSlot(backend, Backend::Slots::Target).toString());
130+
JS::UniqueChars targetChars = encode(cx, target, &target_str.len);
131+
target_str.ptr = targetChars.get();
125132

126-
unsigned int backend_config_mask = 0u;
133+
fastly_dynamic_backend_config_t backend_config;
134+
std::memset(&backend_config, 0, sizeof(backend_config));
127135

128-
std::optional<std::string> hostOverride;
136+
std::string hostOverride;
129137
auto hostOverrideSlot = JS::GetReservedSlot(backend, Backend::Slots::HostOverride);
130-
if (!hostOverrideSlot.isNullOrUndefined()) {
138+
if ((backend_config.host_override.is_some = !hostOverrideSlot.isNullOrUndefined())) {
131139
JS::RootedString hostOverrideString(cx, hostOverrideSlot.toString());
132140
size_t hostOverride_len;
133141
JS::UniqueChars hostOverrideChars = encode(cx, hostOverrideString, &hostOverride_len);
134142
hostOverride = std::string(hostOverrideChars.get(), hostOverride_len);
143+
backend_config.host_override.val.ptr = const_cast<char *>(hostOverride.c_str());
144+
backend_config.host_override.val.len = hostOverride.length();
135145
}
136146

137147
auto connectTimeoutSlot = JS::GetReservedSlot(backend, Backend::Slots::ConnectTimeout);
138-
if (!connectTimeoutSlot.isNullOrUndefined()) {
139-
definition.connect_timeout_ms = connectTimeoutSlot.toInt32();
140-
backend_config_mask |= BACKEND_CONFIG_CONNECT_TIMEOUT;
141-
} else {
142-
definition.connect_timeout_ms = 0;
148+
if ((backend_config.connect_timeout.is_some = !connectTimeoutSlot.isNullOrUndefined())) {
149+
backend_config.connect_timeout.val = connectTimeoutSlot.toInt32();
143150
}
144151

145152
auto firstByteTimeoutSlot = JS::GetReservedSlot(backend, Backend::Slots::FirstByteTimeout);
146-
if (!firstByteTimeoutSlot.isNullOrUndefined()) {
147-
definition.first_byte_timeout_ms = firstByteTimeoutSlot.toInt32();
148-
backend_config_mask |= BACKEND_CONFIG_FIRST_BYTE_TIMEOUT;
149-
} else {
150-
definition.first_byte_timeout_ms = 0;
153+
if ((backend_config.first_byte_timeout.is_some = !firstByteTimeoutSlot.isNullOrUndefined())) {
154+
backend_config.first_byte_timeout.val = firstByteTimeoutSlot.toInt32();
151155
}
156+
152157
auto betweenBytesTimeoutSlot = JS::GetReservedSlot(backend, Backend::Slots::BetweenBytesTimeout);
153-
if (!betweenBytesTimeoutSlot.isNullOrUndefined()) {
154-
definition.between_bytes_timeout_ms = betweenBytesTimeoutSlot.toInt32();
155-
backend_config_mask |= BACKEND_CONFIG_BETWEEN_BYTES_TIMEOUT;
156-
} else {
157-
definition.between_bytes_timeout_ms = 0;
158+
if ((backend_config.between_bytes_timeout.is_some =
159+
!betweenBytesTimeoutSlot.isNullOrUndefined())) {
160+
backend_config.between_bytes_timeout.val = betweenBytesTimeoutSlot.toInt32();
161+
}
162+
163+
auto useSslSlot = JS::GetReservedSlot(backend, Backend::Slots::UseSsl);
164+
if ((backend_config.use_ssl.is_some = !useSslSlot.isNullOrUndefined())) {
165+
backend_config.use_ssl.val = useSslSlot.toBoolean();
158166
}
159167

160168
auto tlsMinVersion = JS::GetReservedSlot(backend, Backend::Slots::TlsMinVersion);
161-
if (!tlsMinVersion.isNullOrUndefined()) {
162-
definition.ssl_min_version = tlsMinVersion.toInt32();
163-
backend_config_mask |= BACKEND_CONFIG_SSL_MIN_VERSION;
164-
} else {
165-
definition.ssl_min_version = 0;
169+
if ((backend_config.ssl_min_version.is_some = !tlsMinVersion.isNullOrUndefined())) {
170+
backend_config.ssl_min_version.val = (int8_t)tlsMinVersion.toInt32();
166171
}
172+
167173
auto tlsMaxVersion = JS::GetReservedSlot(backend, Backend::Slots::TlsMaxVersion);
168-
if (!tlsMaxVersion.isNullOrUndefined()) {
169-
definition.ssl_max_version = tlsMaxVersion.toInt32();
170-
backend_config_mask |= BACKEND_CONFIG_SSL_MAX_VERSION;
171-
} else {
172-
definition.ssl_max_version = 0;
174+
if ((backend_config.ssl_max_version.is_some = !tlsMaxVersion.isNullOrUndefined())) {
175+
backend_config.ssl_max_version.val = (int8_t)tlsMaxVersion.toInt32();
173176
}
174177

175-
std::optional<std::string> certificateHostname;
178+
std::string certificateHostname;
176179
auto certificateHostnameSlot = JS::GetReservedSlot(backend, Backend::Slots::CertificateHostname);
177-
if (!certificateHostnameSlot.isNullOrUndefined()) {
180+
if ((backend_config.cert_hostname.is_some = !certificateHostnameSlot.isNullOrUndefined())) {
178181
JS::RootedString certificateHostnameString(cx, certificateHostnameSlot.toString());
179182
size_t certificateHostname_len;
180183
JS::UniqueChars certificateHostnameChars =
181184
encode(cx, certificateHostnameString, &certificateHostname_len);
182185
certificateHostname = std::string(certificateHostnameChars.get(), certificateHostname_len);
186+
backend_config.cert_hostname.val.ptr = const_cast<char *>(certificateHostname.c_str());
187+
backend_config.cert_hostname.val.len = certificateHostname.length();
183188
}
184189

185-
std::optional<std::string> caCertificate;
190+
std::string caCertificate;
186191
auto caCertificateSlot = JS::GetReservedSlot(backend, Backend::Slots::CaCertificate);
187-
if (!caCertificateSlot.isNullOrUndefined()) {
192+
if ((backend_config.ca_cert.is_some = !caCertificateSlot.isNullOrUndefined())) {
188193
JS::RootedString caCertificateString(cx, caCertificateSlot.toString());
189194
size_t caCertificate_len;
190195
JS::UniqueChars caCertificateChars = encode(cx, caCertificateString, &caCertificate_len);
191196
caCertificate = std::string(caCertificateChars.get(), caCertificate_len);
197+
backend_config.ca_cert.val.ptr = const_cast<char *>(caCertificate.c_str());
198+
backend_config.ca_cert.val.len = caCertificate.length();
192199
}
193200

194-
std::optional<std::string> ciphers;
201+
std::string ciphers;
195202
auto ciphersSlot = JS::GetReservedSlot(backend, Backend::Slots::Ciphers);
196-
if (!ciphersSlot.isNullOrUndefined()) {
203+
if ((backend_config.ciphers.is_some = !ciphersSlot.isNullOrUndefined())) {
197204
JS::RootedString ciphersString(cx, ciphersSlot.toString());
198205
size_t ciphers_len;
199206
JS::UniqueChars ciphersChars = encode(cx, ciphersString, &ciphers_len);
200207
ciphers = std::string(ciphersChars.get(), ciphers_len);
208+
backend_config.ciphers.val.ptr = const_cast<char *>(ciphers.c_str());
209+
backend_config.ciphers.val.len = ciphers.length();
201210
}
202211

203-
std::optional<std::string> sniHostname;
212+
std::string sniHostname;
204213
auto sniHostnameSlot = JS::GetReservedSlot(backend, Backend::Slots::SniHostname);
205-
if (!sniHostnameSlot.isNullOrUndefined()) {
214+
if ((backend_config.sni_hostname.is_some = !sniHostnameSlot.isNullOrUndefined())) {
206215
JS::RootedString sniHostnameString(cx, sniHostnameSlot.toString());
207216
size_t sniHostname_len;
208217
JS::UniqueChars sniHostnameChars = encode(cx, sniHostnameString, &sniHostname_len);
209218
sniHostname = std::string(sniHostnameChars.get(), sniHostname_len);
219+
backend_config.sni_hostname.val.ptr = const_cast<char *>(sniHostname.c_str());
220+
backend_config.sni_hostname.val.len = sniHostname.length();
210221
}
211222

212-
auto useSslSlot = JS::GetReservedSlot(backend, Backend::Slots::UseSsl);
213-
if (!useSslSlot.isNullOrUndefined() && useSslSlot.toBoolean()) {
214-
backend_config_mask |= BACKEND_CONFIG_USE_SSL;
215-
}
216-
217-
JS::RootedString name(cx, JS::GetReservedSlot(backend, Backend::Slots::Name).toString());
218-
size_t name_len;
219-
JS::UniqueChars nameChars = encode(cx, name, &name_len);
220-
auto name_cstr = nameChars.get();
221-
222-
JS::RootedString target(cx, JS::GetReservedSlot(backend, Backend::Slots::Target).toString());
223-
size_t target_len;
224-
JS::UniqueChars targetChars = encode(cx, target, &target_len);
225-
auto target_cstr = targetChars.get();
226-
if (hostOverride.has_value()) {
227-
backend_config_mask |= BACKEND_CONFIG_HOST_OVERRIDE;
228-
definition.host_override = hostOverride.value().c_str();
229-
definition.host_override_len = hostOverride.value().length();
230-
}
231-
if (certificateHostname.has_value()) {
232-
backend_config_mask |= BACKEND_CONFIG_CERT_HOSTNAME;
233-
definition.cert_hostname = certificateHostname.value().c_str();
234-
definition.cert_hostname_len = certificateHostname.value().length();
235-
}
236-
if (caCertificate.has_value()) {
237-
backend_config_mask |= BACKEND_CONFIG_CA_CERT;
238-
definition.ca_cert = caCertificate.value().c_str();
239-
definition.ca_cert_len = caCertificate.value().length();
240-
}
241-
if (ciphers.has_value()) {
242-
backend_config_mask |= BACKEND_CONFIG_CIPHERS;
243-
definition.ciphers = ciphers.value().c_str();
244-
definition.ciphers_len = ciphers.value().length();
245-
}
246-
if (sniHostname.has_value()) {
247-
backend_config_mask |= BACKEND_CONFIG_SNI_HOSTNAME;
248-
definition.sni_hostname = sniHostname.value().c_str();
249-
definition.sni_hostname_len = sniHostname.value().length();
250-
}
251-
252-
auto result = xqd_req_register_dynamic_backend(name_cstr, name_len, target_cstr, target_len,
253-
backend_config_mask, &definition);
254-
if (!HANDLE_RESULT(cx, result)) {
223+
fastly_error_t err;
224+
auto result =
225+
xqd_fastly_http_req_register_dynamic_backend(&name_str, &target_str, &backend_config, &err);
226+
if (!HANDLE_RESULT(cx, result, err)) {
255227
return JS::Result<mozilla::Ok>(JS::Error());
256228
} else {
257229
return mozilla::Ok();

c-dependencies/js-compute-runtime/builtins/cache-override.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,22 +64,22 @@ void CacheOverride::set_pci(JSObject *self, bool pci) {
6464
JS::SetReservedSlot(self, CacheOverride::Slots::PCI, JS::BooleanValue(pci));
6565
}
6666

67-
uint32_t CacheOverride::abi_tag(JSObject *self) {
67+
uint8_t CacheOverride::abi_tag(JSObject *self) {
6868
switch (CacheOverride::mode(self)) {
6969
case CacheOverride::CacheOverrideMode::None:
70-
return (uint32_t)CacheOverrideTag::None;
70+
return (uint8_t)CacheOverrideTag::None;
7171
case CacheOverride::CacheOverrideMode::Pass:
72-
return (uint32_t)CacheOverrideTag::Pass;
72+
return (uint8_t)CacheOverrideTag::Pass;
7373
default:;
7474
}
7575

76-
uint32_t tag = 0;
76+
uint8_t tag = 0;
7777
if (!ttl(self).isUndefined())
78-
tag |= (uint32_t)CacheOverrideTag::TTL;
78+
tag |= (uint8_t)CacheOverrideTag::TTL;
7979
if (!swr(self).isUndefined())
80-
tag |= (uint32_t)CacheOverrideTag::SWR;
80+
tag |= (uint8_t)CacheOverrideTag::SWR;
8181
if (!pci(self).isUndefined())
82-
tag |= (uint32_t)CacheOverrideTag::PCI;
82+
tag |= (uint8_t)CacheOverrideTag::PCI;
8383

8484
return tag;
8585
}

c-dependencies/js-compute-runtime/builtins/cache-override.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class CacheOverride : public BuiltinImpl<CacheOverride> {
4141

4242
static const JSFunctionSpec methods[];
4343
static const JSPropertySpec properties[];
44-
static uint32_t abi_tag(JSObject *self);
44+
static uint8_t abi_tag(JSObject *self);
4545
static JS::Value ttl(JSObject *self);
4646
static void set_ttl(JSObject *self, uint32_t ttl);
4747
static JS::Value swr(JSObject *self);

0 commit comments

Comments
 (0)