json: add v2 JsonDoc/JsonNode plugin with runtime provider switch; vendored yyjson + FFI; loader resolve(name)->method_id; PyVM JSON shims; smokes + CI gate; disable MiniVmPrints fallbacks by default

- plugin_loader_v2: store per-Box resolve() from TypeBox FFI; add resolve_method_id() and use in invoke_instance_method
- plugin_loader_unified: resolve_method() falls back to loader’s resolve when TOML lacks method entries
- nyash.toml: register JsonDocBox/JsonNodeBox methods (birth/parse/root/error; kind/get/size/at/str/int/bool)
- plugins/nyash-json-plugin:
  * serde/yyjson provider switch via env NYASH_JSON_PROVIDER (default serde)
  * vendored yyjson (c/yyjson) + shim; parse/root/get/size/at/str/int/bool implemented for yyjson
  * TLV void returns aligned to tag=9
- PyVM: add minimal JsonDocBox/JsonNodeBox shims in ops_box.py (for dev path)
- tests/smokes: add jsonbox_{parse_ok,parse_err,nested,collect_prints}; wire two into min-gate CI
- tools: collect_prints_mixed now uses JSON-based app
- MiniVmPrints: move BinaryOp and fallback heuristics behind a dev toggle (default OFF)
- CURRENT_TASK.md: updated with provider policy and fallback stance
This commit is contained in:
Selfhosting Dev
2025-09-22 06:16:20 +09:00
parent 0f96f2297d
commit 27568eb4a6
25 changed files with 20816 additions and 60 deletions

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 YaoYuan <ibireme@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
// Minimal shim to keep build/link path ready for a future yyjson backend.
// This file does not currently implement parsing; the Rust side still
// uses serde_json for actual parsing until the real yyjson integration lands.
#include <stdint.h>
#include <stddef.h>
#include "yyjson/yyjson.h"
// Parse JSON via yyjson and return 0 on success; non-zero error code on failure.
int nyash_json_shim_parse(const char *text, size_t len) {
yyjson_read_err err;
yyjson_doc *doc = yyjson_read_opts(text, len, 0, NULL, &err);
if (!doc) return (int)err.code;
yyjson_doc_free(doc);
return 0;
}
// Full wrappers exported with stable names for Rust FFI
void *nyjson_parse_doc(const char *text, size_t len, int *out_err_code) {
yyjson_read_err err;
yyjson_doc *doc = yyjson_read_opts(text, len, 0, NULL, &err);
if (!doc) {
if (out_err_code) *out_err_code = (int)err.code;
return NULL;
}
if (out_err_code) *out_err_code = 0;
return (void *)doc;
}
void nyjson_doc_free(void *doc) {
if (doc) yyjson_doc_free((yyjson_doc *)doc);
}
void *nyjson_doc_root(void *doc) {
if (!doc) return NULL;
return (void *)yyjson_doc_get_root((yyjson_doc *)doc);
}
int nyjson_is_null(void *v) { return v && yyjson_is_null((yyjson_val *)v); }
int nyjson_is_bool(void *v) { return v && yyjson_is_bool((yyjson_val *)v); }
int nyjson_is_int(void *v) { return v && yyjson_is_sint((yyjson_val *)v); }
int nyjson_is_real(void *v) { return v && yyjson_is_real((yyjson_val *)v); }
int nyjson_is_str(void *v) { return v && yyjson_is_str((yyjson_val *)v); }
int nyjson_is_arr(void *v) { return v && yyjson_is_arr((yyjson_val *)v); }
int nyjson_is_obj(void *v) { return v && yyjson_is_obj((yyjson_val *)v); }
int nyjson_get_bool_val(void *v) {
if (!v || !yyjson_is_bool((yyjson_val *)v)) return 0;
return yyjson_get_bool((yyjson_val *)v);
}
long long nyjson_get_sint_val(void *v) {
if (!v || !yyjson_is_sint((yyjson_val *)v)) return 0;
return (long long)yyjson_get_sint((yyjson_val *)v);
}
const char *nyjson_get_str_val(void *v) {
if (!v || !yyjson_is_str((yyjson_val *)v)) return NULL;
return yyjson_get_str((yyjson_val *)v);
}
size_t nyjson_arr_size_val(void *v) {
if (!v || !yyjson_is_arr((yyjson_val *)v)) return 0;
return yyjson_arr_size((yyjson_val *)v);
}
void *nyjson_arr_get_val(void *v, size_t idx) {
if (!v || !yyjson_is_arr((yyjson_val *)v)) return NULL;
return (void *)yyjson_arr_get((yyjson_val *)v, idx);
}
size_t nyjson_obj_size_val(void *v) {
if (!v || !yyjson_is_obj((yyjson_val *)v)) return 0;
return yyjson_obj_size((yyjson_val *)v);
}
void *nyjson_obj_get_key(void *v, const char *key) {
if (!v || !yyjson_is_obj((yyjson_val *)v) || !key) return NULL;
return (void *)yyjson_obj_get((yyjson_val *)v, key);
}