openscad-cpp-evaluator 0.13.0__tar.gz → 0.13.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/bytecode.hpp +125 -17
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/bytecode_vm.hpp +25 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/evaluator.hpp +50 -17
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/builtins.hpp +16 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/color.cpp +10 -6
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/transforms.cpp +7 -3
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/bytecode_compiler.cpp +102 -9
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/bytecode_vm.cpp +126 -5
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/user_calls.cpp +8 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/CMakeLists.txt +13 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_bytecode_compiler.cpp +74 -13
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_debug_hooks.cpp +47 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_tail_calls.cpp +2 -2
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tools/cli/CMakeLists.txt +9 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/.gitignore +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/.gitmodules +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/LICENSE +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/README.md +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/stb_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/text/stb_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-0.13.0 → openscad_cpp_evaluator-0.13.2}/tools/cli/main.cpp +0 -0
|
@@ -260,26 +260,101 @@ enum class Op {
|
|
|
260
260
|
// which splice is unconditional).
|
|
261
261
|
CallModule,
|
|
262
262
|
|
|
263
|
-
//
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
//
|
|
267
|
-
//
|
|
268
|
-
//
|
|
269
|
-
//
|
|
270
|
-
// Op::
|
|
271
|
-
//
|
|
272
|
-
//
|
|
263
|
+
// -- Builtin-wrap compilation (closes the "NativeStatement gap" for ----
|
|
264
|
+
// -- translate/rotate/scale/mirror/multmatrix/resize/color/#/%/!) ------
|
|
265
|
+
// A builtin-with-children statement that isn't a "call" the way
|
|
266
|
+
// Op::CallModule's target is (no callStack_/profiling participation,
|
|
267
|
+
// no named scope with upvalue semantics -- see CompiledChunk::
|
|
268
|
+
// BuiltinWrapSite's own doc comment for the full "why this doesn't
|
|
269
|
+
// need vmCallStack_/pushBracketedModuleFrame-style bracketing"
|
|
270
|
+
// reasoning) -- so unlike Op::CallModule, its children compile INLINE
|
|
271
|
+
// into the SAME instruction stream (via compileStatementList, exactly
|
|
272
|
+
// like Op::OpenLetScope's own body does for ModularLet) rather than
|
|
273
|
+
// becoming a separate chunk. Exists because falling through to
|
|
274
|
+
// Op::NativeStatement here was a REAL, proven Windows/MSVC crash risk
|
|
275
|
+
// for a recursive translate()/multmatrix()-wrapped module chain (see
|
|
276
|
+
// this project's own session notes: BOSL2's attachable() machinery
|
|
277
|
+
// needs native reentry depth ~55, past the empirically-proven-unsafe
|
|
278
|
+
// Windows ceiling for that reentry mechanism -- no depth-guard tuning
|
|
279
|
+
// could satisfy both "the real script works" and "Windows doesn't
|
|
280
|
+
// crash", only eliminating the native reentry itself could).
|
|
281
|
+
//
|
|
282
|
+
// a = index into CompiledChunk::builtinWrapSites. Runtime handler:
|
|
283
|
+
// captures ev.randsCallCount() BEFORE any argument resolution
|
|
284
|
+
// (mirrors Evaluator::buildTreeNode's own ordering exactly -- doing
|
|
285
|
+
// this AFTER would silently drop uncacheable/ManifoldCache taint
|
|
286
|
+
// tracking for a rands() call embedded in the wrapper's own
|
|
287
|
+
// arguments), computes this site's own params (and, for Transform/
|
|
288
|
+
// Color kinds, a possibly-$-scoped child EvalContext, pushed onto
|
|
289
|
+
// f.ctxChain unconditionally -- Modifier kind needs neither params
|
|
290
|
+
// nor a ctx push), pushes a fresh ev.treeStack_ frame, and stashes
|
|
291
|
+
// {params, randsBefore, siteIdx} onto VmFrame::builtinWrapStack (a
|
|
292
|
+
// real per-frame LIFO stack, not a single slot: Push/PopBuiltinWrap
|
|
293
|
+
// pairs can nest or sequence within one frame's own instruction
|
|
294
|
+
// stream, e.g. `translate(a) translate(b) recur();`). The compiler
|
|
295
|
+
// always emits a plain Op::CheckDebugStatement immediately before
|
|
296
|
+
// this (see emitBuiltinWrap, bytecode_compiler.cpp), mirroring
|
|
297
|
+
// ModularEcho/ModularAssert's own pattern -- NOT skipped the way
|
|
298
|
+
// Op::CallModule's own call site skips one: this is a genuine
|
|
299
|
+
// statement doing real work here, unlike a module call (which
|
|
300
|
+
// transfers control to a declaration whose OWN body statements each
|
|
301
|
+
// get their own check instead).
|
|
302
|
+
PushBuiltinWrap,
|
|
303
|
+
|
|
304
|
+
// Closes the matching Op::PushBuiltinWrap bracket: pops
|
|
305
|
+
// VmFrame::builtinWrapStack's own top entry FIRST (before anything
|
|
306
|
+
// that can itself throw, e.g. Evaluator::setTreeDepthOrThrow below --
|
|
307
|
+
// so the exception-teardown path's own pending count is already
|
|
308
|
+
// correct if THIS throws), pops the ctx push Push made (Transform/
|
|
309
|
+
// Color kinds only), pops ev.treeStack_ to retrieve the children this
|
|
310
|
+
// bracket's own body produced, and builds the tagged CSGNode exactly
|
|
311
|
+
// like Evaluator::buildTreeNode's own post-resolveBody() half does
|
|
312
|
+
// (kind/node/isBuiltin=true/children/params/uncacheable/
|
|
313
|
+
// setTreeDepthOrThrow), pushing it onto the new top of treeStack_. a
|
|
314
|
+
// = index into CompiledChunk::builtinWrapSites (same site Push used).
|
|
315
|
+
//
|
|
316
|
+
// teardownVmCallStackDownTo's own exception path (bytecode_vm.cpp)
|
|
317
|
+
// pops frame->builtinWrapStack.size() additional treeStack_ entries
|
|
318
|
+
// per torn-down frame, on top of its existing ownsModuleSplice-gated
|
|
319
|
+
// pop -- required because an exception can leave N of these brackets
|
|
320
|
+
// open in one frame, unlike the "at most one Op::CallModule splice
|
|
321
|
+
// per frame" shape that gated pop was originally sized for. See
|
|
322
|
+
// releaseVmFrame's own doc comment (user_calls.cpp) for a real,
|
|
323
|
+
// previously-ASan-caught bug from exactly this class of mismatched-
|
|
324
|
+
// bookkeeping-vs-treeStack_-depth mistake (a 1-bit version of the
|
|
325
|
+
// same seam, now a counter).
|
|
326
|
+
PopBuiltinWrap,
|
|
327
|
+
|
|
328
|
+
// A single "native passthrough" statement -- intersection_for,
|
|
329
|
+
// children(), union/difference/intersection and every other builtin
|
|
330
|
+
// module call NOT covered by Op::PushBuiltinWrap (see that op's own
|
|
331
|
+
// doc comment for exactly which builtins ARE covered), the `*`
|
|
332
|
+
// modifier's own no-op case, or a user-module call that didn't
|
|
333
|
+
// resolve at compile time (shadowed, forward-declared, or otherwise
|
|
334
|
+
// not statically known) -- anything compileStatementList doesn't give
|
|
335
|
+
// its own real bytecode. (Assignment/ModularEcho/ModularAssert/
|
|
336
|
+
// ModularLet used to fall here too; they now have their own real
|
|
337
|
+
// bytecode -- Op::StoreModuleVar/Op::Echo/Op::AssertStatement/
|
|
338
|
+
// Op::OpenLetScope+StoreLetVar -- purely a throughput change, since
|
|
339
|
+
// none of these were ever the recursion-depth risk this compiler
|
|
340
|
+
// targets. `#`/`%`/`!` modifiers and translate/rotate/scale/mirror/
|
|
341
|
+
// multmatrix/resize/color used to fall here too, for the SAME
|
|
342
|
+
// throughput reasoning -- WRONG in that one specific case: a
|
|
343
|
+
// recursive module call wrapped in one of these is exactly the
|
|
344
|
+
// pattern that made this op's own native reentry a genuine Windows
|
|
345
|
+
// crash risk in practice, not just a missed optimization. See
|
|
346
|
+
// Op::PushBuiltinWrap's own doc comment for the real story and the
|
|
347
|
+
// fix.)
|
|
273
348
|
// a = index into CompiledChunk::nativeStatements. Runtime just does
|
|
274
349
|
// what Evaluator::evalChildren's own per-statement loop already does
|
|
275
350
|
// for one node: derive childCtx via ctx.withScope(...), checkDebug,
|
|
276
|
-
// evalStatement. These are "leaf-shaped"
|
|
277
|
-
//
|
|
278
|
-
//
|
|
279
|
-
//
|
|
280
|
-
//
|
|
281
|
-
//
|
|
282
|
-
//
|
|
351
|
+
// evalStatement. These are still "leaf-shaped" for what's left here
|
|
352
|
+
// after Op::PushBuiltinWrap peeled off the proven-risky subset: real
|
|
353
|
+
// recursion safety for a recursive module chain is covered by
|
|
354
|
+
// CallModule/PushBuiltinWrap/ForIterNext/the Jump-based if/for control
|
|
355
|
+
// flow, not by how many of THESE sit alongside them in the same body
|
|
356
|
+
// -- true again now that the one construct that violated it
|
|
357
|
+
// (translate()-wrapped recursion) has its own real bytecode instead.
|
|
283
358
|
NativeStatement,
|
|
284
359
|
|
|
285
360
|
// If/if-else's own condition, evaluated NATIVELY (Evaluator::
|
|
@@ -583,6 +658,38 @@ struct CompiledChunk {
|
|
|
583
658
|
std::string calleeName;
|
|
584
659
|
};
|
|
585
660
|
|
|
661
|
+
// One Op::PushBuiltinWrap/PopBuiltinWrap site pair -- a builtin-with-
|
|
662
|
+
// children statement recognized at COMPILE time as one of the small,
|
|
663
|
+
// closed set this covers (see Op::PushBuiltinWrap's own doc comment
|
|
664
|
+
// for the full list and the Windows-crash rationale). Unlike
|
|
665
|
+
// ModuleCallSite, this is NOT "a call" -- see this struct's own `kind`
|
|
666
|
+
// discriminator and Evaluator::evalModularCall/buildTreeNode/
|
|
667
|
+
// evalModifier (csg_resolve.cpp): builtins never touch callStack_ or
|
|
668
|
+
// fire profileEnter/profileExit, native or compiled, so there's no
|
|
669
|
+
// enterUserCall-style bracketing to represent here, just enough to
|
|
670
|
+
// replay the native param-resolution step and rebuild the tagged
|
|
671
|
+
// CSGNode at Pop time.
|
|
672
|
+
//
|
|
673
|
+
// `node`'s concrete type depends on `kind`: Transform/Color sites are
|
|
674
|
+
// genuine `ModularCall`s (down-cast to read `.name`/`.arguments`/
|
|
675
|
+
// `.children`); Modifier sites are the wrapper node itself
|
|
676
|
+
// (`ModularModifierHighlight`/`Background`/`ShowOnly` -- `!`/`#`/`%`;
|
|
677
|
+
// `*`/Disable never reaches here, its child never evaluates at all,
|
|
678
|
+
// so it stays Op::NativeStatement's no-op-shaped native path), which
|
|
679
|
+
// does NOT derive from ModularCall (it derives from
|
|
680
|
+
// ModuleInstantiation directly and carries a single `child`) -- read
|
|
681
|
+
// via its own concrete type when kind == Modifier, never as a
|
|
682
|
+
// ModularCall. Stored as the generic `ASTNode*` here (not a tagged
|
|
683
|
+
// union of concrete pointers) because that's all Op::PopBuiltinWrap
|
|
684
|
+
// itself ever needs `node` for: the resulting CSGNode's own
|
|
685
|
+
// `node`/error-position field.
|
|
686
|
+
struct BuiltinWrapSite {
|
|
687
|
+
enum class Kind { Transform, Color, Modifier };
|
|
688
|
+
Kind kind;
|
|
689
|
+
std::string tagName; // "translate"/"rotate"/.../"color"/"highlight"/"background"/"show_only"
|
|
690
|
+
const oscad::ASTNode* node = nullptr;
|
|
691
|
+
};
|
|
692
|
+
|
|
586
693
|
// One Op::AssertStatement site -- see that op's own doc comment for
|
|
587
694
|
// the full contract. `conditionArgIndex`/`messageArgIndex` are indices
|
|
588
695
|
// into the site's own argCount-sized popped-argument array (source
|
|
@@ -644,6 +751,7 @@ struct CompiledChunk {
|
|
|
644
751
|
// NativeCondJumpIfFalse/NativeCheckDebugExprLevel/NativeIterMaterialize's
|
|
645
752
|
// own doc comments, above) -- always empty for a function chunk.
|
|
646
753
|
std::vector<ModuleCallSite> moduleCallSites;
|
|
754
|
+
std::vector<BuiltinWrapSite> builtinWrapSites;
|
|
647
755
|
std::vector<AssertSite> assertSites;
|
|
648
756
|
std::vector<const oscad::Expression*> nativeExprs;
|
|
649
757
|
std::vector<const oscad::ASTNode*> nativeStatements;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
#include "openscad_cpp_evaluator/bound_args.hpp"
|
|
4
4
|
#include "openscad_cpp_evaluator/bytecode.hpp"
|
|
5
|
+
#include "openscad_cpp_evaluator/csg_node.hpp"
|
|
5
6
|
#include "openscad_cpp_evaluator/eval_context.hpp"
|
|
6
7
|
#include "openscad_cpp_evaluator/value.hpp"
|
|
7
8
|
|
|
@@ -16,6 +17,19 @@ namespace oscadeval {
|
|
|
16
17
|
|
|
17
18
|
class Evaluator;
|
|
18
19
|
|
|
20
|
+
// One still-open Op::PushBuiltinWrap bracket's own state, needed again by
|
|
21
|
+
// its matching Op::PopBuiltinWrap -- see that op's own doc comment
|
|
22
|
+
// (bytecode.hpp) for the full contract. Lives in the header for the same
|
|
23
|
+
// reason IterList does, just above: it travels with a VmFrame (VmFrame::
|
|
24
|
+
// builtinWrapStack, below), not a free-standing local, since Push/
|
|
25
|
+
// PopBuiltinWrap pairs can nest or sequence within one frame's own
|
|
26
|
+
// instruction stream.
|
|
27
|
+
struct PendingBuiltinWrap {
|
|
28
|
+
CSGParams params;
|
|
29
|
+
std::uint64_t randsBefore = 0;
|
|
30
|
+
int siteIdx = -1;
|
|
31
|
+
};
|
|
32
|
+
|
|
19
33
|
// One ListCompFor/statement-for assignment's own materialized iteration
|
|
20
34
|
// state -- see Op::IterMaterialize/IterReset/IterNext's own doc comments
|
|
21
35
|
// (bytecode.hpp). Lives in the header (not bytecode_vm.cpp's own anonymous
|
|
@@ -102,6 +116,17 @@ struct VmFrame {
|
|
|
102
116
|
std::vector<std::vector<Value>> accumStack;
|
|
103
117
|
std::vector<IterList> iterLists;
|
|
104
118
|
std::vector<EvalContext> ctxChain;
|
|
119
|
+
// Still-open Op::PushBuiltinWrap brackets, LIFO, scoped to THIS frame's
|
|
120
|
+
// own instruction stream -- mirrors accumStack/iterLists' own role for
|
|
121
|
+
// their respective bracket pairs. Normal execution always drains this
|
|
122
|
+
// back to empty (every Push has a compile-time-matched Pop); only the
|
|
123
|
+
// exception-teardown path (teardownVmCallStackDownTo, bytecode_vm.cpp)
|
|
124
|
+
// needs to know its size, to pop the matching number of extra
|
|
125
|
+
// treeStack_ entries for a frame torn down mid-bracket. Not explicitly
|
|
126
|
+
// cleared in releaseVmFrame, same as accumStack/ctxChain -- the
|
|
127
|
+
// existing invariant ("whoever pops this frame drains its own open
|
|
128
|
+
// brackets first") already covers it.
|
|
129
|
+
std::vector<PendingBuiltinWrap> builtinWrapStack;
|
|
105
130
|
// The ORIGINAL callee name at push time, used by
|
|
106
131
|
// Evaluator::exitUserCallSuccess's own returnHook call when this frame
|
|
107
132
|
// carries a bracket -- deliberately NOT updated by a later tail hop
|
|
@@ -559,18 +559,25 @@ private:
|
|
|
559
559
|
void buildTreeNode(const std::string& kind, const oscad::ASTNode& node,
|
|
560
560
|
const std::function<CSGParams()>& resolveBody);
|
|
561
561
|
|
|
562
|
+
// -- User function/module calls (Phase 4) --------------------------
|
|
563
|
+
|
|
564
|
+
public:
|
|
562
565
|
// Sets node.treeDepth from its own (already-finalized) `children`,
|
|
563
566
|
// throwing (kMaxCsgTreeDepth's own doc comment, above, for why) if
|
|
564
567
|
// it's now too deep. Called by every csg_resolve.cpp site that
|
|
565
568
|
// finalizes a CSGNode's own `children` -- buildTreeNode,
|
|
566
569
|
// evalModularCall's non-splice tail, spliceModuleChildren's
|
|
567
570
|
// union-wrap branch -- right after assigning `children`, before the
|
|
568
|
-
// node is ever linked into anything a caller could see.
|
|
571
|
+
// node is ever linked into anything a caller could see. Public (not
|
|
572
|
+
// alongside buildTreeNode/evalModularCall, just above, which stay
|
|
573
|
+
// private member functions): Op::PopBuiltinWrap's own runtime handler
|
|
574
|
+
// (bytecode_vm.cpp, a free function, same "needs direct access, no
|
|
575
|
+
// friend declaration in play" reasoning as treeStack_/randsCallCount()
|
|
576
|
+
// above) calls this directly, replicating buildTreeNode's own
|
|
577
|
+
// post-resolveBody() half rather than going through it (the "body"
|
|
578
|
+
// there already ran as bytecode, not a callback buildTreeNode could
|
|
579
|
+
// invoke).
|
|
569
580
|
void setTreeDepthOrThrow(CSGNode& node, const oscad::ASTNode& errNode);
|
|
570
|
-
|
|
571
|
-
// -- User function/module calls (Phase 4) --------------------------
|
|
572
|
-
|
|
573
|
-
public:
|
|
574
581
|
// Picks between an isolated call scope (callCtx()) and a closure-
|
|
575
582
|
// capturing one (childCtx()) for entering `decl`'s body: walks the
|
|
576
583
|
// live call stack, and if `decl`'s own declaration span is *strictly*
|
|
@@ -1351,18 +1358,44 @@ public:
|
|
|
1351
1358
|
// doubled to 100 for headroom -- that immediately segfaulted on
|
|
1352
1359
|
// Windows CI (ModuleBodyCompiles.
|
|
1353
1360
|
// NativeReentrantRecursionHitsAControlledErrorInsteadOfCrashing, its
|
|
1354
|
-
// own guard-safety regression test
|
|
1355
|
-
//
|
|
1356
|
-
//
|
|
1357
|
-
//
|
|
1358
|
-
//
|
|
1359
|
-
//
|
|
1360
|
-
//
|
|
1361
|
-
//
|
|
1362
|
-
//
|
|
1363
|
-
//
|
|
1364
|
-
//
|
|
1365
|
-
//
|
|
1361
|
+
// own guard-safety regression test at the time -- since renamed/
|
|
1362
|
+
// repurposed, see Op::PushBuiltinWrap below). Backed off to 50 --
|
|
1363
|
+
// STILL segfaulted there. Confirms this chain's real per-level
|
|
1364
|
+
// native-frame cost is heavier than kMaxUserCallDepth's own (which
|
|
1365
|
+
// needed the SAME kind of comedown, an initial 50 down to 30, for a
|
|
1366
|
+
// shallower chain), and that Windows' real safe ceiling for THIS
|
|
1367
|
+
// chain sits somewhere below 50, above the already-Windows-verified-
|
|
1368
|
+
// safe 30 (confirmed safe by PR #60's own successful merge, before
|
|
1369
|
+
// this value ever changed). Landed at 40.
|
|
1370
|
+
//
|
|
1371
|
+
// A real stack-margin check (nativeStackMarginLow(), since removed --
|
|
1372
|
+
// see git history for `native_stack.hpp`/`.cpp` if the exact mechanism
|
|
1373
|
+
// is ever needed again) was tried as a REPLACEMENT for this fixed
|
|
1374
|
+
// count, specifically because BOSL2's attachable() machinery
|
|
1375
|
+
// (Anklet.scad) needed native reentry depth 55, past this ceiling --
|
|
1376
|
+
// and confirmed working for that: Anklet.scad rendered successfully
|
|
1377
|
+
// with an unmodified build. But the margin-based check was THEN
|
|
1378
|
+
// confirmed, via two separate real Windows CI runs, to segfault for a
|
|
1379
|
+
// DIFFERENT deep native-reentry chain (union()-wrapped recursion)
|
|
1380
|
+
// regardless of total thread stack size (an 8 MiB Windows stack,
|
|
1381
|
+
// matching macOS's own default byte-for-byte, still crashed at the
|
|
1382
|
+
// same depth) -- i.e. this fixed count, not the margin check, is the
|
|
1383
|
+
// mechanism actually proven safe on Windows for genuine deep native
|
|
1384
|
+
// reentry; the margin check is not a safe general replacement for it.
|
|
1385
|
+
//
|
|
1386
|
+
// The REAL fix for Anklet.scad turned out to be architectural, not a
|
|
1387
|
+
// better safety-check mechanism: Op::PushBuiltinWrap/PopBuiltinWrap
|
|
1388
|
+
// (bytecode.hpp/bytecode_compiler.cpp/bytecode_vm.cpp) eliminates
|
|
1389
|
+
// native reentry ENTIRELY for the specific pattern that needed depth
|
|
1390
|
+
// 55 (translate/rotate/scale/mirror/multmatrix/resize/color/#/%/!-
|
|
1391
|
+
// wrapped recursion) by compiling it to run on the heap-based
|
|
1392
|
+
// vmCallStack_ instead of falling to Op::NativeStatement -- so this
|
|
1393
|
+
// guard no longer needs to accommodate that case at all. What's left
|
|
1394
|
+
// uncovered (union/difference/intersection-wrapped recursion, other
|
|
1395
|
+
// builtins, fully interpreted-mode scripts) is genuinely "leaf-shaped"
|
|
1396
|
+
// again in the sense Stage 2's original design assumed, comfortably
|
|
1397
|
+
// within this fixed, Windows-proven-safe ceiling for any realistic
|
|
1398
|
+
// script. Do not raise this value again based on local (macOS/Linux)
|
|
1366
1399
|
// testing alone -- only a real Windows CI pass is evidence of safety
|
|
1367
1400
|
// here. Deliberately its own named constant (not a reuse of
|
|
1368
1401
|
// kMaxUserCallDepth) so the two can be recalibrated independently.
|
|
@@ -38,13 +38,29 @@ CSGParams resolve2d(Evaluator& ev, const oscad::ModularCall& node, EvalContext&
|
|
|
38
38
|
std::vector<ColoredBody> generate2d(Evaluator& ev, const CSGParams& params,
|
|
39
39
|
const std::vector<std::unique_ptr<CSGNode>>& children, const oscad::ASTNode& node);
|
|
40
40
|
|
|
41
|
+
// Shared return shape for computeTransformParams/computeColorParams,
|
|
42
|
+
// below -- the "resolve args, build params, compute a possibly-$-scoped
|
|
43
|
+
// child ctx" half of resolveTransform/resolveColor, split out so
|
|
44
|
+
// Op::PushBuiltinWrap's own runtime handler (bytecode_vm.cpp) can call it
|
|
45
|
+
// directly instead of going through the full resolve function (whose
|
|
46
|
+
// OTHER half, `ev.evalChildren(...)`, is exactly the native reentry this
|
|
47
|
+
// split exists to avoid). `ctx` is the input ctx unchanged unless this
|
|
48
|
+
// builtin's own resolution opened a new one (mirrors ResolvedCallArgs's
|
|
49
|
+
// own `ctx` field, call_args.hpp).
|
|
50
|
+
struct BuiltinWrapParams {
|
|
51
|
+
CSGParams params;
|
|
52
|
+
EvalContext ctx;
|
|
53
|
+
};
|
|
54
|
+
|
|
41
55
|
// translate/rotate/scale/mirror/multmatrix/resize share one resolve/
|
|
42
56
|
// generate pair (2D/3D dispatch happens per-body at generate time).
|
|
57
|
+
BuiltinWrapParams computeTransformParams(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx);
|
|
43
58
|
CSGParams resolveTransform(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx);
|
|
44
59
|
std::vector<ColoredBody> generateTransform(Evaluator& ev, const CSGParams& params,
|
|
45
60
|
const std::vector<std::unique_ptr<CSGNode>>& children,
|
|
46
61
|
const oscad::ASTNode& node);
|
|
47
62
|
|
|
63
|
+
BuiltinWrapParams computeColorParams(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx);
|
|
48
64
|
CSGParams resolveColor(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx);
|
|
49
65
|
std::vector<ColoredBody> generateColor(Evaluator& ev, const CSGParams& params,
|
|
50
66
|
const std::vector<std::unique_ptr<CSGNode>>& children, const oscad::ASTNode& node);
|
|
@@ -12,7 +12,7 @@ namespace oscadeval {
|
|
|
12
12
|
// case). Sets the color on ctx for every descendant statement. Mirrors
|
|
13
13
|
// _resolve_color/_generate_color.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
BuiltinWrapParams computeColorParams(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx) {
|
|
16
16
|
auto [args, effCtx] = resolveCallArgs(ev, node.arguments, ctx);
|
|
17
17
|
const Value defaultC =
|
|
18
18
|
Value{std::make_shared<const ValueList>(ValueList{{Value{1.0}, Value{1.0}, Value{1.0}, Value{1.0}}})};
|
|
@@ -33,15 +33,19 @@ CSGParams resolveColor(Evaluator& ev, const oscad::ModularCall& node, EvalContex
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
EvalContext childCtx = effCtx.childCtx(nullptr, std::optional<std::array<double, 4>>(rgba));
|
|
36
|
+
CSGParams params;
|
|
37
|
+
params["rgba"] = colorToValue(rgba);
|
|
38
|
+
return BuiltinWrapParams{std::move(params), std::move(childCtx)};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
CSGParams resolveColor(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx) {
|
|
42
|
+
BuiltinWrapParams result = computeColorParams(ev, node, ctx);
|
|
36
43
|
// Evaluated for the side effect of building the children's own CSGNodes
|
|
37
44
|
// under the color-tagged context -- the returned bodies themselves are
|
|
38
45
|
// unused here; generate reads them back via each child's own .bodies
|
|
39
46
|
// and stamps `rgba` onto all of them. Mirrors _resolve_color.
|
|
40
|
-
ev.evalChildren(node.children,
|
|
41
|
-
|
|
42
|
-
CSGParams params;
|
|
43
|
-
params["rgba"] = colorToValue(rgba);
|
|
44
|
-
return params;
|
|
47
|
+
ev.evalChildren(node.children, result.ctx);
|
|
48
|
+
return std::move(result.params);
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
std::vector<ColoredBody> generateColor(Evaluator&, const CSGParams& params,
|
|
@@ -164,7 +164,7 @@ manifold::CrossSection applyTransform2d(const std::string& name, const CallArgs&
|
|
|
164
164
|
|
|
165
165
|
} // namespace
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
BuiltinWrapParams computeTransformParams(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx) {
|
|
168
168
|
const std::string& name = node.name->name;
|
|
169
169
|
auto [args, effCtx] = resolveCallArgs(ev, node.arguments, ctx);
|
|
170
170
|
|
|
@@ -176,9 +176,13 @@ CSGParams resolveTransform(Evaluator& ev, const oscad::ModularCall& node, EvalCo
|
|
|
176
176
|
// getArg() again in applyTransform2d/3d below, instead of resolving
|
|
177
177
|
// e.g. "v"/"a" to a concrete vec3/vec2 here.
|
|
178
178
|
params["args"] = callArgsToValue(args);
|
|
179
|
+
return BuiltinWrapParams{std::move(params), std::move(effCtx)};
|
|
180
|
+
}
|
|
179
181
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
+
CSGParams resolveTransform(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx) {
|
|
183
|
+
BuiltinWrapParams result = computeTransformParams(ev, node, ctx);
|
|
184
|
+
ev.evalChildren(node.children, result.ctx);
|
|
185
|
+
return std::move(result.params);
|
|
182
186
|
}
|
|
183
187
|
|
|
184
188
|
std::vector<ColoredBody> generateTransform(Evaluator&, const CSGParams& params,
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
#include "openscad_cpp_evaluator/bytecode_compiler.hpp"
|
|
2
2
|
|
|
3
3
|
#include "openscad_cpp_evaluator/call_args.hpp"
|
|
4
|
+
#include "openscad_cpp_evaluator/dispatch.hpp"
|
|
4
5
|
#include "openscad_cpp_evaluator/function_builtins.hpp"
|
|
5
6
|
|
|
7
|
+
#include "builtins/builtins.hpp"
|
|
8
|
+
|
|
6
9
|
#include "openscad_cpp_parser/ast/declarations.hpp"
|
|
7
10
|
#include "openscad_cpp_parser/ast/expression.hpp"
|
|
8
11
|
#include "openscad_cpp_parser/ast/module_instantiation.hpp"
|
|
@@ -1163,6 +1166,42 @@ public:
|
|
|
1163
1166
|
out.push_back({Op::CloseExprScope, 0, 0, nullptr});
|
|
1164
1167
|
}
|
|
1165
1168
|
|
|
1169
|
+
// Shared by ModularCall's Transform/Color-kind branch and the 3 real
|
|
1170
|
+
// modifier cases (ModularModifierHighlight/Background/ShowOnly),
|
|
1171
|
+
// below -- emits one Op::PushBuiltinWrap/PopBuiltinWrap bracket around
|
|
1172
|
+
// `children` compiled inline (exactly like ModularLet's own body
|
|
1173
|
+
// does, via this same compileStatementList recursion). See
|
|
1174
|
+
// Op::PushBuiltinWrap's own doc comment (bytecode.hpp) for the full
|
|
1175
|
+
// design and why this specific set doesn't fall to Op::NativeStatement
|
|
1176
|
+
// like other builtins-with-children still do.
|
|
1177
|
+
//
|
|
1178
|
+
// Op::CheckDebugStatement emitted first, mirroring ModularEcho/
|
|
1179
|
+
// ModularAssert's own pattern (both above) -- NOT Op::CallModule's own
|
|
1180
|
+
// lack of one: that omission is specific to a resolved USER MODULE
|
|
1181
|
+
// call, whose own body statements each get their own check instead
|
|
1182
|
+
// (mirrors evalUserModule's "no body-entry checkDebug of its own",
|
|
1183
|
+
// evaluator.hpp). A builtin wrap statement isn't "control transferring
|
|
1184
|
+
// to a declaration" the way a module call is -- it's a plain statement
|
|
1185
|
+
// representing real work happening HERE, exactly like echo/assert/
|
|
1186
|
+
// assignment, which is why those get their own checkpoint. Confirmed
|
|
1187
|
+
// for real: DebugHooks.FastContinueNotHookSkippableStillFiresEvery-
|
|
1188
|
+
// Checkpoint (a translate()-wrapped script) caught the miscount when
|
|
1189
|
+
// this was first omitted by analogy to Op::CallModule.
|
|
1190
|
+
void emitBuiltinWrap(CompiledChunk::BuiltinWrapSite::Kind kind, const std::string& tagName,
|
|
1191
|
+
const oscad::ASTNode& wrapperNode, const std::vector<const oscad::ASTNode*>& children,
|
|
1192
|
+
std::vector<Instruction>& out) {
|
|
1193
|
+
out.push_back({Op::CheckDebugStatement, internNativeStatement(&wrapperNode), 0, nullptr});
|
|
1194
|
+
CompiledChunk::BuiltinWrapSite site;
|
|
1195
|
+
site.kind = kind;
|
|
1196
|
+
site.tagName = tagName;
|
|
1197
|
+
site.node = &wrapperNode;
|
|
1198
|
+
chunk_.builtinWrapSites.push_back(std::move(site));
|
|
1199
|
+
const int idx = static_cast<int>(chunk_.builtinWrapSites.size()) - 1;
|
|
1200
|
+
out.push_back({Op::PushBuiltinWrap, idx, 0, &wrapperNode.position()});
|
|
1201
|
+
compileStatementList(children, out);
|
|
1202
|
+
out.push_back({Op::PopBuiltinWrap, idx, 0, &wrapperNode.position()});
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1166
1205
|
void compileOneStatement(const oscad::ASTNode& stmt, std::vector<Instruction>& out) {
|
|
1167
1206
|
using oscad::NodeKind;
|
|
1168
1207
|
trackSpan(stmt);
|
|
@@ -1350,14 +1389,61 @@ public:
|
|
|
1350
1389
|
{Op::CallModule, static_cast<int>(chunk_.moduleCallSites.size()) - 1, 0, &call.position()});
|
|
1351
1390
|
return;
|
|
1352
1391
|
}
|
|
1353
|
-
//
|
|
1354
|
-
//
|
|
1355
|
-
//
|
|
1356
|
-
//
|
|
1357
|
-
//
|
|
1392
|
+
// A user module never shadows a builtin transform/color
|
|
1393
|
+
// name in a way that reaches here -- the `resolved` check
|
|
1394
|
+
// above already ruled that out (isBuiltin per
|
|
1395
|
+
// evalModularCall's own comment). So a name found in
|
|
1396
|
+
// resolveDispatch() here is unambiguously the real C++
|
|
1397
|
+
// builtin. Detected by FUNCTION-POINTER identity against
|
|
1398
|
+
// &resolveTransform/&resolveColor, not a second,
|
|
1399
|
+
// independently-maintained name list -- stays in sync
|
|
1400
|
+
// with registry.cpp automatically if a 7th transform name
|
|
1401
|
+
// is ever added there. See Op::PushBuiltinWrap's own doc
|
|
1402
|
+
// comment (bytecode.hpp) for why this specific subset
|
|
1403
|
+
// gets real bytecode instead of falling to
|
|
1404
|
+
// Op::NativeStatement below like every other builtin
|
|
1405
|
+
// still does.
|
|
1406
|
+
const auto& dispatch = resolveDispatch();
|
|
1407
|
+
auto dispatchIt = dispatch.find(call.name->name);
|
|
1408
|
+
std::optional<CompiledChunk::BuiltinWrapSite::Kind> wrapKind;
|
|
1409
|
+
if (dispatchIt != dispatch.end()) {
|
|
1410
|
+
if (dispatchIt->second == &resolveTransform) {
|
|
1411
|
+
wrapKind = CompiledChunk::BuiltinWrapSite::Kind::Transform;
|
|
1412
|
+
} else if (dispatchIt->second == &resolveColor) {
|
|
1413
|
+
wrapKind = CompiledChunk::BuiltinWrapSite::Kind::Color;
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
if (wrapKind) {
|
|
1417
|
+
std::vector<const oscad::ASTNode*> children;
|
|
1418
|
+
children.reserve(call.children.size());
|
|
1419
|
+
for (const auto& c : call.children) children.push_back(c.get());
|
|
1420
|
+
emitBuiltinWrap(*wrapKind, call.name->name, call, children, out);
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
// Every other builtin, children(), or a name that didn't
|
|
1424
|
+
// resolve to a user module statically -- native
|
|
1425
|
+
// passthrough, exactly like echo/assert/etc. below. Never
|
|
1426
|
+
// the recursion-depth risk this compiler targets for
|
|
1427
|
+
// THESE (see NativeStatement's own doc comment,
|
|
1428
|
+
// bytecode.hpp).
|
|
1358
1429
|
out.push_back({Op::NativeStatement, internNativeStatement(&stmt), 0, &stmt.position()});
|
|
1359
1430
|
return;
|
|
1360
1431
|
}
|
|
1432
|
+
case NodeKind::ModularModifierHighlight: {
|
|
1433
|
+
auto& n = static_cast<const oscad::ModularModifierHighlight&>(stmt);
|
|
1434
|
+
emitBuiltinWrap(CompiledChunk::BuiltinWrapSite::Kind::Modifier, "highlight", n, {n.child.get()}, out);
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
case NodeKind::ModularModifierBackground: {
|
|
1438
|
+
auto& n = static_cast<const oscad::ModularModifierBackground&>(stmt);
|
|
1439
|
+
emitBuiltinWrap(CompiledChunk::BuiltinWrapSite::Kind::Modifier, "background", n, {n.child.get()}, out);
|
|
1440
|
+
return;
|
|
1441
|
+
}
|
|
1442
|
+
case NodeKind::ModularModifierShowOnly: {
|
|
1443
|
+
auto& n = static_cast<const oscad::ModularModifierShowOnly&>(stmt);
|
|
1444
|
+
emitBuiltinWrap(CompiledChunk::BuiltinWrapSite::Kind::Modifier, "show_only", n, {n.child.get()}, out);
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1361
1447
|
case NodeKind::ModularIf: {
|
|
1362
1448
|
auto& n = static_cast<const oscad::ModularIf&>(stmt);
|
|
1363
1449
|
const int jumpFalseIdx = static_cast<int>(out.size());
|
|
@@ -1389,10 +1475,17 @@ public:
|
|
|
1389
1475
|
return;
|
|
1390
1476
|
}
|
|
1391
1477
|
default:
|
|
1392
|
-
//
|
|
1393
|
-
//
|
|
1394
|
-
//
|
|
1395
|
-
//
|
|
1478
|
+
// ModularModifierDisable (`*`) -- deliberately native: its
|
|
1479
|
+
// child never evaluates at all (see evalStatement's own
|
|
1480
|
+
// ModularModifierDisable case, stmt_eval.cpp), so there's
|
|
1481
|
+
// no recursion to eliminate here in the first place.
|
|
1482
|
+
// intersection_for -- deliberately native (bespoke
|
|
1483
|
+
// per-statement grouping, same reasoning as union/
|
|
1484
|
+
// difference/intersection; not covered by
|
|
1485
|
+
// Op::PushBuiltinWrap, see that op's own doc comment).
|
|
1486
|
+
// `#`/`%`/`!` and translate/rotate/scale/mirror/multmatrix/
|
|
1487
|
+
// resize/color have their own real bytecode cases now,
|
|
1488
|
+
// above; echo/assert/assignment/let-block already did.
|
|
1396
1489
|
out.push_back({Op::NativeStatement, internNativeStatement(&stmt), 0, &stmt.position()});
|
|
1397
1490
|
return;
|
|
1398
1491
|
}
|