This commit is contained in:
2025-12-21 10:37:02 -06:00
parent d50f4119ee
commit 8b9e088385
32 changed files with 206 additions and 144 deletions

View File

@@ -56,7 +56,7 @@ static:
# Bootstrap: build cell from scratch using meson (only needed once)
# Also installs core scripts to ~/.cell/core
bootstrap:
meson setup build_bootstrap -Dbuildtype=release
meson setup build_bootstrap -Dbuildtype=debugoptimized
meson compile -C build_bootstrap
cp build_bootstrap/cell .
cp build_bootstrap/libcell_runtime.dylib .

2
add.ce
View File

@@ -1,6 +1,6 @@
// cell get <locator> [alias] - Add and install a package with its dependencies
var shop = use('shop')
var shop = use('internal/shop')
if (args.length < 1) {
log.console("Usage: cell get <locator> [alias]")

View File

@@ -6,7 +6,7 @@
// cell build -t <target> Cross-compile dynamic libraries for target platform
var build = use('build')
var shop = use('shop')
var shop = use('internal/shop')
var pkg_tools = use('package')
var fd = use('fd')

View File

@@ -11,7 +11,7 @@ var crypto = use('crypto')
var utf8 = use('utf8')
var os = use('os')
var toolchains = use('toolchains')
var shop = use('shop')
var shop = use('internal/shop')
var pkg_tools = use('package')
var Build = {}

View File

@@ -278,7 +278,7 @@ function mount_package(name) {
return
}
var shop = use('shop')
var shop = use('internal/shop')
var dir = shop.get_package_dir(name)
if (!dir) {
@@ -475,7 +475,6 @@ cellfs.writepath = set_writepath
cellfs.basedir = basedir
cellfs.prefdir = prefdir
cellfs.realdir = realdir
cellfs.slurp = slurp
cellfs.mount('.')

View File

@@ -1,7 +1,7 @@
// cell clean - Remove build artifacts from global shop
var fd = use('fd')
var shop = use('shop')
var shop = use('internal/shop')
var build_dir = shop.get_shop_path() + '/build'

View File

@@ -2,7 +2,6 @@
var toml = use('toml')
var pkg = use('package')
var text = use('text')
function print_help() {
log.console("Usage: cell config <command> [options]")
@@ -80,7 +79,7 @@ function format_value(val) {
// Add underscores to large numbers
return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '_')
}
return String(val)
return text(val)
}
// Print configuration tree recursively

View File

@@ -8,7 +8,7 @@
// cell fetch - Fetch all packages
// cell fetch <package> - Fetch a specific package
var shop = use('shop')
var shop = use('internal/shop')
// Parse arguments
var target_pkg = null
@@ -67,7 +67,7 @@ for (var pkg of packages_to_fetch) {
}
var result = shop.fetch(pkg)
if (result && result.ok) {
if (result) {
if (result.zip_blob) {
log.console("Fetched: " + pkg)
success_count++

View File

@@ -1,7 +1,7 @@
// cell install <locator> - Install a package to the shop
// Does not modify the current project's cell.toml
var shop = use('shop')
var shop = use('internal/shop')
var build = use('build')
if (args.length < 1) {

View File

@@ -5,6 +5,7 @@ var _slice = Array.prototype.slice
var _push = Array.prototype.push
var _sort = Array.prototype.sort
var _keys = Object.keys
var _from = Array.from
function array(arg, arg2, arg3, arg4) {
// array(number) - create array of size with nulls
@@ -91,6 +92,9 @@ function array(arg, arg2, arg3, arg4) {
// array(object) - keys
if (typeof arg == 'object' && arg != null && !_isArray(arg)) {
if (arg instanceof Set) {
return _from(arg)
}
return _keys(arg)
}

View File

@@ -4,8 +4,6 @@ delete globalThis.cell
var ACTORDATA = _cell.hidden.actorsym
var SYSYM = '__SYSTEM__'
var __cell = globalThis._cell
var hidden = _cell.hidden
var os = hidden.os;
@@ -29,10 +27,19 @@ function use_embed(name) {
return load_internal(`js_${name}_use`)
}
globalThis.meme = function(obj) {
return {
globalThis.meme = function(obj, ...mixins) {
var result = {
__proto__: obj
}
array.for(mixins, mix => {
if (isa(mix, object)) {
for (var key in mix) {
result[key] = mix[key]
}
}
})
return result
}
globalThis.logical = function(val1)
@@ -66,6 +73,11 @@ use_cache['core/os'] = os
var _Symbol = Symbol
globalThis.key = function()
{
return _Symbol()
}
// Load a core module from the file system
function use_core(path) {
var cache_key = 'core/' + path
@@ -392,7 +404,7 @@ os.use_cache = use_cache
os.global_shop_path = shop_path
os.$_ = $_
var shop = use_core('shop')
var shop = use_core('internal/shop')
var json = use_core('json')
var time = use_core('time')
@@ -949,10 +961,6 @@ function enet_check()
// enet_check();
var init_end = time.number()
var load_program_start = time.number()
// Finally, run the program
actor_mod.setname(_cell.args.program)
@@ -1005,8 +1013,8 @@ delete globalThis.WeakSet
delete globalThis.WeakRef
delete globalThis.BigInt
delete globalThis.Symbol
delete globalThis.Map
delete globalThis.Set
//delete globalThis.Map
//delete globalThis.Set
delete globalThis.Promise
delete globalThis.ArrayBuffer
delete globalThis.DataView

View File

@@ -326,7 +326,7 @@ static JSValue js_os_dylib_open(JSContext *js, JSValue self, int argc, JSValue *
#ifdef _WIN32
handle = LoadLibraryA(path);
#else
handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
handle = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
#endif
JS_FreeCString(js, path);

View File

@@ -99,6 +99,11 @@ function get_import_package(name) {
return null
}
function is_internal_path(path)
{
return path && path.startsWith('internal/')
}
function split_explicit_package_import(path)
{
if (!path) return null
@@ -429,6 +434,10 @@ function resolve_mod_fn(path, pkg) {
function resolve_locator(path, ctx)
{
var explicit = split_explicit_package_import(path)
if (explicit) {
if (is_internal_path(explicit.path) && ctx && explicit.package != ctx)
explicit = null
}
if (explicit) {
var explicit_path = get_packages_dir() + '/' + safe_package_path(explicit.package) + '/' + explicit.path
if (fd.is_file(explicit_path)) {
@@ -456,6 +465,9 @@ function resolve_locator(path, ctx)
return {path: ctx_path, scope: SCOPE_LOCAL, symbol: fn}
}
if (is_internal_path(path))
return null
// check for aliased dependency
var alias = pkg_tools.split_alias(ctx, path)
if (alias) {
@@ -510,16 +522,20 @@ function get_lib_path(pkg) {
// Resolve a C symbol by searching:
// 1. If package_context is null, only check core internal symbols
// 2. Otherwise: own package (internal then dylib) -> other packages (internal then dylib) -> core (internal only)
// Core is never loaded as a dynamic library via dlopen
function resolve_c_symbol(path, package_context)
{
var explicit = split_explicit_package_import(path)
if (explicit) {
var sym = make_c_symbol(explicit.package, explicit.path)
if (os.internal_exists(sym)) {
return {
symbol: function() { return os.load_internal(sym) },
scope: SCOPE_PACKAGE,
// Core is never loaded as a dynamic library via dlopen
function resolve_c_symbol(path, package_context)
{
var explicit = split_explicit_package_import(path)
if (explicit) {
if (is_internal_path(explicit.path) && package_context && explicit.package != package_context)
explicit = null
}
if (explicit) {
var sym = make_c_symbol(explicit.package, explicit.path)
if (os.internal_exists(sym)) {
return {
symbol: function() { return os.load_internal(sym) },
scope: SCOPE_PACKAGE,
package: explicit.package,
path: sym
}
@@ -575,6 +591,9 @@ function resolve_c_symbol(path, package_context)
}
}
if (is_internal_path(path))
return null
// 2. Check aliased package imports (e.g. 'prosperon/sprite')
var pkg_alias = get_import_package(path)
if (pkg_alias) {
@@ -622,7 +641,15 @@ function resolve_c_symbol(path, package_context)
return null
}
// Cache for resolved module info
var module_info_cache = {}
function resolve_module_info(path, package_context) {
var lookup_key = package_context ? package_context + ':' + path : ':' + path
if (module_info_cache[lookup_key])
return module_info_cache[lookup_key]
var c_resolve = resolve_c_symbol(path, package_context) || {scope:999}
var mod_resolve = resolve_locator(path + '.cm', package_context) || {scope:999}
var min_scope = number.min(c_resolve.scope, mod_resolve.scope)
@@ -630,58 +657,49 @@ function resolve_module_info(path, package_context) {
if (min_scope == 999)
return null
// Cache key is based on the realpath of the resolved file
// This ensures linked packages resolve to the same cache entry
// whether accessed via symlink or directly
var cache_key
if (mod_resolve.scope == SCOPE_CORE) {
cache_key = 'core/' + path
} else if (mod_resolve.scope < 900 && mod_resolve.path) {
// Use realpath to resolve symlinks and get the actual file location
var real_path = fd.realpath(mod_resolve.path)
if (real_path) {
// Derive cache key from the real path's package info
var real_info = Shop.file_info(real_path)
if (real_info.package && real_info.name) {
if (real_info.package && real_info.name)
cache_key = real_info.package + '/' + real_info.name
} else {
// Fallback to the realpath itself
else
cache_key = real_path
}
}
}
// Fallback for C-only modules or if realpath failed
if (!cache_key) {
if (min_scope == SCOPE_CORE) {
if (min_scope == SCOPE_CORE)
cache_key = 'core/' + path
} else if (min_scope == SCOPE_LOCAL && package_context) {
else if (min_scope == SCOPE_LOCAL && package_context)
cache_key = package_context + '/' + path
} else if (min_scope == SCOPE_PACKAGE) {
// For package imports like 'prosperon/sprite', resolve to canonical path
else if (min_scope == SCOPE_PACKAGE) {
var pkg_alias = get_import_package(path)
if (pkg_alias) {
var canon_pkg = get_canonical_package(pkg_alias, package_context)
if (canon_pkg) {
var mod_name = get_import_name(path)
cache_key = canon_pkg + '/' + mod_name
} else {
} else
cache_key = path
}
} else {
} else
cache_key = path
}
} else {
} else
cache_key = path
}
}
return {
var info = {
cache_key: cache_key,
c_resolve: c_resolve,
mod_resolve: mod_resolve,
min_scope: min_scope
}
module_info_cache[lookup_key] = info
return info
}
function get_module_cache_key(path, package_context) {
@@ -689,7 +707,7 @@ function get_module_cache_key(path, package_context) {
return info ? info.cache_key : null
}
Shop.is_loaded = function(path, package_context) {
Shop.is_loaded = function is_loaded(path, package_context) {
var cache_key = get_module_cache_key(path, package_context)
return use_cache[cache_key] != null
}
@@ -732,7 +750,7 @@ function execute_module(info)
} if (!used)
throw new Error(`Module ${info} returned null`)
stone(used)
// stone(used)
return used
}
@@ -745,7 +763,7 @@ function get_module(path, package_context) {
return execute_module(info)
}
Shop.use = function(path, package_context) {
Shop.use = function use(path, package_context) {
var info = resolve_module_info(path, package_context)
if (!info)
throw new Error(`Module ${path} could not be found in ${package_context}`)
@@ -1034,6 +1052,11 @@ Shop.file_reload = function(file)
Shop.module_reload = function(path, package) {
if (!Shop.is_loaded(path,package)) return
// Clear the module info cache for this path
var lookup_key = package ? package + ':' + path : ':' + path
module_info_cache[lookup_key] = null
var info = resolve_module_info(path, package)
if (!info) return
@@ -1044,10 +1067,9 @@ Shop.module_reload = function(path, package) {
for (var i in newmod)
old[i] = newmod[i]
for (var i in old) {
for (var i in old)
if (!(i in newmod))
old[i] = null
}
}
function get_package_scripts(package)

View File

@@ -13,7 +13,7 @@
// cell link gitea.pockle.world/john/prosperon github.com/prosperon (Links to another remote)
var link = use('link')
var shop = use('shop')
var shop = use('internal/shop')
var fd = use('fd')
var toml = use('toml')

View File

@@ -3,7 +3,7 @@
// cell list all -> list all packages (including those that are there due to installed packages)
// cell list package <name> -> list the packages for the package <name>
var shop = use('shop')
var shop = use('internal/shop')
var pkg = use('package')
var mode = 'local'

2
ls.ce
View File

@@ -2,7 +2,7 @@
// if args[0] is a package alias, list that one
// otherwise, list the local one
var shop = use('shop')
var shop = use('internal/shop')
var package = use('package')
var ctx = null

View File

@@ -6,7 +6,7 @@
// cell pack <package> -t <target> Cross-compile for target platform
var build = use('build')
var shop = use('shop')
var shop = use('internal/shop')
var pkg_tools = use('package')
var target = null

View File

@@ -1,6 +1,6 @@
// cell remove <alias|path> - Remove a package from dependencies or shop
var shop = use('shop')
var shop = use('internal/shop')
if (args.length < 1) {
log.console("Usage: cell remove <alias|path>")

View File

@@ -275,6 +275,11 @@ double cell_random() {
return (double)buf / 9007199254740992.0;
}
void cell_trace_sethook(cell_hook)
{
}
int uncaught_exception(JSContext *js, JSValue v)
{
cell_rt *rt = JS_GetContextOpaque(js);

View File

@@ -28,6 +28,11 @@ JSValue number2js(JSContext *js, double g);
JSValue wota2value(JSContext *js, void *v);
void *value2wota(JSContext *js, JSValue v, JSValue replacer, size_t *bytes);
#define CELL_HOOK_ENTER 1
#define CELL_HOOK_EXIT 2
typedef void (*cell_hook)(const char *name, int type);
void cell_trace_sethook(cell_hook);
// Macros to help with creating scripts
#define MIST_CFUNC_DEF(name, length, func1, props) { name, props, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }

View File

@@ -56,6 +56,7 @@ typedef struct cell_rt {
JSAtom actor_sym;
const char *name; // human friendly name
cell_hook trace_hook;
} cell_rt;
cell_rt *create_actor(void *wota);

View File

@@ -340,11 +340,9 @@ struct JSContext {
const char *filename, int flags, int scope_idx);
void *user_opaque;
js_hook fn_start_hook;
js_hook fn_end_hook;
js_hook fn_cycle_hook;
js_hook fn_gc_hook;
int hook_disabled;
js_hook trace_hook;
int trace_type;
void *trace_data;
};
typedef union JSFloat64Union {
@@ -1569,9 +1567,11 @@ JSContext *JS_NewContextRaw(JSRuntime *rt)
int i;
ctx = js_mallocz_rt(rt, sizeof(JSContext));
if (!ctx)
return NULL;
ctx->header.ref_count = 1;
ctx->trace_hook = NULL;
add_gc_object(rt, &ctx->header, JS_GC_OBJ_TYPE_JS_CONTEXT);
ctx->class_proto = js_malloc_rt(rt, sizeof(ctx->class_proto[0]) *
@@ -1586,7 +1586,6 @@ JSContext *JS_NewContextRaw(JSRuntime *rt)
ctx->class_proto[i] = JS_NULL;
ctx->array_ctor = JS_NULL;
ctx->regexp_ctor = JS_NULL;
JS_AddIntrinsicBasicObjects(ctx);
rt->js = ctx;
return ctx;
@@ -5943,6 +5942,38 @@ static int find_line_num(JSContext *ctx, JSFunctionBytecode *b,
return 0;
}
/* return a string property without executing arbitrary JS code (used
when dumping the stack trace or in debug print). */
static const char *get_prop_string(JSContext *ctx, JSValueConst obj, JSAtom prop)
{
JSObject *p;
JSProperty *pr;
JSShapeProperty *prs;
JSValueConst val;
if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)
return NULL;
p = JS_VALUE_GET_OBJ(obj);
prs = find_own_property(&pr, p, prop);
if (!prs) {
/* we look at one level in the prototype to handle the 'name'
field of the Error objects */
p = p->shape->proto;
if (!p)
return NULL;
prs = find_own_property(&pr, p, prop);
if (!prs)
return NULL;
}
if ((prs->flags & JS_PROP_TMASK) != JS_PROP_NORMAL)
return NULL;
val = pr->u.value;
if (JS_VALUE_GET_TAG(val) != JS_TAG_STRING)
return NULL;
return JS_ToCString(ctx, val);
}
/* in order to avoid executing arbitrary code during the stack trace
generation, we only look at simple 'name' properties containing a
string. */
@@ -5962,7 +5993,9 @@ static const char *get_func_name(JSContext *ctx, JSValueConst func)
val = pr->u.value;
if (JS_VALUE_GET_TAG(val) != JS_TAG_STRING)
return NULL;
return JS_ToCString(ctx, val);
// char *buf = js_malloc(ctx->rt, 128);
// return JS_AtomGetStr(ctx, buf, 128, prs->atom);
}
#define JS_BACKTRACE_FLAG_SKIP_FIRST_LEVEL (1 << 0)
@@ -12222,10 +12255,11 @@ static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj,
func = p->u.cfunc.c_function;
if (unlikely(ctx->fn_start_hook) && !ctx->hook_disabled) {
ctx->hook_disabled = 1;
ctx->fn_start_hook(ctx,func_obj);
ctx->hook_disabled = 0;
if (unlikely(ctx->trace_hook) && (ctx->trace_type & JS_HOOK_CALL)) {
js_debug dbg = {0};
js_debug_info(ctx, func_obj, &dbg);
ctx->trace_hook(ctx, JS_HOOK_CALL, &dbg, ctx->trace_data);
free_js_debug_info(ctx, &dbg);
}
switch(cproto) {
@@ -12312,13 +12346,14 @@ static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj,
}
rt->current_stack_frame = sf->prev_frame;
if (unlikely(ctx->fn_end_hook) && !ctx->hook_disabled) {
ctx->hook_disabled = 1;
ctx->fn_end_hook(ctx, func_obj);
ctx->hook_disabled = 0;
if (unlikely(ctx->trace_hook) && (ctx->trace_type & JS_HOOK_RET)) {
js_debug dbg = {0};
js_debug_info(ctx, func_obj, &dbg);
ctx->trace_hook(ctx, JS_HOOK_RET, &dbg, ctx->trace_data);
free_js_debug_info(ctx, &dbg);
}
return ret_val;
}
@@ -12418,10 +12453,11 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
}
b = p->u.func.function_bytecode;
if (unlikely(caller_ctx->fn_start_hook) && !caller_ctx->hook_disabled) {
caller_ctx->hook_disabled = 1;
caller_ctx->fn_start_hook(caller_ctx,func_obj);
caller_ctx->hook_disabled = 0;
if (unlikely(caller_ctx->trace_hook) && (caller_ctx->trace_type & JS_HOOK_CALL)) {
js_debug dbg = {0};
js_debug_info(caller_ctx, func_obj, &dbg);
caller_ctx->trace_hook(caller_ctx, JS_HOOK_CALL, &dbg, caller_ctx->trace_data);
free_js_debug_info(caller_ctx, &dbg);
}
if (unlikely(argc < b->arg_count || (flags & JS_CALL_FLAG_COPY_ARGV))) {
@@ -14584,11 +14620,12 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
}
rt->current_stack_frame = sf->prev_frame;
if (unlikely(caller_ctx->fn_end_hook) && !caller_ctx->hook_disabled) {
caller_ctx->hook_disabled = 1;
caller_ctx->fn_end_hook(caller_ctx,func_obj);
caller_ctx->hook_disabled = 0;
}
if (unlikely(caller_ctx->trace_hook) && (caller_ctx->trace_type & JS_HOOK_RET)) {
js_debug dbg = {0};
js_debug_info(caller_ctx, func_obj, &dbg);
caller_ctx->trace_hook(caller_ctx, JS_HOOK_RET, &dbg, caller_ctx->trace_data);
free_js_debug_info(caller_ctx, &dbg);
}
return ret_val;
}
@@ -36834,7 +36871,7 @@ void js_debug_info(JSContext *js, JSValue fn, js_debug *dbg)
if (!JS_IsObject(fn)) return;
JSObject *p = JS_VALUE_GET_OBJ(fn);
const char *fn_name = get_func_name(js,fn);
const char *fn_name = get_prop_string(js, fn, JS_ATOM_name);
if (!fn_name)
dbg->name = js_strdup(js, "<anonymous>");
@@ -36867,7 +36904,8 @@ void js_debug_info(JSContext *js, JSValue fn, js_debug *dbg)
dbg->closure_n = b->closure_var_count;
dbg->param_n = b->arg_count;
dbg->vararg = 1;
// dbg->line = b->debug.line_num;
int pcol_num;
dbg->line = find_line_num(js, b, -1, &pcol_num);
dbg->source = b->debug.source;
dbg->srclen = b->debug.source_len;
break;
@@ -36890,16 +36928,11 @@ void free_js_debug_info(JSContext *js, js_debug *dbg)
js_free(js, dbg->name);
}
void js_debug_sethook(JSContext *ctx, js_hook hook, int type)
void js_debug_sethook(JSContext *ctx, js_hook hook, int type, void *user)
{
if (type == JS_HOOK_CALL)
ctx->fn_start_hook = hook;
else if (type == JS_HOOK_RET)
ctx->fn_end_hook = hook;
else if (type == JS_HOOK_CYCLE)
ctx->fn_cycle_hook = hook;
else if (type == JS_HOOK_GC)
ctx->fn_gc_hook = hook;
ctx->trace_hook = hook;
ctx->trace_type = type;
ctx->trace_data = user;
}
uint32_t js_debugger_stack_depth(JSContext *ctx) {
@@ -37502,4 +37535,4 @@ void *js_debugger_val_address(JSContext *ctx, JSValue val) {
JSContext *JS_GetContext(JSRuntime *rt) {
return rt->js;
}
}

View File

@@ -961,7 +961,6 @@ void JS_PrintValueRT(JSRuntime *rt, JSPrintValueWrite *write_func, void *write_o
void JS_PrintValue(JSContext *ctx, JSPrintValueWrite *write_func, void *write_opaque,
JSValueConst val, const JSPrintValueOptions *options);
typedef struct js_debug {
const char *name; // nameof function
const char *what;
@@ -979,12 +978,12 @@ typedef struct js_debug {
void js_debug_info(JSContext *js, JSValue fn, js_debug *dbg);
void free_js_debug_info(JSContext *js, js_debug *dbg);
typedef void (*js_hook)(JSContext*, JSValue);
#define JS_HOOK_CALL 0
#define JS_HOOK_RET 1
#define JS_HOOK_CYCLE 2
#define JS_HOOK_GC 3
void js_debug_sethook(JSContext *ctx, js_hook, int type);
typedef void (*js_hook)(JSContext*, int type, js_debug *dbg, void *user);
#define JS_HOOK_CALL 1
#define JS_HOOK_RET 2
#define JS_HOOK_CYCLE 4
#define JS_HOOK_GC 8
void js_debug_sethook(JSContext *ctx, js_hook, int type, void *user);
uint32_t js_debugger_stack_depth(JSContext *ctx);
JSValue js_debugger_backtrace_fns(JSContext *ctx, const uint8_t *cur_pc);

View File

@@ -259,12 +259,7 @@ void actor_initialize(void) {
void actor_free(cell_rt *actor)
{
lockless_shdel(actors, actor->id);
// Note: Removing from ready queue is hard with a singly linked list.
// We assume actor_turn handles disrupted/freed actors gracefully or they run once more.
// The old code did lockless_rm(ready_queue, actor), which was O(N).
// Here we rely on the actor->disrupt flag checked in actor_turn.
// Do not go forward with actor destruction until the actor is completely free
pthread_mutex_lock(actor->msg_mutex);
pthread_mutex_lock(actor->mutex);
@@ -539,10 +534,6 @@ const char *register_actor(const char *id, cell_rt *actor, int mainthread, doubl
int actor_interrupt_cb(JSRuntime *rt, cell_rt *crt)
{
// Locking engine.lock for shutting_down might be too expensive for interrupt?
// Check atomic-like access or just access it.
// int s; pthread_mutex_lock(&engine.lock); s = engine.shutting_down; pthread_mutex_unlock(&engine.lock);
// But engine.shutting_down is int, atomic read on x86/arm usually ok.
return engine.shutting_down || crt->disrupt;
}
@@ -573,10 +564,12 @@ const char *send_message(const char *id, void *msg)
void actor_turn(cell_rt *actor)
{
pthread_mutex_lock(actor->mutex);
actor->state = ACTOR_RUNNING;
actor->state = ACTOR_RUNNING;
if (actor->trace_hook)
actor->trace_hook(actor->name, CELL_HOOK_ENTER);
TAKETURN:
pthread_mutex_lock(actor->msg_mutex);
@@ -605,20 +598,12 @@ void actor_turn(cell_rt *actor)
if (actor->disrupt) goto ENDTURN;
// Check if anyone else is waiting?
// In the new system, checking the global queue is expensive (lock).
// And "someone else waiting" logic was to yield.
// With threads, we don't need to yield as much, let the OS schedule.
// But we might want to prevent one actor hogging the worker?
// For now, remove the yield check or implement it with try_lock or simple check.
// int someone_else_waiting = (lockless_arrlen(ready_queue) > 0);
// We'll just remove the optimization/yield for now to simplify.
// if (!someone_else_waiting) goto TAKETURN;
ENDTURN:
actor->state = ACTOR_IDLE;
actor->state = ACTOR_IDLE;
if (actor->trace_hook)
actor->trace_hook(actor->name, CELL_HOOK_EXIT);
set_actor_state(actor);
pthread_mutex_unlock(actor->mutex);

View File

@@ -1,4 +1,4 @@
var shop = use('shop')
var shop = use('internal/shop')
var fd = use('fd')
var time = use('time')
var json = use('json')

View File

@@ -1,5 +1,3 @@
var text = use('text')
return {
// Array conversion tests
test_array_basic: function() {

View File

@@ -1,4 +1,3 @@
var text = use('text');
var blob = use('blob');
var utf8 = use('utf8');

View File

@@ -146,7 +146,7 @@ function encode_toml(obj) {
} else if (typeof value == 'boolean') {
return value ? 'true' : 'false'
} else if (typeof value == 'number') {
return String(value)
return text(value)
} else if (isa(value, array)) {
var items = []
for (var i = 0; i < value.length; i++) {
@@ -154,7 +154,7 @@ function encode_toml(obj) {
}
return '[' + items.join(', ') + ']'
}
return String(value)
return text(value)
}
function quote_key(k) {

View File

@@ -8,7 +8,7 @@
// cell update - Update all packages
// cell update <package> - Update a specific package
var shop = use('shop')
var shop = use('internal/shop')
var target_pkg = null

View File

@@ -1,4 +1,4 @@
var shop = use('shop')
var shop = use('internal/shop')
var fd = use('fd')
var cmd = args.length > 0 ? args[0] : null

5
util.cm Normal file
View File

@@ -0,0 +1,5 @@
var shop = use('internal/shop')
return {
file_reload: shop.file_reload
}

2
why.ce
View File

@@ -1,4 +1,4 @@
var shop = use('shop')
var shop = use('internal/shop')
var pkg = use('package')
if (!args || args.length < 1) {