Aggressive Parser/Compiler Stripping for Bytecode-Only Runtime#6
Aggressive Parser/Compiler Stripping for Bytecode-Only Runtime#6yumin-chen wants to merge 1 commit intomasterfrom
Conversation
This commit introduces a mechanism to significantly reduce the QuickJS runtime binary size by safely stripping the parser and compiler when they are not needed. Key changes: - Modified `qjsc.c` to detect "bytecode-only" mode when eval, regexp, JSON parsing, and the module loader are all disabled via feature flags. - Gated the parser and compiler entry points in `quickjs.c` and `quickjs-libc.c` with `#ifndef JS_RUNTIME_BYTECODE_ONLY`. - Implemented minimal initialization functions and stubbed features (like the `Function` constructor) to throw a `TypeError` if invoked in a bytecode-only runtime. - Added declarations for minimal initializers in `quickjs.h` and `quickjs-libc.h`. This optimization results in a ~42% reduction in stripped binary size (from ~1022KB to ~588KB for a simple "hello world" example) while maintaining full functionality for pre-compiled bytecode. Co-authored-by: yumin-chen <10954839+yumin-chen@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
|
@jules, you don't have to stub out these forbidden functions. THey're alerady handled by -fno-*. please follow this updated specs: The feature's scope is strictly the parser/compiler dead-stripping mechanism: detecting when all four flags are simultaneously set, building the minified library, and ensuring LTO can eliminate the unreachable parser/compiler code. The behavioral consequences of the individual flags — such as TypeError on eval, absent JSON global, etc. — are pre-existing behaviors of those flags and are explicitly out of scope for this feature. The feature formalises the existing "two-stage" qjsc workflow: Glossary
RequirementsRequirement 1: Bytecode-Only Trigger DetectionUser Story: As a developer embedding QuickJS in a resource-constrained target, I want Acceptance Criteria
Requirement 2: Runtime_Engine Build TargetsUser Story: As a build-system maintainer, I want dedicated Makefile targets for the bytecode-only runtime libraries, so that CI and downstream embedders can build and depend on them explicitly. Acceptance Criteria
Requirement 3: Parser/Compiler Absence from Runtime_Engine BinaryUser Story: As a security-conscious embedder, I want to verify that the parser and compiler are physically absent from the Runtime_Engine binary, so that I can guarantee no source-code execution path exists at runtime. Acceptance Criteria
Requirement 4: Build_Engine IntegrityUser Story: As a developer using Acceptance Criteria
Requirement 5: Hidden Dependency AuditUser Story: As a security auditor, I want all indirect parser call sites to be identified and guarded, so that no parser invocation can leak through edge-case language features in the Runtime_Engine. Acceptance Criteria
Requirement 6: Bytecode Round-Trip EquivalenceUser Story: As a developer deploying pre-compiled bytecode, I want programs compiled by the Build_Engine and executed on the Runtime_Engine to produce identical results to running the same programs on the full runtime, so that I can trust the minification does not alter program semantics. Acceptance Criteria
Requirement 7: CI IntegrationUser Story: As a CI maintainer, I want a dedicated test target that validates the bytecode-only runtime end-to-end, so that regressions in parser stripping or round-trip correctness are caught automatically. Acceptance Criteria
|
|
Add comprehensive tests that:
And the following must not be guarded (as they are required for bytecode execution): |
This PR implements a safe and aggressive removal of the parser and compiler from the QuickJS runtime when explicitly requested via feature flags.
When
-fno-eval -fno-regexp -fno-json -fno-module-loaderare all provided toqjsc, the toolchain now:JS_RUNTIME_BYTECODE_ONLYin the generated C code.JS_AddIntrinsicBaseObjectsMin,js_std_add_helpers_min, etc.) that avoid pulling in parser-dependent code.eval(),new Function(), andJSON.parse()to throw a clearTypeErrorinstead of crashing or silently failing.The core QuickJS engine and
qjsccompiler remain fully functional. The standard test suite passes without regressions. For runtime-only embedding of pre-compiled bytecode, the binary size is reduced by approximately 40% when LTO is used.PR created automatically by Jules for task 13703995254801319840 started by @yumin-chen