Compare commits

...

6 Commits

Author SHA1 Message Date
Ben Visness b07db61938 Add Mac implementation of oc_run_cmd
so much easier than windows, oh my goodness
2023-10-01 10:40:42 -05:00
Ben Visness d74f67f9a8 Embiggen stack 2023-09-28 20:29:13 -05:00
Ben Visness caed72856e Include empty strings in oc_str8_split 2023-09-28 20:28:51 -05:00
Ben Visness 8d915f03bf Ignore clangd .cache 2023-09-27 21:21:10 -05:00
Ben Visness 4507ec33aa Vendor all kinds of stuff, fix subprocess chunk issue 2023-09-27 21:20:33 -05:00
Ben Visness d502f35da4 Add oc_run_cmd 2023-09-27 15:53:15 -05:00
21 changed files with 768 additions and 163 deletions

View File

@ -26,7 +26,6 @@ BraceWrapping:
AfterNamespace: true AfterNamespace: true
AfterObjCDeclaration: true AfterObjCDeclaration: true
AfterStruct: true AfterStruct: true
AfterObjCDeclaration: true
AfterUnion: true AfterUnion: true
BeforeCatch: true BeforeCatch: true
BeforeElse: true BeforeElse: true

1
.gitignore vendored
View File

@ -33,6 +33,7 @@ src/graphics/orca_gl31.h
.vscode/settings.json .vscode/settings.json
__pycache__ __pycache__
/.cache
scripts/files scripts/files
# explicitly abandon old ext dir # explicitly abandon old ext dir

View File

@ -19,7 +19,7 @@ set STDLIB_DIR=%ORCA_DIR%\src\libc-shim
set wasmFlags=--target=wasm32^ set wasmFlags=--target=wasm32^
--no-standard-libraries ^ --no-standard-libraries ^
-mbulk-memory ^ -mbulk-memory ^
-g -O2 ^ -g ^
-D__ORCA__ ^ -D__ORCA__ ^
-Wl,--no-entry ^ -Wl,--no-entry ^
-Wl,--export-dynamic ^ -Wl,--export-dynamic ^

View File

@ -7,6 +7,7 @@ import subprocess
from argparse import ArgumentParser from argparse import ArgumentParser
from .log import * from .log import *
from .version import install_dir
def attach_bundle_commands(subparsers): def attach_bundle_commands(subparsers):

View File

@ -0,0 +1,74 @@
[
{
"directory": "{{ORCAROOT}}",
"file": "src/orca.c",
"arguments": [
"src/orca.c",
"-g",
"-D",
"OC_DEBUG",
"-D",
"OC_LOG_COMPILE_DEBUG",
"-c",
"-std=c11",
"-I",
"src",
"-I",
"src/util",
"-I",
"src/platform",
"-I",
"src/ext",
"-I",
"src/ext/angle/include"
]
},
{
"directory": "{{ORCAROOT}}",
"file": "src/orca.m",
"arguments": [
"-xobjective-c",
"src/orca.m",
"-g",
"-D",
"OC_DEBUG",
"-D",
"OC_LOG_COMPILE_DEBUG",
"-c",
"-I",
"src",
"-I",
"src/util",
"-I",
"src/platform",
"-I",
"src/ext",
"-I",
"src/ext/angle/include"
]
},
{
"directory": "{{ORCAROOT}}",
"file": "src/runtime.c",
"arguments": [
"src/runtime.c",
"-g",
"-D",
"OC_DEBUG",
"-D",
"OC_LOG_COMPILE_DEBUG",
"-I",
"src",
"-I",
"src/ext",
"-I",
"src/ext/angle/include",
"-I",
"src/ext/wasm3/source",
"-Lbuild/bin",
"-Lbuild/lib",
"-lorca",
"-lwasm3"
]
}
]

View File

@ -1,7 +1,7 @@
import glob import glob
import json
import os import os
import platform import platform
import re
import urllib.request import urllib.request
import shutil import shutil
import subprocess import subprocess
@ -63,6 +63,8 @@ def build_runtime(args):
ensure_programs() ensure_programs()
ensure_angle() ensure_angle()
plonk_compile_commands()
build_platform_layer("lib", args.release) build_platform_layer("lib", args.release)
build_wasm3(args.release) build_wasm3(args.release)
build_orca(args.release) build_orca(args.release)
@ -90,6 +92,14 @@ def clean(args):
yeetdir("scripts/__pycache__") yeetdir("scripts/__pycache__")
def plonk_compile_commands():
os.makedirs("build", exist_ok=True)
with open("scripts/compile_commands.template.json") as infile:
out = infile.read().replace(r'"{{ORCAROOT}}"', json.dumps(os.getcwd()))
with open("build/compile_commands.json", "w") as outfile:
outfile.write(out)
def build_platform_layer(target, release): def build_platform_layer(target, release):
print("Building Orca platform layer...") print("Building Orca platform layer...")
@ -344,7 +354,7 @@ def build_orca_mac(release):
"-Isrc/ext/wasm3/source" "-Isrc/ext/wasm3/source"
] ]
libs = ["-Lbuild/bin", "-Lbuild/lib", "-lorca", "-lwasm3"] libs = ["-Lbuild/bin", "-Lbuild/lib", "-lorca", "-lwasm3"]
debug_flags = ["-O2"] if release else ["-g", "-DOC_DEBUG -DOC_LOG_COMPILE_DEBUG"] debug_flags = ["-O2"] if release else ["-g", "-DOC_DEBUG", "-DOC_LOG_COMPILE_DEBUG"]
flags = [ flags = [
*debug_flags, *debug_flags,
"-mmacos-version-min=10.15.4"] "-mmacos-version-min=10.15.4"]
@ -376,22 +386,18 @@ def gen_all_bindings():
"src/wasmbind/gles_api.json", "src/wasmbind/gles_api.json",
"src/graphics/orca_gl31.h" "src/graphics/orca_gl31.h"
) )
bindgen("gles", "src/wasmbind/gles_api.json", bindgen("gles", "src/wasmbind/gles_api.json",
wasm3_bindings="src/wasmbind/gles_api_bind_gen.c", wasm3_bindings="src/wasmbind/gles_api_bind_gen.c",
) )
bindgen("core", "src/wasmbind/core_api.json", bindgen("core", "src/wasmbind/core_api.json",
guest_stubs="src/wasmbind/core_api_stubs.c", guest_stubs="src/wasmbind/core_api_stubs.c",
wasm3_bindings="src/wasmbind/core_api_bind_gen.c", wasm3_bindings="src/wasmbind/core_api_bind_gen.c",
) )
bindgen("surface", "src/wasmbind/surface_api.json", bindgen("surface", "src/wasmbind/surface_api.json",
guest_stubs="src/graphics/orca_surface_stubs.c", guest_stubs="src/graphics/orca_surface_stubs.c",
guest_include="graphics/graphics.h", guest_include="graphics/graphics.h",
wasm3_bindings="src/wasmbind/surface_api_bind_gen.c", wasm3_bindings="src/wasmbind/surface_api_bind_gen.c",
) )
bindgen("clock", "src/wasmbind/clock_api.json", bindgen("clock", "src/wasmbind/clock_api.json",
guest_include="platform/platform_clock.h", guest_include="platform/platform_clock.h",
wasm3_bindings="src/wasmbind/clock_api_bind_gen.c", wasm3_bindings="src/wasmbind/clock_api_bind_gen.c",
@ -400,6 +406,10 @@ def gen_all_bindings():
guest_stubs="src/platform/orca_io_stubs.c", guest_stubs="src/platform/orca_io_stubs.c",
wasm3_bindings="src/wasmbind/io_api_bind_gen.c", wasm3_bindings="src/wasmbind/io_api_bind_gen.c",
) )
bindgen("subprocess", "src/wasmbind/subprocess_api.json",
guest_stubs="src/wasmbind/subprocess_api_stubs.c",
wasm3_bindings="src/wasmbind/subprocess_api_bind_gen.c",
)
def ensure_programs(): def ensure_programs():
@ -565,6 +575,8 @@ def install(args):
dest = install_dir() dest = install_dir()
bin_dir = os.path.join(dest, "bin") bin_dir = os.path.join(dest, "bin")
src_dir = os.path.join(dest, "src") src_dir = os.path.join(dest, "src")
runtime_dir = os.path.join(dest, "build", "bin")
resources_dir = os.path.join(dest, "resources")
version_file = os.path.join(dest, ".orcaversion") version_file = os.path.join(dest, ".orcaversion")
version = orca_version() version = orca_version()
@ -587,6 +599,8 @@ def install(args):
yeetdir(bin_dir) yeetdir(bin_dir)
yeetdir(src_dir) yeetdir(src_dir)
yeetdir(runtime_dir)
yeetdir(resources_dir)
yeetfile(version_file) yeetfile(version_file)
# The MS Store version of Python does some really stupid stuff with AppData: # The MS Store version of Python does some really stupid stuff with AppData:
@ -607,6 +621,8 @@ def install(args):
shutil.copytree("scripts", os.path.join(bin_dir, "sys_scripts")) shutil.copytree("scripts", os.path.join(bin_dir, "sys_scripts"))
shutil.copy("orca", bin_dir) shutil.copy("orca", bin_dir)
shutil.copytree("src", src_dir, dirs_exist_ok=True) shutil.copytree("src", src_dir, dirs_exist_ok=True)
shutil.copytree(os.path.join("build", "bin"), runtime_dir, dirs_exist_ok=True)
shutil.copytree("resources", resources_dir, dirs_exist_ok=True)
if platform.system() == "Windows": if platform.system() == "Windows":
shutil.copy("orca.bat", bin_dir) shutil.copy("orca.bat", bin_dir)
with open(version_file, "w") as f: with open(version_file, "w") as f:

View File

@ -7,7 +7,7 @@ import shutil
from .checksum import dirsum from .checksum import dirsum
from .log import * from .log import *
from .utils import yeetdir from .utils import yeetdir
from .version import src_dir, orca_version from .version import orca_version, install_dir
def attach_source_commands(subparsers): def attach_source_commands(subparsers):
@ -15,7 +15,7 @@ def attach_source_commands(subparsers):
source_sub = source_cmd.add_subparsers(required=True, title="commands") source_sub = source_cmd.add_subparsers(required=True, title="commands")
cflags_cmd = source_sub.add_parser("cflags", help="Get help setting up a C or C++ compiler to compile the Orca source.") cflags_cmd = source_sub.add_parser("cflags", help="Get help setting up a C or C++ compiler to compile the Orca source.")
cflags_cmd.add_argument("srcdir", nargs="?", default=src_dir(), help="the directory containing the Orca source code (defaults to system installation)") cflags_cmd.add_argument("srcdir", nargs="?", default=path_in_install("src"), help="the directory containing the Orca source code (defaults to system installation)")
cflags_cmd.set_defaults(func=shellish(cflags)) cflags_cmd.set_defaults(func=shellish(cflags))
vendor_cmd = source_sub.add_parser("vendor", help="Copy the Orca source code into your project.") vendor_cmd = source_sub.add_parser("vendor", help="Copy the Orca source code into your project.")
@ -23,6 +23,10 @@ def attach_source_commands(subparsers):
vendor_cmd.set_defaults(func=shellish(vendor)) vendor_cmd.set_defaults(func=shellish(vendor))
def path_in_install(path):
return os.path.join(install_dir(), path)
def vendor(args): def vendor(args):
# Verify that we are ok to vendor into the requested dir. # Verify that we are ok to vendor into the requested dir.
if os.path.exists(args.dir): if os.path.exists(args.dir):
@ -41,12 +45,19 @@ def vendor(args):
exit(1) exit(1)
yeetdir(args.dir) yeetdir(args.dir)
shutil.copytree(src_dir(), args.dir)
vendor_src = os.path.join(args.dir, "src")
vendor_runtime = os.path.join(args.dir, "build", "bin")
vendor_resources = os.path.join(args.dir, "resources")
shutil.copytree(path_in_install("src"), vendor_src)
shutil.copytree(path_in_install("build/bin"), vendor_runtime)
shutil.copytree(path_in_install("resources"), vendor_resources)
with open(vendor_file_path(args.dir), "w") as f: with open(vendor_file_path(args.dir), "w") as f:
json.dump({ json.dump({
"version": orca_version(), "version": orca_version(),
"checksum": vendor_checksum(args.dir), "checksum": vendor_checksum(args.dir),
}, f, indent=2) }, f, indent=2)
print(f"Version {orca_version()} of the Orca source code has been copied to {args.dir}.") print(f"Version {orca_version()} of the Orca source code has been copied to {args.dir}.")

View File

@ -38,20 +38,13 @@ def is_orca_source():
return use_source return use_source
def actual_install_dir(): def install_dir():
# The path adjustment in here is technically sort of fragile because it depends # The path adjustment in here is technically sort of fragile because it depends
# on the current location of this actual file. But oh well. # on the current location of this actual file. But oh well.
if is_orca_source(): if is_orca_source():
raise Exception("actual_install_dir should not be called when using the source version of the Orca tools") return os.path.normpath(os.path.join(os.path.abspath(__file__), "../.."))
return os.path.normpath(os.path.join(os.path.abspath(__file__), "../../.."))
def src_dir():
# More fragile path adjustments! Yay!
if is_orca_source():
return os.path.normpath(os.path.join(os.path.abspath(__file__), "../../src"))
else: else:
return os.path.normpath(os.path.join(os.path.abspath(__file__), "../../../src")) return os.path.normpath(os.path.join(os.path.abspath(__file__), "../../.."))
def orca_version(): def orca_version():
@ -68,7 +61,7 @@ def orca_version():
return f"dev-{version}" return f"dev-{version}"
else: else:
try: try:
with open(os.path.join(actual_install_dir(), ".orcaversion"), "r") as f: with open(os.path.join(install_dir(), ".orcaversion"), "r") as f:
version = f.read().strip() version = f.read().strip()
return version return version
except FileNotFoundError: except FileNotFoundError:
@ -92,4 +85,4 @@ def print_orca_version(args):
sys.stderr.write(f"Source dir: {source_dir}\n") sys.stderr.write(f"Source dir: {source_dir}\n")
else: else:
sys.stderr.write(f"Orca is running from a system installation.\n") sys.stderr.write(f"Orca is running from a system installation.\n")
sys.stderr.write(f"Install dir: {actual_install_dir()}\n") sys.stderr.write(f"Install dir: {install_dir()}\n")

View File

@ -20,6 +20,7 @@
#include "platform/win32_io.c" #include "platform/win32_io.c"
#include "platform/win32_thread.c" #include "platform/win32_thread.c"
#include "platform/win32_platform.c" #include "platform/win32_platform.c"
#include "platform/win32_subprocess.c"
//TODO //TODO
#elif OC_PLATFORM_MACOS #elif OC_PLATFORM_MACOS
#include "platform/native_debug.c" #include "platform/native_debug.c"
@ -28,6 +29,7 @@
#include "platform/posix_io.c" #include "platform/posix_io.c"
#include "platform/posix_thread.c" #include "platform/posix_thread.c"
#include "platform/osx_platform.c" #include "platform/osx_platform.c"
#include "platform/osx_subprocess.c"
/* /*
#include"platform/unix_rng.c" #include"platform/unix_rng.c"
@ -53,6 +55,7 @@
#include "platform/orca_io_stubs.c" #include "platform/orca_io_stubs.c"
#include "platform/orca_platform.c" #include "platform/orca_platform.c"
#include "platform/platform_path.c" #include "platform/platform_path.c"
#include "platform/orca_subprocess.c"
#else #else
#error "Unsupported platform" #error "Unsupported platform"
#endif #endif
@ -98,6 +101,7 @@
#elif OC_PLATFORM_ORCA #elif OC_PLATFORM_ORCA
#include "app/orca_app.c" #include "app/orca_app.c"
#include "wasmbind/core_api_stubs.c" #include "wasmbind/core_api_stubs.c"
#include "wasmbind/subprocess_api_stubs.c"
#include "graphics/graphics_common.c" #include "graphics/graphics_common.c"
#include "graphics/orca_surface_stubs.c" #include "graphics/orca_surface_stubs.c"
#else #else

View File

@ -23,6 +23,7 @@
#include "platform/platform_io.h" #include "platform/platform_io.h"
#include "platform/platform_io_dialog.h" #include "platform/platform_io_dialog.h"
#include "platform/platform_path.h" #include "platform/platform_path.h"
#include "platform/platform_subprocess.h"
#if !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA) #if !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA)
#include "platform/platform_thread.h" #include "platform/platform_thread.h"

View File

@ -0,0 +1,11 @@
/*************************************************************************
*
* Orca
* Copyright 2023 Martin Fouilleul and the Orca project contributors
* See LICENSE.txt for licensing information
*
**************************************************************************/
#include "platform_subprocess.h"
#include "util/typedefs.h"
oc_str8 ORCA_IMPORT(oc_run_cmd)(oc_arena* arena, oc_str8 cmd);

View File

@ -0,0 +1,60 @@
/*************************************************************************
*
* Orca
* Copyright 2023 Martin Fouilleul and the Orca project contributors
* See LICENSE.txt for licensing information
*
**************************************************************************/
#include "platform_subprocess.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
oc_str8 oc_run_cmd(oc_arena* arena, oc_str8 cmd)
{
const char* cmdC = oc_str8_to_cstring(arena, cmd);
FILE* p = popen(cmdC, "r+");
if(!p)
{
oc_log_error("failed to launch process");
return OC_STR8("");
}
oc_str8_list chunks = { 0 };
char buffer[1024];
while(true)
{
ssize_t nRead = read(fileno(p), buffer, sizeof(buffer));
if(nRead < 0)
{
oc_log_error("failed to read from process's stdout\n");
return OC_STR8("");
}
if(nRead == 0)
{
break;
}
oc_str8 chunk = oc_str8_from_buffer(nRead, buffer);
oc_str8_list_push(arena, &chunks, oc_str8_push_copy(arena, chunk));
}
int status = pclose(p);
if(status == -1)
{
oc_log_warning("failed to close subprocess\n");
}
else if(!WIFEXITED(status))
{
oc_log_warning("subprocess did not exit correctly\n");
}
return oc_str8_list_join(arena, chunks);
}
#ifdef __cplusplus
} // extern "C"
#endif

View File

@ -0,0 +1,24 @@
/*************************************************************************
*
* Orca
* Copyright 2023 Martin Fouilleul and the Orca project contributors
* See LICENSE.txt for licensing information
*
**************************************************************************/
#ifndef __PLATFORM_SUBPROCESS_H
#define __PLATFORM_SUBPROCESS_H
#include "platform.h"
#include "util/strings.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
ORCA_API oc_str8 oc_run_cmd(oc_arena* arena, oc_str8 cmd);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // __PLATFORM_SUBPROCESS_H

View File

@ -0,0 +1,136 @@
/*************************************************************************
*
* Orca
* Copyright 2023 Martin Fouilleul and the Orca project contributors
* See LICENSE.txt for licensing information
*
**************************************************************************/
#include "platform_subprocess.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
oc_str8 oc_run_cmd(oc_arena* arena, oc_str8 cmd)
{
oc_arena_scope scratch = oc_scratch_begin();
oc_str8 out = { 0 };
HANDLE childStdinRd = NULL;
HANDLE childStdinWr = NULL;
HANDLE childStdoutRd = NULL;
HANDLE childStdoutWr = NULL;
// Create child process's stdin and stdout pipes
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.lpSecurityDescriptor = NULL;
saAttr.bInheritHandle = TRUE;
if(!CreatePipe(&childStdinRd, &childStdinWr,
&saAttr, 0)
|| !SetHandleInformation(childStdinWr, HANDLE_FLAG_INHERIT, 0))
{
oc_log_error("failed to create child stdin\n");
goto error;
}
if(!CreatePipe(&childStdoutRd, &childStdoutWr,
&saAttr, 0)
|| !SetHandleInformation(childStdoutRd, HANDLE_FLAG_INHERIT, 0))
{
oc_log_error("failed to create child stdout\n");
goto error;
}
// Create child process
char* cmdStr = oc_str8_to_cstring(scratch.arena, cmd);
PROCESS_INFORMATION procInfo;
STARTUPINFO startInfo;
memset(&procInfo, 0, sizeof(PROCESS_INFORMATION));
memset(&startInfo, 0, sizeof(STARTUPINFO));
startInfo.cb = sizeof(STARTUPINFO);
startInfo.hStdInput = childStdinRd;
startInfo.hStdOutput = childStdoutWr;
startInfo.hStdError = childStdoutWr;
startInfo.dwFlags |= STARTF_USESTDHANDLES;
BOOL success = CreateProcess(
NULL,
cmdStr,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&startInfo,
&procInfo);
if(!success)
{
oc_log_error("failed to create child process\n");
goto error;
}
CloseHandle(procInfo.hProcess);
CloseHandle(procInfo.hThread);
CloseHandle(childStdinRd); // the parent does not need these ends of the pipes
CloseHandle(childStdoutWr);
// TODO: Optionally write to the child's stdin
if(!CloseHandle(childStdinWr))
{
oc_log_error("failed to close child's stdin");
goto error;
}
// Read child's combined stdout/stderr
u64 outputLen = 0;
char* outputBuf = NULL;
while(true)
{
// TODO: apply smartness to this number
#define CHUNK_SIZE 1024
char chunkBuf[CHUNK_SIZE];
DWORD nRead;
BOOL success = ReadFile(childStdoutRd, chunkBuf, CHUNK_SIZE, &nRead, NULL);
if(!success || nRead == 0)
{
break;
}
char* dst = oc_arena_push(arena, nRead);
if(!outputBuf)
{
outputBuf = dst;
}
memcpy(dst, chunkBuf, nRead);
outputLen += nRead;
}
out = oc_str8_from_buffer(outputLen, outputBuf);
CloseHandle(childStdinWr);
CloseHandle(childStdoutRd);
goto cleanup;
error:
LPVOID msgBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&msgBuf,
0, NULL);
oc_log_error("%s\n", msgBuf);
LocalFree(msgBuf);
cleanup:
oc_scratch_end(scratch);
return out;
}

View File

@ -15,6 +15,7 @@
#include "runtime.h" #include "runtime.h"
#include "runtime_clipboard.c" #include "runtime_clipboard.c"
#include "runtime_subprocess.c"
#include "runtime_io.c" #include "runtime_io.c"
#include "runtime_memory.c" #include "runtime_memory.c"
@ -216,6 +217,12 @@ void oc_bridge_request_quit(void)
__orcaApp.quit = true; __orcaApp.quit = true;
} }
// TODO: wait why do I have this bridge
oc_wasm_str8 oc_bridge_run_cmd(oc_wasm_addr wasmArena, oc_wasm_str8 cmd)
{
return oc_runtime_run_cmd(wasmArena, cmd);
}
typedef struct orca_surface_create_data typedef struct orca_surface_create_data
{ {
oc_window window; oc_window window;
@ -403,6 +410,7 @@ void oc_wasm_env_init(oc_wasm_env* runtime)
#include "wasmbind/io_api_bind_gen.c" #include "wasmbind/io_api_bind_gen.c"
#include "wasmbind/surface_api_bind_manual.c" #include "wasmbind/surface_api_bind_manual.c"
#include "wasmbind/surface_api_bind_gen.c" #include "wasmbind/surface_api_bind_gen.c"
#include "wasmbind/subprocess_api_bind_gen.c"
i32 orca_runloop(void* user) i32 orca_runloop(void* user)
{ {
@ -431,7 +439,7 @@ i32 orca_runloop(void* user)
fread(app->env.wasmBytecode.ptr, 1, app->env.wasmBytecode.len, file); fread(app->env.wasmBytecode.ptr, 1, app->env.wasmBytecode.len, file);
fclose(file); fclose(file);
u32 stackSize = 65536; u32 stackSize = 65536 * 20; // MOAR STACK
app->env.m3Env = m3_NewEnvironment(); app->env.m3Env = m3_NewEnvironment();
app->env.m3Runtime = m3_NewRuntime(app->env.m3Env, stackSize, NULL); app->env.m3Runtime = m3_NewRuntime(app->env.m3Env, stackSize, NULL);
@ -461,6 +469,7 @@ i32 orca_runloop(void* user)
err |= bindgen_link_clock_api(app->env.m3Module); err |= bindgen_link_clock_api(app->env.m3Module);
err |= bindgen_link_io_api(app->env.m3Module); err |= bindgen_link_io_api(app->env.m3Module);
err |= bindgen_link_gles_api(app->env.m3Module); err |= bindgen_link_gles_api(app->env.m3Module);
err |= bindgen_link_subprocess_api(app->env.m3Module);
err |= manual_link_gles_api(app->env.m3Module); err |= manual_link_gles_api(app->env.m3Module);
if(err) if(err)

View File

@ -11,6 +11,7 @@
#include "platform/platform_io_internal.h" #include "platform/platform_io_internal.h"
#include "runtime_memory.h" #include "runtime_memory.h"
#include "runtime_clipboard.h" #include "runtime_clipboard.h"
#include "runtime_subprocess.h"
#include "m3_compile.h" #include "m3_compile.h"
#include "m3_env.h" #include "m3_env.h"

29
src/runtime_subprocess.c Normal file
View File

@ -0,0 +1,29 @@
/*************************************************************************
*
* Orca
* Copyright 2023 Martin Fouilleul and the Orca project contributors
* See LICENSE.txt for licensing information
*
**************************************************************************/
#include "runtime_subprocess.h"
// #include "memory.h"
oc_arena cmdArena;
oc_wasm_str8 oc_runtime_run_cmd(oc_wasm_addr wasmArena, oc_wasm_str8 cmd)
{
if(!cmdArena.currentChunk)
{
oc_arena_init(&cmdArena);
}
oc_arena_clear(&cmdArena);
oc_str8 nativeCmd = oc_wasm_str8_to_native(cmd);
oc_str8 out = oc_run_cmd(&cmdArena, nativeCmd);
oc_wasm_addr outAddr = oc_wasm_arena_push(wasmArena, out.len);
char* outPtr = (char*)oc_wasm_address_to_ptr(outAddr, out.len);
memcpy(outPtr, out.ptr, out.len);
return (oc_wasm_str8){ .ptr = outAddr,
.len = out.len };
}

15
src/runtime_subprocess.h Normal file
View File

@ -0,0 +1,15 @@
/*************************************************************************
*
* Orca
* Copyright 2023 Martin Fouilleul and the Orca project contributors
* See LICENSE.txt for licensing information
*
**************************************************************************/
#ifndef __RUNTIME_SUBPROCESS_H_
#define __RUNTIME_SUBPROCESS_H_
#include "runtime_memory.h"
oc_wasm_str8 oc_runtime_run_cmd(oc_wasm_addr wasmArena, oc_wasm_str8 cmd);
#endif // __RUNTIME_SUBPROCESS_H

View File

@ -196,23 +196,16 @@ oc_str8_list oc_str8_split(oc_arena* arena, oc_str8 str, oc_str8_list separators
} }
if(foundSep) if(foundSep)
{ {
//NOTE(martin): we found a separator. If the start of the current substring is != ptr, oc_str8 sub = oc_str8_from_buffer(ptr - subStart, subStart);
// the current substring is not empty and we emit the substring oc_str8_list_push(arena, &list, sub);
if(ptr != subStart)
{
oc_str8 sub = oc_str8_from_buffer(ptr - subStart, subStart);
oc_str8_list_push(arena, &list, sub);
}
ptr += foundSep->len - 1; //NOTE(martin): ptr is incremented at the end of the loop ptr += foundSep->len - 1; //NOTE(martin): ptr is incremented at the end of the loop
subStart = ptr + 1; subStart = ptr + 1;
} }
} }
//NOTE(martin): emit the last substring //NOTE(martin): emit the last substring
if(ptr != subStart) oc_str8 sub = oc_str8_from_buffer(ptr - subStart, subStart);
{ oc_str8_list_push(arena, &list, sub);
oc_str8 sub = oc_str8_from_buffer(ptr - subStart, subStart);
oc_str8_list_push(arena, &list, sub);
}
return (list); return (list);
} }

View File

@ -1,128 +1,326 @@
[ [
{ {
"name": "oc_bridge_log", "name": "oc_bridge_log",
"cname": "oc_bridge_log", "cname": "oc_bridge_log",
"ret": {"name": "void", "tag": "v"}, "ret": {
"args": [ {"name": "level", "name": "void",
"type": {"name": "oc_log_level", "tag": "i"}}, "tag": "v"
{"name": "functionLen", },
"type": {"name": "int", "tag": "i"}}, "args": [
{"name": "function", {
"type": {"name": "char*", "tag": "p"}, "name": "level",
"len": {"count": "functionLen"}}, "type": {
{"name": "fileLen", "name": "oc_log_level",
"type": {"name": "int", "tag": "i"}}, "tag": "i"
{"name": "file", }
"type": {"name": "char*", "tag": "p"}, },
"len": {"count": "fileLen"}}, {
{"name": "line", "name": "functionLen",
"type": {"name": "int", "tag": "i"}}, "type": {
{"name": "msgLen", "name": "int",
"type": {"name": "int", "tag": "i"}}, "tag": "i"
{"name": "msg", }
"type": {"name": "char*", "tag": "p"}, },
"len": {"count": "msgLen"}} {
] "name": "function",
}, "type": {
{ "name": "char*",
"name": "oc_mem_grow", "tag": "p"
"cname": "oc_mem_grow", },
"ret": {"name": "int", "tag": "i"}, "len": {
"args": [ {"name": "size", "count": "functionLen"
"type": {"name": "u64", "tag": "I"}}] }
}, },
{ {
"name": "oc_bridge_assert_fail", "name": "fileLen",
"cname": "oc_assert_fail", "type": {
"ret": {"name": "void", "tag": "v"}, "name": "int",
"args": [ {"name": "file", "tag": "i"
"type": {"name": "const char*", "tag": "p"}, }
"len": {"proc": "orca_check_cstring", "args": ["file"]}}, },
{"name": "function", {
"type": {"name": "const char*", "tag": "p"}, "name": "file",
"len": {"proc": "orca_check_cstring", "args": ["function"]}}, "type": {
{"name": "line", "name": "char*",
"type": {"name": "int", "tag": "i"}}, "tag": "p"
{"name": "src", },
"type": {"name": "const char*", "tag": "p"}, "len": {
"len": {"proc": "orca_check_cstring", "args": ["src"]}}, "count": "fileLen"
{"name": "note", }
"type": {"name": "const char*", "tag": "p"}, },
"len": {"proc": "orca_check_cstring", "args": ["note"]}} {
] "name": "line",
}, "type": {
{ "name": "int",
"name": "oc_bridge_abort_ext", "tag": "i"
"cname": "oc_abort_ext", }
"ret": {"name": "void", "tag": "v"}, },
"args": [ {"name": "file", {
"type": {"name": "const char*", "tag": "p"}, "name": "msgLen",
"len": {"proc": "orca_check_cstring", "args": ["file"]}}, "type": {
{"name": "function", "name": "int",
"type": {"name": "const char*", "tag": "p"}, "tag": "i"
"len": {"proc": "orca_check_cstring", "args": ["function"]}}, }
{"name": "line", },
"type": {"name": "int", "tag": "i"}}, {
{"name": "note", "name": "msg",
"type": {"name": "const char*", "tag": "p"}, "type": {
"len": {"proc": "orca_check_cstring", "args": ["note"]}} "name": "char*",
] "tag": "p"
}, },
{ "len": {
"name": "oc_get_host_platform", "count": "msgLen"
"cname": "oc_get_host_platform", }
"ret": {"name": "int", "tag": "i"}, }
"args": [] ]
}, },
{ {
"name": "oc_request_quit", "name": "oc_mem_grow",
"cname": "oc_bridge_request_quit", "cname": "oc_mem_grow",
"ret": {"name": "void", "tag": "v"}, "ret": {
"args": [] "name": "int",
}, "tag": "i"
{ },
"name": "oc_window_set_title", "args": [
"cname": "oc_bridge_window_set_title", {
"ret": {"name": "void", "tag": "v"}, "name": "size",
"args": [ "type": {
{ "name": "title", "name": "u64",
"type": {"name": "oc_str8", "cname": "oc_wasm_str8", "tag": "S"}} "tag": "I"
] }
}, }
{ ]
"name": "oc_window_set_size", },
"cname": "oc_bridge_window_set_size", {
"ret": {"name": "void", "tag": "v"}, "name": "oc_bridge_assert_fail",
"args": [ "cname": "oc_assert_fail",
{ "name": "size", "ret": {
"type": {"name": "oc_vec2", "tag": "S"}} "name": "void",
] "tag": "v"
}, },
{ "args": [
"name": "oc_scancode_to_keycode", {
"cname": "oc_scancode_to_keycode", "name": "file",
"ret": { "name": "oc_key_code", "tag": "i"}, "type": {
"args": [ "name": "const char*",
{ "name": "scanCode", "tag": "p"
"type": {"name": "oc_scan_code", "tag": "i"}} },
] "len": {
}, "proc": "orca_check_cstring",
{ "args": [
"name": "oc_clipboard_get_string", "file"
"cname": "oc_bridge_clipboard_get_string", ]
"ret": { "name": "oc_str8", "cname": "oc_wasm_str8", "tag": "S"}, }
"args": [ },
{"name": "arena", {
"type": {"name": "oc_arena*", "cname": "i32", "tag": "i"}} "name": "function",
] "type": {
}, "name": "const char*",
{ "tag": "p"
"name": "oc_clipboard_set_string", },
"cname": "oc_bridge_clipboard_set_string", "len": {
"ret": {"name": "void", "tag": "v"}, "proc": "orca_check_cstring",
"args": [ "args": [
{ "name": "value", "function"
"type": {"name": "oc_str8", "cname": "oc_wasm_str8", "tag": "S"}} ]
] }
} },
] {
"name": "line",
"type": {
"name": "int",
"tag": "i"
}
},
{
"name": "src",
"type": {
"name": "const char*",
"tag": "p"
},
"len": {
"proc": "orca_check_cstring",
"args": [
"src"
]
}
},
{
"name": "note",
"type": {
"name": "const char*",
"tag": "p"
},
"len": {
"proc": "orca_check_cstring",
"args": [
"note"
]
}
}
]
},
{
"name": "oc_bridge_abort_ext",
"cname": "oc_abort_ext",
"ret": {
"name": "void",
"tag": "v"
},
"args": [
{
"name": "file",
"type": {
"name": "const char*",
"tag": "p"
},
"len": {
"proc": "orca_check_cstring",
"args": [
"file"
]
}
},
{
"name": "function",
"type": {
"name": "const char*",
"tag": "p"
},
"len": {
"proc": "orca_check_cstring",
"args": [
"function"
]
}
},
{
"name": "line",
"type": {
"name": "int",
"tag": "i"
}
},
{
"name": "note",
"type": {
"name": "const char*",
"tag": "p"
},
"len": {
"proc": "orca_check_cstring",
"args": [
"note"
]
}
}
]
},
{
"name": "oc_get_host_platform",
"cname": "oc_get_host_platform",
"ret": {
"name": "int",
"tag": "i"
},
"args": []
},
{
"name": "oc_request_quit",
"cname": "oc_bridge_request_quit",
"ret": {
"name": "void",
"tag": "v"
},
"args": []
},
{
"name": "oc_window_set_title",
"cname": "oc_bridge_window_set_title",
"ret": {
"name": "void",
"tag": "v"
},
"args": [
{
"name": "title",
"type": {
"name": "oc_str8",
"cname": "oc_wasm_str8",
"tag": "S"
}
}
]
},
{
"name": "oc_window_set_size",
"cname": "oc_bridge_window_set_size",
"ret": {
"name": "void",
"tag": "v"
},
"args": [
{
"name": "size",
"type": {
"name": "oc_vec2",
"tag": "S"
}
}
]
},
{
"name": "oc_scancode_to_keycode",
"cname": "oc_scancode_to_keycode",
"ret": {
"name": "oc_key_code",
"tag": "i"
},
"args": [
{
"name": "scanCode",
"type": {
"name": "oc_scan_code",
"tag": "i"
}
}
]
},
{
"name": "oc_clipboard_get_string",
"cname": "oc_bridge_clipboard_get_string",
"ret": {
"name": "oc_str8",
"cname": "oc_wasm_str8",
"tag": "S"
},
"args": [
{
"name": "arena",
"type": {
"name": "oc_arena*",
"cname": "i32",
"tag": "i"
}
}
]
},
{
"name": "oc_clipboard_set_string",
"cname": "oc_bridge_clipboard_set_string",
"ret": {
"name": "void",
"tag": "v"
},
"args": [
{
"name": "value",
"type": {
"name": "oc_str8",
"cname": "oc_wasm_str8",
"tag": "S"
}
}
]
}
]

View File

@ -0,0 +1,29 @@
[
{
"name": "oc_run_cmd",
"cname": "oc_bridge_run_cmd",
"ret": {
"name": "oc_str8",
"cname": "oc_wasm_str8",
"tag": "S"
},
"args": [
{
"name": "arena",
"type": {
"name": "oc_arena*",
"cname": "i32",
"tag": "i"
}
},
{
"name": "cmd",
"type": {
"name": "oc_str8",
"cname": "oc_wasm_str8",
"tag": "S"
}
}
]
}
]