run with mcode
This commit is contained in:
134805
fold.cm.mcode
Normal file
134805
fold.cm.mcode
Normal file
File diff suppressed because it is too large
Load Diff
@@ -24,15 +24,21 @@ function use_basic(path) {
|
||||
return result
|
||||
}
|
||||
|
||||
// Load a module from .mach bytecode (bootstrap modules have no source fallback)
|
||||
// Load a module from .mach/.mcode bytecode (bootstrap modules have no source fallback)
|
||||
function boot_load(name, env) {
|
||||
var mach_path = core_path + '/' + name + ".mach"
|
||||
var mach_path = core_path + '/' + name + ".cm.mach"
|
||||
var mcode_path = core_path + '/' + name + ".cm.mcode"
|
||||
var data = null
|
||||
var mcode_json = null
|
||||
if (fd.is_file(mach_path)) {
|
||||
data = fd.slurp(mach_path)
|
||||
return mach_load(data, env)
|
||||
}
|
||||
print("error: missing bootstrap bytecode: " + mach_path + "\n")
|
||||
if (fd.is_file(mcode_path)) {
|
||||
mcode_json = text(fd.slurp(mcode_path))
|
||||
return mach_eval_mcode(name, mcode_json, env)
|
||||
}
|
||||
print("error: missing bootstrap bytecode: " + name + "\n")
|
||||
disrupt
|
||||
}
|
||||
|
||||
@@ -50,33 +56,45 @@ use_cache['mcode'] = mcode_mod
|
||||
var streamline_mod = null
|
||||
var qbe_emit_mod = null
|
||||
|
||||
// Warn if any .cm source is newer than its .mach bytecode
|
||||
// Warn if any .cm source is newer than its compiled bytecode
|
||||
function check_mach_stale() {
|
||||
var pairs = [
|
||||
["tokenize.cm", "tokenize.mach"],
|
||||
["parse.cm", "parse.mach"],
|
||||
["fold.cm", "fold.mach"],
|
||||
["mcode.cm", "mcode.mach"],
|
||||
["streamline.cm", "streamline.mach"],
|
||||
["qbe.cm", "qbe.mach"],
|
||||
["qbe_emit.cm", "qbe_emit.mach"],
|
||||
["internal/bootstrap.cm", "internal/bootstrap.mach"],
|
||||
["internal/engine.cm", "internal/engine.mach"]
|
||||
var sources = [
|
||||
"tokenize.cm",
|
||||
"parse.cm",
|
||||
"fold.cm",
|
||||
"mcode.cm",
|
||||
"streamline.cm",
|
||||
"qbe.cm",
|
||||
"qbe_emit.cm",
|
||||
"internal/bootstrap.cm",
|
||||
"internal/engine.cm"
|
||||
]
|
||||
var stale = []
|
||||
var _i = 0
|
||||
var cm_path = null
|
||||
var mach_path = null
|
||||
var mcode_path = null
|
||||
var cm_stat = null
|
||||
var mach_stat = null
|
||||
while (_i < length(pairs)) {
|
||||
cm_path = core_path + '/' + pairs[_i][0]
|
||||
mach_path = core_path + '/' + pairs[_i][1]
|
||||
if (fd.is_file(cm_path) && fd.is_file(mach_path)) {
|
||||
var compiled_stat = null
|
||||
var best_mtime = null
|
||||
while (_i < length(sources)) {
|
||||
cm_path = core_path + '/' + sources[_i]
|
||||
mach_path = cm_path + '.mach'
|
||||
mcode_path = cm_path + '.mcode'
|
||||
best_mtime = null
|
||||
if (fd.is_file(mach_path)) {
|
||||
best_mtime = fd.stat(mach_path).mtime
|
||||
}
|
||||
if (fd.is_file(mcode_path)) {
|
||||
compiled_stat = fd.stat(mcode_path)
|
||||
if (best_mtime == null || compiled_stat.mtime > best_mtime) {
|
||||
best_mtime = compiled_stat.mtime
|
||||
}
|
||||
}
|
||||
if (best_mtime != null && fd.is_file(cm_path)) {
|
||||
cm_stat = fd.stat(cm_path)
|
||||
mach_stat = fd.stat(mach_path)
|
||||
if (cm_stat.mtime > mach_stat.mtime) {
|
||||
push(stale, pairs[_i][0])
|
||||
if (cm_stat.mtime > best_mtime) {
|
||||
push(stale, sources[_i])
|
||||
}
|
||||
}
|
||||
_i = _i + 1
|
||||
@@ -123,10 +141,12 @@ function analyze(src, filename) {
|
||||
return ast
|
||||
}
|
||||
|
||||
// Load a module from .mach bytecode, falling back to source compilation
|
||||
// Load a module from .mach/.mcode bytecode, falling back to source compilation
|
||||
function load_module(name, env) {
|
||||
var mach_path = core_path + '/' + name + ".mach"
|
||||
var mach_path = core_path + '/' + name + ".cm.mach"
|
||||
var mcode_path = core_path + '/' + name + ".cm.mcode"
|
||||
var data = null
|
||||
var mcode_json = null
|
||||
var src_path = null
|
||||
var src = null
|
||||
var ast = null
|
||||
@@ -136,6 +156,10 @@ function load_module(name, env) {
|
||||
data = fd.slurp(mach_path)
|
||||
return mach_load(data, env)
|
||||
}
|
||||
if (fd.is_file(mcode_path)) {
|
||||
mcode_json = text(fd.slurp(mcode_path))
|
||||
return mach_eval_mcode(name, mcode_json, env)
|
||||
}
|
||||
src_path = core_path + '/' + name + ".cm"
|
||||
src = text(fd.slurp(src_path))
|
||||
ast = analyze(src, src_path)
|
||||
@@ -176,6 +200,8 @@ function run_ast(name, ast, env) {
|
||||
function use_fn(path) {
|
||||
var file_path = null
|
||||
var mach_path = null
|
||||
var mcode_path = null
|
||||
var mcode_json = null
|
||||
var data = null
|
||||
var script = null
|
||||
var ast = null
|
||||
@@ -183,10 +209,10 @@ function use_fn(path) {
|
||||
if (use_cache[path])
|
||||
return use_cache[path]
|
||||
|
||||
// Try .mach bytecode first (CWD then core_path)
|
||||
mach_path = path + '.mach'
|
||||
// Try .cm.mach bytecode first (CWD then core_path)
|
||||
mach_path = path + '.cm.mach'
|
||||
if (!fd.is_file(mach_path))
|
||||
mach_path = core_path + '/' + path + '.mach'
|
||||
mach_path = core_path + '/' + path + '.cm.mach'
|
||||
if (fd.is_file(mach_path)) {
|
||||
data = fd.slurp(mach_path)
|
||||
result = mach_load(data, {use: use_fn})
|
||||
@@ -194,6 +220,17 @@ function use_fn(path) {
|
||||
return result
|
||||
}
|
||||
|
||||
// Try .cm.mcode JSON IR (CWD then core_path)
|
||||
mcode_path = path + '.cm.mcode'
|
||||
if (!fd.is_file(mcode_path))
|
||||
mcode_path = core_path + '/' + path + '.cm.mcode'
|
||||
if (fd.is_file(mcode_path)) {
|
||||
mcode_json = text(fd.slurp(mcode_path))
|
||||
result = mach_eval_mcode(path, mcode_json, {use: use_fn})
|
||||
use_cache[path] = result
|
||||
return result
|
||||
}
|
||||
|
||||
// Try .cm source (CWD then core_path)
|
||||
file_path = path + '.cm'
|
||||
if (!fd.is_file(file_path))
|
||||
@@ -215,14 +252,20 @@ function use_fn(path) {
|
||||
|
||||
// Helper to load engine.cm and run it with given env
|
||||
function load_engine(env) {
|
||||
var engine_path = core_path + '/internal/engine.mach'
|
||||
var engine_path = core_path + '/internal/engine.cm.mach'
|
||||
var mcode_path = core_path + '/internal/engine.cm.mcode'
|
||||
var data = null
|
||||
var mcode_json = null
|
||||
var engine_src = null
|
||||
var engine_ast = null
|
||||
if (fd.is_file(engine_path)) {
|
||||
data = fd.slurp(engine_path)
|
||||
return mach_load(data, env)
|
||||
}
|
||||
if (fd.is_file(mcode_path)) {
|
||||
mcode_json = text(fd.slurp(mcode_path))
|
||||
return mach_eval_mcode('engine', mcode_json, env)
|
||||
}
|
||||
engine_path = core_path + '/internal/engine.cm'
|
||||
engine_src = text(fd.slurp(engine_path))
|
||||
engine_ast = analyze(engine_src, engine_path)
|
||||
|
||||
20621
internal/bootstrap.cm.mcode
Normal file
20621
internal/bootstrap.cm.mcode
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -76,14 +76,22 @@ function use_core(path) {
|
||||
arrfor(array(core_extras), function(k) { env[k] = core_extras[k] })
|
||||
if (sym) env.native = sym
|
||||
|
||||
// Check for pre-compiled .mach file first
|
||||
var mach_path = core_path + '/' + path + '.mach'
|
||||
// Check for pre-compiled .cm.mach file first
|
||||
var mach_path = core_path + '/' + path + '.cm.mach'
|
||||
if (fd.is_file(mach_path)) {
|
||||
result = mach_load(fd.slurp(mach_path), env)
|
||||
use_cache[cache_key] = result
|
||||
return result
|
||||
}
|
||||
|
||||
// Check for .cm.mcode JSON IR
|
||||
var mcode_path = core_path + '/' + path + '.cm.mcode'
|
||||
if (fd.is_file(mcode_path)) {
|
||||
result = mach_eval_mcode('core:' + path, text(fd.slurp(mcode_path)), env)
|
||||
use_cache[cache_key] = result
|
||||
return result
|
||||
}
|
||||
|
||||
// Fall back to source .cm file — compile at runtime
|
||||
var file_path = core_path + '/' + path + MOD_EXT
|
||||
if (fd.is_file(file_path)) {
|
||||
|
||||
41635
internal/engine.cm.mcode
Normal file
41635
internal/engine.cm.mcode
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
139605
mcode.cm.mcode
Normal file
139605
mcode.cm.mcode
Normal file
File diff suppressed because it is too large
Load Diff
BIN
mcode.mach
BIN
mcode.mach
Binary file not shown.
168633
parse.cm.mcode
Normal file
168633
parse.cm.mcode
Normal file
File diff suppressed because it is too large
Load Diff
BIN
parse.mach
BIN
parse.mach
Binary file not shown.
12003
qbe.cm.mcode
Normal file
12003
qbe.cm.mcode
Normal file
File diff suppressed because it is too large
Load Diff
71286
qbe_emit.cm.mcode
Normal file
71286
qbe_emit.cm.mcode
Normal file
File diff suppressed because it is too large
Load Diff
BIN
qbe_emit.mach
BIN
qbe_emit.mach
Binary file not shown.
28
regen.cm
28
regen.cm
@@ -1,4 +1,4 @@
|
||||
// regen.cm — regenerate .mach bytecode files
|
||||
// regen.cm — regenerate .cm.mcode files
|
||||
// Run with: ./cell --core . regen.cm
|
||||
|
||||
var fd = use("fd")
|
||||
@@ -10,15 +10,15 @@ var mcode = use("mcode")
|
||||
var streamline = use("streamline")
|
||||
|
||||
var files = [
|
||||
{src: "tokenize.cm", name: "tokenize", out: "tokenize.mach"},
|
||||
{src: "parse.cm", name: "parse", out: "parse.mach"},
|
||||
{src: "fold.cm", name: "fold", out: "fold.mach"},
|
||||
{src: "mcode.cm", name: "mcode", out: "mcode.mach"},
|
||||
{src: "streamline.cm", name: "streamline", out: "streamline.mach"},
|
||||
{src: "qbe.cm", name: "qbe", out: "qbe.mach"},
|
||||
{src: "qbe_emit.cm", name: "qbe_emit", out: "qbe_emit.mach"},
|
||||
{src: "internal/bootstrap.cm", name: "bootstrap", out: "internal/bootstrap.mach"},
|
||||
{src: "internal/engine.cm", name: "engine", out: "internal/engine.mach"}
|
||||
{src: "tokenize.cm", name: "tokenize", out: "tokenize.cm.mcode"},
|
||||
{src: "parse.cm", name: "parse", out: "parse.cm.mcode"},
|
||||
{src: "fold.cm", name: "fold", out: "fold.cm.mcode"},
|
||||
{src: "mcode.cm", name: "mcode", out: "mcode.cm.mcode"},
|
||||
{src: "streamline.cm", name: "streamline", out: "streamline.cm.mcode"},
|
||||
{src: "qbe.cm", name: "qbe", out: "qbe.cm.mcode"},
|
||||
{src: "qbe_emit.cm", name: "qbe_emit", out: "qbe_emit.cm.mcode"},
|
||||
{src: "internal/bootstrap.cm", name: "bootstrap", out: "internal/bootstrap.cm.mcode"},
|
||||
{src: "internal/engine.cm", name: "engine", out: "internal/engine.cm.mcode"}
|
||||
]
|
||||
|
||||
var i = 0
|
||||
@@ -29,8 +29,7 @@ var ast = null
|
||||
var folded = null
|
||||
var compiled = null
|
||||
var optimized = null
|
||||
var mcode_json = null
|
||||
var bytecode = null
|
||||
var mcode_text = null
|
||||
var f = null
|
||||
var errs = null
|
||||
var ei = 0
|
||||
@@ -62,10 +61,9 @@ while (i < length(files)) {
|
||||
folded = fold(ast)
|
||||
compiled = mcode(folded)
|
||||
optimized = streamline(compiled)
|
||||
mcode_json = json.encode(optimized)
|
||||
bytecode = mach_compile_mcode_bin(entry.name, mcode_json)
|
||||
mcode_text = json.encode(optimized, null, 2)
|
||||
f = fd.open(entry.out, "w")
|
||||
fd.write(f, bytecode)
|
||||
fd.write(f, mcode_text)
|
||||
fd.close(f)
|
||||
print(`wrote ${entry.out}`)
|
||||
i = i + 1
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
#include "cell_internal.h"
|
||||
#include "cJSON.h"
|
||||
|
||||
#define BOOTSTRAP_MACH "internal/bootstrap.mach"
|
||||
#define BOOTSTRAP_SRC "internal/bootstrap.cm"
|
||||
#define BOOTSTRAP_MACH "internal/bootstrap.cm.mach"
|
||||
#define BOOTSTRAP_MCODE "internal/bootstrap.cm.mcode"
|
||||
#define BOOTSTRAP_SRC "internal/bootstrap.cm"
|
||||
#define CELL_SHOP_DIR ".cell"
|
||||
#define CELL_CORE_DIR "packages/core"
|
||||
|
||||
@@ -178,9 +179,14 @@ void script_startup(cell_rt *prt)
|
||||
cell_rt *crt = JS_GetContextOpaque(js);
|
||||
JS_FreeValue(js, js_blob_use(js));
|
||||
|
||||
// Load pre-compiled bootstrap bytecode (.mach)
|
||||
// Load pre-compiled bootstrap (.cm.mach or .cm.mcode)
|
||||
size_t boot_size;
|
||||
char *boot_data = load_core_file(BOOTSTRAP_MACH, &boot_size);
|
||||
int boot_is_mcode = 0;
|
||||
if (!boot_data) {
|
||||
boot_data = load_core_file(BOOTSTRAP_MCODE, &boot_size);
|
||||
boot_is_mcode = 1;
|
||||
}
|
||||
if (!boot_data) {
|
||||
printf("ERROR: Could not load bootstrap from %s!\n", core_path);
|
||||
return;
|
||||
@@ -218,7 +224,9 @@ void script_startup(cell_rt *prt)
|
||||
|
||||
// Run through MACH VM
|
||||
crt->state = ACTOR_RUNNING;
|
||||
JSValue v = JS_RunMachBin(js, (const uint8_t *)boot_data, boot_size, hidden_env);
|
||||
JSValue v = boot_is_mcode
|
||||
? JS_RunMachMcode(js, boot_data, boot_size, hidden_env)
|
||||
: JS_RunMachBin(js, (const uint8_t *)boot_data, boot_size, hidden_env);
|
||||
free(boot_data);
|
||||
uncaught_exception(js, v);
|
||||
crt->state = ACTOR_IDLE;
|
||||
@@ -349,6 +357,11 @@ int cell_init(int argc, char **argv)
|
||||
|
||||
size_t boot_size;
|
||||
char *boot_data = load_core_file(BOOTSTRAP_MACH, &boot_size);
|
||||
int boot_is_mcode = 0;
|
||||
if (!boot_data) {
|
||||
boot_data = load_core_file(BOOTSTRAP_MCODE, &boot_size);
|
||||
boot_is_mcode = 1;
|
||||
}
|
||||
if (!boot_data) {
|
||||
printf("ERROR: Could not load bootstrap from %s\n", core_path);
|
||||
return 1;
|
||||
@@ -417,7 +430,9 @@ int cell_init(int argc, char **argv)
|
||||
JS_SetPropertyStr(ctx, hidden_env, "args", args_arr);
|
||||
hidden_env = JS_Stone(ctx, hidden_env);
|
||||
|
||||
JSValue result = JS_RunMachBin(ctx, (const uint8_t *)boot_data, boot_size, hidden_env);
|
||||
JSValue result = boot_is_mcode
|
||||
? JS_RunMachMcode(ctx, boot_data, boot_size, hidden_env)
|
||||
: JS_RunMachBin(ctx, (const uint8_t *)boot_data, boot_size, hidden_env);
|
||||
free(boot_data);
|
||||
|
||||
int exit_code = 0;
|
||||
|
||||
@@ -3166,6 +3166,29 @@ JSValue JS_RunMachBin(JSContext *ctx, const uint8_t *data, size_t size, JSValue
|
||||
return result;
|
||||
}
|
||||
|
||||
JSValue JS_RunMachMcode(JSContext *ctx, const char *json_str, size_t len, JSValue env) {
|
||||
(void)len;
|
||||
cJSON *mcode = cJSON_Parse(json_str);
|
||||
if (!mcode)
|
||||
return JS_ThrowSyntaxError(ctx, "failed to parse mcode JSON");
|
||||
|
||||
MachCode *mc = mach_compile_mcode(mcode);
|
||||
cJSON_Delete(mcode);
|
||||
if (!mc)
|
||||
return JS_ThrowInternalError(ctx, "mcode compilation failed");
|
||||
|
||||
JSGCRef env_ref;
|
||||
JS_PushGCRef(ctx, &env_ref);
|
||||
env_ref.val = env;
|
||||
|
||||
JSCodeRegister *code = JS_LoadMachCode(ctx, mc, env_ref.val);
|
||||
JS_FreeMachCode(mc);
|
||||
|
||||
JSValue result = JS_CallRegisterVM(ctx, code, ctx->global_obj, 0, NULL, env_ref.val, JS_NULL);
|
||||
JS_PopGCRef(ctx, &env_ref);
|
||||
return result;
|
||||
}
|
||||
|
||||
void JS_DumpMachBin(JSContext *ctx, const uint8_t *data, size_t size, JSValue env) {
|
||||
MachCode *mc = JS_DeserializeMachCode(data, size);
|
||||
if (!mc) {
|
||||
|
||||
@@ -995,6 +995,9 @@ struct JSCodeRegister *JS_LoadMachCode(JSContext *ctx, MachCode *mc, JSValue env
|
||||
/* Deserialize and execute pre-compiled MACH binary bytecode. */
|
||||
JSValue JS_RunMachBin(JSContext *ctx, const uint8_t *data, size_t size, JSValue env);
|
||||
|
||||
/* Parse mcode JSON IR, compile, and execute via register VM. */
|
||||
JSValue JS_RunMachMcode(JSContext *ctx, const char *json_str, size_t len, JSValue env);
|
||||
|
||||
/* Dump disassembly of pre-compiled MACH binary bytecode. */
|
||||
void JS_DumpMachBin(JSContext *ctx, const uint8_t *data, size_t size, JSValue env);
|
||||
|
||||
|
||||
84002
streamline.cm.mcode
Normal file
84002
streamline.cm.mcode
Normal file
File diff suppressed because it is too large
Load Diff
BIN
streamline.mach
BIN
streamline.mach
Binary file not shown.
65282
tokenize.cm.mcode
Normal file
65282
tokenize.cm.mcode
Normal file
File diff suppressed because it is too large
Load Diff
BIN
tokenize.mach
BIN
tokenize.mach
Binary file not shown.
Reference in New Issue
Block a user