W5
This commit is contained in:
+13
-1
@@ -860,13 +860,25 @@ void compile_shared_unit(Request* context, SharedUnit* su)
|
||||
));
|
||||
|
||||
if(su->compiler_messages.length() == 0 && !su->opt_so_optional && compiler_wasm_unit_compile_enabled(context))
|
||||
su->compiler_messages = trim(shell_exec(shell_escape(compiler_wasm_compile_script(context))+" "+
|
||||
{
|
||||
// The wasm side-module build is best-effort: a unit that cannot compile
|
||||
// to wasm (e.g. try/catch) still works via the native .so and falls back
|
||||
// to native at request time. Record the failure, never fail the unit on
|
||||
// it. On failure, remove any stale .wasm so the backend won't serve it.
|
||||
String wasm_messages = trim(shell_exec(shell_escape(compiler_wasm_compile_script(context))+" "+
|
||||
shell_escape(su->src_path)+" "+
|
||||
shell_escape(su->bin_path)+" "+
|
||||
shell_escape(su->file_name)+" "+
|
||||
shell_escape(su->pre_file_name)+" "+
|
||||
shell_escape(su->wasm_file_name)
|
||||
));
|
||||
if(wasm_messages.length() > 0)
|
||||
{
|
||||
file_put_contents(su->wasm_check_file_name, wasm_messages + "\n");
|
||||
file_unlink(su->wasm_name);
|
||||
printf("(i) wasm side-module unavailable for %s (native .so serves it)\n", su->file_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if(su->compiler_messages.length() > 0)
|
||||
{
|
||||
|
||||
+45
-17
@@ -642,41 +642,69 @@ StringList regex_split(String pattern, String subject, String flags)
|
||||
|
||||
#else
|
||||
|
||||
// PCRE2 is not compiled into the wasm core; regex runs host-side (the host
|
||||
// already links libpcre2). One UCEB1-marshalled hostcall carries the request
|
||||
// {op,pattern,subject,flags,replacement} in and the result tree out — the host
|
||||
// runs the real regex_* and packs the answer. See uce_host_regex in
|
||||
// src/wasm/worker.cpp.
|
||||
extern "C" size_t uce_host_regex(const char* in, size_t in_len, char* out, size_t cap);
|
||||
|
||||
static DValue wasm_regex_call(String op, String pattern, String subject, String flags, String replacement = "")
|
||||
{
|
||||
DValue request;
|
||||
request["op"] = op;
|
||||
request["pattern"] = pattern;
|
||||
request["subject"] = subject;
|
||||
request["flags"] = flags;
|
||||
request["replacement"] = replacement;
|
||||
String encoded = ucb_encode(request);
|
||||
size_t need = uce_host_regex(encoded.data(), encoded.size(), 0, 0);
|
||||
if(need == 0)
|
||||
return(DValue());
|
||||
String buffer(need, 0);
|
||||
size_t got = uce_host_regex(encoded.data(), encoded.size(), &buffer[0], need);
|
||||
if(got == 0 || got > need)
|
||||
return(DValue());
|
||||
DValue response;
|
||||
String error;
|
||||
ucb_decode(String(buffer.data(), got), response, &error);
|
||||
return(response);
|
||||
}
|
||||
|
||||
bool regex_match(String pattern, String subject, String flags)
|
||||
{
|
||||
(void)pattern; (void)subject; (void)flags;
|
||||
return(false);
|
||||
return(wasm_regex_call("match", pattern, subject, flags)["bool"].to_bool());
|
||||
}
|
||||
|
||||
DValue regex_search(String pattern, String subject, String flags)
|
||||
{
|
||||
DValue result;
|
||||
result["matched"].set_bool(false);
|
||||
result["pattern"] = pattern;
|
||||
result["flags"] = flags == "" ? "default" : flags;
|
||||
return(result);
|
||||
DValue response = wasm_regex_call("search", pattern, subject, flags);
|
||||
DValue* tree = response.key("tree");
|
||||
return(tree ? *tree : DValue());
|
||||
}
|
||||
|
||||
DValue regex_search_all(String pattern, String subject, String flags)
|
||||
{
|
||||
DValue result;
|
||||
result["matched"].set_bool(false);
|
||||
result["pattern"] = pattern;
|
||||
result["flags"] = flags == "" ? "default" : flags;
|
||||
result["count"] = (f64)0;
|
||||
return(result);
|
||||
DValue response = wasm_regex_call("search_all", pattern, subject, flags);
|
||||
DValue* tree = response.key("tree");
|
||||
return(tree ? *tree : DValue());
|
||||
}
|
||||
|
||||
String regex_replace(String pattern, String replacement, String subject, String flags)
|
||||
{
|
||||
(void)pattern; (void)replacement; (void)flags;
|
||||
return(subject);
|
||||
return(wasm_regex_call("replace", pattern, subject, flags, replacement)["text"].to_string());
|
||||
}
|
||||
|
||||
StringList regex_split(String pattern, String subject, String flags)
|
||||
{
|
||||
(void)pattern; (void)flags;
|
||||
return(StringList{ subject });
|
||||
DValue response = wasm_regex_call("split", pattern, subject, flags);
|
||||
StringList result;
|
||||
DValue* list = response.key("list");
|
||||
if(list)
|
||||
list->each([&](const DValue& part, String) {
|
||||
result.push_back(part.to_string());
|
||||
});
|
||||
return(result);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+17
-3
@@ -14,6 +14,8 @@ void uce_host_log(int level, const char* buf, size_t len);
|
||||
// cwd convention); file_read uses the length-query convention
|
||||
int uce_host_file_exists(const char* path, size_t path_len, const char* current, size_t current_len);
|
||||
size_t uce_host_file_read(const char* path, size_t path_len, const char* current, size_t current_len, char* buf, size_t cap);
|
||||
int uce_host_file_write(const char* path, size_t path_len, const char* current, size_t current_len, const char* content, size_t content_len, int append);
|
||||
void uce_host_file_unlink(const char* path, size_t path_len, const char* current, size_t current_len);
|
||||
}
|
||||
|
||||
static String wasm_current_unit_file()
|
||||
@@ -50,13 +52,25 @@ String file_get_contents(String file_name)
|
||||
content.resize(got <= required ? got : 0);
|
||||
return(content);
|
||||
}
|
||||
bool file_put_contents(String file_name, String content) { (void)file_name; (void)content; return(false); }
|
||||
bool file_append_contents(String file_name, String content) { (void)file_name; (void)content; return(false); }
|
||||
bool file_put_contents(String file_name, String content)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
return(uce_host_file_write(file_name.data(), file_name.size(), current.data(), current.size(), content.data(), content.size(), 0) != 0);
|
||||
}
|
||||
bool file_append_contents(String file_name, String content)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
return(uce_host_file_write(file_name.data(), file_name.size(), current.data(), current.size(), content.data(), content.size(), 1) != 0);
|
||||
}
|
||||
String cwd_get() { return("/"); }
|
||||
void cwd_set(String path) { (void)path; }
|
||||
String process_start_directory() { return("/"); }
|
||||
time_t file_mtime(String file_name) { (void)file_name; return(0); }
|
||||
void file_unlink(String file_name) { (void)file_name; }
|
||||
void file_unlink(String file_name)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
uce_host_file_unlink(file_name.data(), file_name.size(), current.data(), current.size());
|
||||
}
|
||||
String expand_path(String path, String relative_to_path) { return(path_join(relative_to_path, path)); }
|
||||
StringList ls(String dir) { (void)dir; return(StringList()); }
|
||||
u64 config_map_u64(StringMap& cfg, String key, u64 fallback) { String raw = first(cfg[key], std::to_string(fallback)); char* end = 0; unsigned long long v = strtoull(raw.c_str(), &end, 10); return(end && *end == 0 ? (u64)v : fallback); }
|
||||
|
||||
@@ -12,6 +12,16 @@
|
||||
#include "uri.cpp"
|
||||
#include "cli.cpp"
|
||||
|
||||
#ifdef __UCE_WASM_CORE__
|
||||
// markdown is pure compute (no PCRE/syscalls/regex) — it belongs in the wasm
|
||||
// core so markdown_to_html/markdown_to_ast render in-workspace. compiler.cpp
|
||||
// (which declares component() ahead of markdown in the native build) is carved
|
||||
// out here, and the wasm core defines component() later in src/wasm/core.cpp,
|
||||
// so markdown just needs the forward declaration.
|
||||
String component(String name, DValue props, Request& context);
|
||||
#include "markdown.cpp"
|
||||
#endif
|
||||
|
||||
#ifndef __UCE_WASM_CORE__
|
||||
#include "compiler-parser.cpp"
|
||||
#include "compiler.cpp"
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if defined(__GNUG__)
|
||||
// The demangler is a host-side nicety for trap traces. wasi-libc++ does not
|
||||
// provide __cxa_demangle, and a wasm unit that merely includes uce_lib.h must
|
||||
// not pull it in as an unresolvable import — so it is host-only.
|
||||
#if defined(__GNUG__) && !defined(__wasm__)
|
||||
#define UCE_WASM_TRACE_HAVE_DEMANGLE 1
|
||||
#include <cxxabi.h>
|
||||
#endif
|
||||
|
||||
@@ -30,7 +34,7 @@ struct WasmTraceSummary
|
||||
|
||||
inline std::string wasm_trace_demangle(const std::string& name)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
#if defined(UCE_WASM_TRACE_HAVE_DEMANGLE)
|
||||
// frame names look like "module!symbol"; demangle the symbol part
|
||||
auto bang = name.find('!');
|
||||
std::string prefix = bang == std::string::npos ? "" : name.substr(0, bang + 1);
|
||||
|
||||
Reference in New Issue
Block a user