From 4b31629dccc0be99d48b5b80e1b8222c809c34c4 Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Wed, 16 Sep 2026 19:53:06 +0300 Subject: [PATCH 01/12] aot: a no_jit dependency stops folding a zero into the semantic hash linkCppAot skipped the hash pass for a requestNoJit function under LLVM-AOT, but getFunctionAotHash folds every non-noAot dependency into a caller's hash whether or not the rail can bind it. The skipped function kept hash 0, so every caller folded a zero where the object emitter folded the real value and missed its own entry - the diagnostic prints it as `test_r2v C1>?=0x0`. Hash the whole non-noAot set; the requestNoJit skip belongs to the binding loop, which still has it. C++ AOT is unaffected by construction: isLlvmAot is false there, so the old condition already read `!noAot`. Only the LLVM-AOT path changes, and only a program that reaches a no_jit function through a bound caller. --- src/ast/ast_simulate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/ast_simulate.cpp b/src/ast/ast_simulate.cpp index 18de99ecd2..3cb13f827b 100644 --- a/src/ast/ast_simulate.cpp +++ b/src/ast/ast_simulate.cpp @@ -4192,7 +4192,7 @@ namespace das }); } for ( int fni=0, fnis=context.totalFunctions; fni!=fnis; ++fni ) { - if ( !fnn[fni]->noAot && !(isLlvmAot && fnn[fni]->requestNoJit) ) { + if ( !fnn[fni]->noAot ) { SimFunction & fn = context.functions[fni]; fnn[fni]->hash = getFunctionHash(fnn[fni], fn.code, &context); } From a6827dccba567e8ce6051afd1ccaadb1261ad698 Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Wed, 16 Sep 2026 19:53:06 +0300 Subject: [PATCH 02/12] tune: an AOT-consuming run is stamp-free whether or not the JIT is on A [tune] stamp rewrites the function before codegen, so it changes the semantic hash. tune_aot_gate froze only an AOT run without the JIT, which left the -jit --use-aot rail stamping at run time against objects built under other assumptions. The gate is policies.aot now: a run that consumes AOT artifacts is frozen, whichever backend binds them. A plain -jit run sets no aot policy and still stamps, and -exe still stamps through tune_exe_gate. The object emitter freezes for the reason every other AOT generator does - the artifact is cross-box. utils/internal/jit/main.das is the driver the cmake rules invoke, and it was the one sibling that never set tune_frozen, so it baked its own sidecar path into the emitted objects. --- modules/dasLLVM/daslib/llvm_tune.das | 69 +++++++++++----------------- utils/internal/jit/main.das | 1 + 2 files changed, 28 insertions(+), 42 deletions(-) diff --git a/modules/dasLLVM/daslib/llvm_tune.das b/modules/dasLLVM/daslib/llvm_tune.das index a1f13d258e..894164385d 100644 --- a/modules/dasLLVM/daslib/llvm_tune.das +++ b/modules/dasLLVM/daslib/llvm_tune.das @@ -73,12 +73,9 @@ def jit_cli_opt_level() : int { return cli.opt_level |> unwrap_or(compiling_program().policies.jit_opt_level) } - //! True when this compile must stay stamp-free - `policies.tune_frozen`, an AOT-consuming run - //! without the JIT (a stamp changes the semantic hash), or a `--jit-target` cross target (the - //! artifact runs on a box this sidecar never measured): every tune annotation goes inert. def tune_aot_gate() : bool { return (compiling_program().policies.tune_frozen - || (compiling_program().policies.aot && !compiling_program().policies.jit_enabled) + || compiling_program().policies.aot || !empty(get_target_triple())) } @@ -223,18 +220,16 @@ def tune_box_identity() : string { let plat = get_platform_name() if (plat == "windows") { var build = "" - unsafe { - popen("ver") $(f) { - if (f != null) { - while (!feof(f)) { - let ln = strip(fgets(f)) - if (!empty(ln)) { - build = ln - } + unsafe(popen("ver") $(f) { + if (f != null) { + while (!feof(f)) { + let ln = strip(fgets(f)) + if (!empty(ln)) { + build = ln } } } - } + }) let lb = find(build, "[") let rb = find(build, "]") // keep only the trailing [0-9.] version run, so a localized "Version" word (and its @@ -246,27 +241,23 @@ def tune_box_identity() : string { cpu = env_value_of("PROCESSOR_IDENTIFIER") } elif (plat == "osx" || plat == "darwin") { // get_platform_name says "darwin" on macOS var lines : array - unsafe { - popen("sysctl -n hw.model kern.osversion machdep.cpu.brand_string 2>/dev/null") $(f) { - while (!feof(f)) { - let ln = strip(fgets(f)) - if (!empty(ln)) { - lines |> push(ln) - } + unsafe(popen("sysctl -n hw.model kern.osversion machdep.cpu.brand_string 2>/dev/null") $(f) { + while (!feof(f)) { + let ln = strip(fgets(f)) + if (!empty(ln)) { + lines |> push(ln) } } - } + }) // positional: a missing sysctl key blank-fills its field rather than collapsing the count model_id = !empty(lines) ? lines[0] : "" os_build = length(lines) > 1 ? lines[1] : "" cpu = length(lines) > 2 ? lines[2] : "" delete lines } else { - unsafe { - popen("uname -r 2>/dev/null") $(f) { - os_build = strip(fgets(f)) - } - } + unsafe(popen("uname -r 2>/dev/null") $(f) { + os_build = strip(fgets(f)) + }) cpu = linux_cpu_brand() } if (empty(cpu)) { @@ -2641,16 +2632,13 @@ def private run_scope_tuner(scope : TuneScope; onlyFilter : string = "") : bool if (!empty(onlyFilter)) { set_env_variable("DAS_TUNE_ONLY", onlyFilter) } - var rc : int - unsafe { - rc = popen(cmd) $(f) { - if (f != null) { - while (!feof(f)) { - relay_line(fgets(f)) - } + let rc = unsafe(popen(cmd) $(f) { + if (f != null) { + while (!feof(f)) { + relay_line(fgets(f)) } } - } + }) if (!empty(onlyFilter)) { set_env_variable("DAS_TUNE_ONLY", "") } @@ -2829,16 +2817,13 @@ def tune_auto_reexec() : bool { } print("llvm_tune: re-launching to apply the fresh manifests\n") set_env_variable("DAS_TUNE_RELAUNCH", "{g_env_tune.tune_relaunch + 1}") - var rc : int - unsafe { - rc = popen_argv(args, 0.0) $(f) { - if (f != null) { - while (!feof(f)) { - print(fgets(f)) - } + let rc = unsafe(popen_argv(args, 0.0) $(f) { + if (f != null) { + while (!feof(f)) { + print(fgets(f)) } } - } + }) delete args g_reexec_code = rc return true diff --git a/utils/internal/jit/main.das b/utils/internal/jit/main.das index fd94ee03da..4db6fae6c2 100644 --- a/utils/internal/jit/main.das +++ b/utils/internal/jit/main.das @@ -282,6 +282,7 @@ def private jit_setup_cop(var cop : CodeOfPolicies; input : string; tool : JitTo } elif (tool.aot_object) { cop.jit_emit_object = true cop.jit_dll_mode = false + cop.tune_frozen = true } elif (tool.exe) { cop.jit_exe_mode = true cop.jit_dll_mode = false From 486c31f27f2a1bdfc0523af8d5ca1bd5e36f3b0a Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Wed, 16 Sep 2026 19:53:22 +0300 Subject: [PATCH 03/12] jit: the emitter disposes the target triple LLVM hands it LLVMGetDefaultTargetTriple returns a string the caller owns. emit_object_only leaked one per emitted object, and the debug-flag path leaked one per module, which LeakSanitizer reports as a batch's worth of strdup at once on the asan lane. llvm_jit_common.das is in the pinned emitter set, so the pin moves with it. The disposal frees a string LLVMSetTarget has already copied, so emitted code is unchanged and LLVM_JIT_CODEGEN_VERSION holds. --- modules/dasLLVM/daslib/llvm_jit_common.das | 4 +++- modules/dasLLVM/daslib/llvm_jit_run.das | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/dasLLVM/daslib/llvm_jit_common.das b/modules/dasLLVM/daslib/llvm_jit_common.das index b368177467..8605c05d50 100644 --- a/modules/dasLLVM/daslib/llvm_jit_common.das +++ b/modules/dasLLVM/daslib/llvm_jit_common.das @@ -1026,7 +1026,9 @@ def public emit_object_only(mod : LLVMOpaqueModule?; out_path : string; use_host // assumes, which need not be what this target machine emits. let dl = LLVMCreateTargetDataLayout(targetMachine) LLVMSetModuleDataLayout(mod, dl) - LLVMSetTarget(mod, LLVMGetDefaultTargetTriple()) + let mod_triple = LLVMGetDefaultTargetTriple() + LLVMSetTarget(mod, mod_triple) + LLVMDisposeMessage(mod_triple) LLVMDisposeTargetData(dl) let error : string? let file = artifact_path(out_path, JitArtifact.object) diff --git a/modules/dasLLVM/daslib/llvm_jit_run.das b/modules/dasLLVM/daslib/llvm_jit_run.das index 3a97c423d1..39a8af9014 100644 --- a/modules/dasLLVM/daslib/llvm_jit_run.das +++ b/modules/dasLLVM/daslib/llvm_jit_run.das @@ -37,7 +37,7 @@ var LINK_WHOLE_LIB = false // when true, standalone exe links against the whole // Read by tests-cpp/small/test_jit_emitter_pin.cpp: FNV-1a64 of the emitter sources // (normalized to LF; file list in the test) -let LLVM_JIT_EMITTER_HASH : uint64 = 0x39cbe46110eda829ul +let LLVM_JIT_EMITTER_HASH : uint64 = 0xbf8412b8bfc82374ul def private apply_fast_math_to_module(m : LLVMOpaqueModule?) { var fn = LLVMGetFirstFunction(m) From 910de88276fcc2adb63b4f85ba456f4dbfd8f9eb Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Wed, 16 Sep 2026 19:53:22 +0300 Subject: [PATCH 04/12] ci: a generated corpus travels in a file, not on the command line Two rules handed a whole corpus to a tool as one argument. The standalone sweep passed ~900 absolute paths as -DFILES=, which at 70KB overruns cmd.exe's 8191-character line limit whatever wrapper script the generator writes, so the windows lane died on a truncated path. run_tests_llvm_aot spelled the corpus a second time as --exclude patterns, which cannot track TEST_AOT_ALL_DAS because that is partly curated lists (AOT_DASLIB_FILES) - a file the corpus lacks has no object, and reaching it under --use-aot is a hard error. Both now write the list at configure time and name the file. dastest gains --test-list, which restricts the collected set rather than replacing it, so --test still walks tests/ and tests/.das_test still gates the folders this rail must not enter. --- dastest/dastest.das | 29 ++++++++++++++------- dastest/dastest_clargs.das | 4 +++ tests/CMakeLists.txt | 5 +--- tests/aot/CMakeLists.txt | 7 +++++ tests/standalone-sweep/CMakeLists.txt | 8 +++--- tests/standalone-sweep/sweep_contexts.cmake | 1 + tests/standalone-sweep/sweep_jit.cmake | 5 ++-- 7 files changed, 41 insertions(+), 18 deletions(-) diff --git a/dastest/dastest.das b/dastest/dastest.das index 8e3616b5b4..3c05f0a7a0 100644 --- a/dastest/dastest.das +++ b/dastest/dastest.das @@ -425,13 +425,9 @@ def deserialize_path(var ctx : SuiteCtx, _files : array, in_file : strin return } var count = 0 - unsafe { - _builtin_read(f, addr(count), typeinfo sizeof(count)) - } + _builtin_read(f, unsafe(addr(count)), typeinfo sizeof(count)) var sz = 0l - unsafe { - _builtin_read(f, addr(sz), typeinfo sizeof(sz)) - } + _builtin_read(f, unsafe(addr(sz)), typeinfo sizeof(sz)) var data : array data |> reserve(sz) // the blob size is known: exact reserve, and the resize never grows data |> resize(sz) @@ -550,9 +546,7 @@ def main() : int { // nolint:STYLE037,STYLE038 - CLI dispatch, one arm per mode log::error("dastest: the suite ran past its --timeout of {timeout}s; the process ends here with exit code {TIMEOUT_EXIT_CODE} and no summary") // not fio::exit - it runs the job queue teardown, which busy-waits on this very thread; // and nothing here invokes into the main context, which the main thread is still running - unsafe { - fio::exit_now(TIMEOUT_EXIT_CODE) - } + unsafe(fio::exit_now(TIMEOUT_EXIT_CODE)) } } } @@ -561,6 +555,23 @@ def main() : int { // nolint:STYLE037,STYLE038 - CLI dispatch, one arm per mode var inputPaths := test_args.test_files var files : array return 1 if (!collect_files(inputPaths, files)) + if (!empty(test_args.test_list)) { + var keep : table + fopen(test_args.test_list, "rb") $(fr) { + return if (fr == null) + fmap(fr) $(data) { + for (line in string(data) |> split("\n")) { + let one = line |> strip() |> replace("\\", "/") + keep |> insert(one) if (!empty(one)) + } + } + } + if (keep |> empty()) { + log::error("dastest: --test-list {test_args.test_list} is empty or unreadable") + return 1 + } + files |> erase_if() $(f) => !(keep |> key_exists(f |> replace("\\", "/"))) + } if (!empty(test_args.exclude_files)) { files |> erase_if() $(f) { let base = base_name(f) diff --git a/dastest/dastest_clargs.das b/dastest/dastest_clargs.das index 6ab705a3d5..d45c37d5c7 100644 --- a/dastest/dastest_clargs.das +++ b/dastest/dastest_clargs.das @@ -65,6 +65,10 @@ struct DastestArgs { @clarg_doc = "Skip test files whose base name contains this substring (repeatable)" exclude_files : array + @clarg_name = "test-list" + @clarg_doc = "Path to a file listing one test path per line; restricts the collected set to those paths" + test_list : string + @clarg_doc = "Run top-level tests matching this name prefix" test_names : array diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e88644249d..e818d20001 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -135,11 +135,8 @@ endif() # LLVM-AOT (LLVM-backend .o) mirror of run_tests_aot: test bodies bound from the # statically-linked self-registering objects and run jitted. Opt-in, not in CI. if(TARGET test_llvm_aot) - # -jit (fun->hash matches the --aot-object emit) AND --use-aot (linkCppAot binds - # the .o as SimNode_Jit; run_jit no-ops). --exclude must match the corpus filter in - # tests/aot/CMakeLists.txt: files with no emitted object would miss (a hard error now). add_custom_target(run_tests_llvm_aot - COMMAND $ ${PROJECT_SOURCE_DIR}/dastest/dastest.das -jit -- --use-aot --color --failures-only --isolated-mode --batch 4 --timeout 1800 --exclude jit_fastpath --exclude typeinfo --exclude global_variables_solid --exclude llvm_code --exclude llvm_compile_only --exclude llvm_compile_only_client --exclude test_msl_ --exclude test_metal_ --test ${PROJECT_SOURCE_DIR}/tests/ + COMMAND $ ${PROJECT_SOURCE_DIR}/dastest/dastest.das -jit -- --use-aot --color --failures-only --isolated-mode --batch 4 --timeout 1800 --test-list ${LLVM_AOT_TEST_LIST} --test ${PROJECT_SOURCE_DIR}/tests/ DEPENDS test_llvm_aot WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMENT "Running tests (LLVM-AOT)" diff --git a/tests/aot/CMakeLists.txt b/tests/aot/CMakeLists.txt index a5c8876366..d0dfb3a704 100644 --- a/tests/aot/CMakeLists.txt +++ b/tests/aot/CMakeLists.txt @@ -585,6 +585,13 @@ if(NOT ${DAS_LLVM_DISABLED}) # llvm_jit.das) — they interpret, so they have no emitted object; keep them out of the AOT rail. list(FILTER LLVM_AOT_TEST_FILES EXCLUDE REGEX "tests/(msl|metal)/") + set(LLVM_AOT_TEST_LIST ${PROJECT_BINARY_DIR}/llvm_aot_corpus.txt) + set(_llvm_aot_list_text "") + foreach(_f IN LISTS LLVM_AOT_TEST_FILES) + string(APPEND _llvm_aot_list_text "${PROJECT_SOURCE_DIR}/${_f}\n") + endforeach() + file(WRITE ${LLVM_AOT_TEST_LIST} "${_llvm_aot_list_text}") + add_custom_target(test_llvm_aot_corpus) SET(LLVM_AOT_GENERATED_OBJ) DAS_LLVM_AOT_LIB("${LLVM_AOT_TEST_FILES}" LLVM_AOT_GENERATED_OBJ test_llvm_aot_corpus) diff --git a/tests/standalone-sweep/CMakeLists.txt b/tests/standalone-sweep/CMakeLists.txt index 90c11e6b5a..04bd491f66 100644 --- a/tests/standalone-sweep/CMakeLists.txt +++ b/tests/standalone-sweep/CMakeLists.txt @@ -45,6 +45,8 @@ endforeach() list(LENGTH _sweep_files _sweep_count) message(STATUS "standalone sweep: ${_sweep_count} files, ${_skipped} with no standalone form or a claimed stem") list(JOIN _sweep_files "|" _sweep_files_arg) +set(_sweep_files_list "${CMAKE_CURRENT_BINARY_DIR}/sweep_files.txt") +file(WRITE "${_sweep_files_list}" "${_sweep_files_arg}") ### C++ tier add_custom_target(standalone_sweep_aot_corpus) @@ -55,9 +57,9 @@ DAS_AOT_CTX("${_sweep_files}" SWEEP_CTX_GENERATED_SRC standalone_sweep_aot_corpu set(_contexts "${CMAKE_CURRENT_BINARY_DIR}/sweep_contexts.h") add_custom_command( OUTPUT ${_contexts} - COMMAND ${CMAKE_COMMAND} -DOUT=${_contexts} "-DFILES=${_sweep_files_arg}" + COMMAND ${CMAKE_COMMAND} -DOUT=${_contexts} -DFILES_LIST=${_sweep_files_list} -P ${CMAKE_CURRENT_SOURCE_DIR}/sweep_contexts.cmake - DEPENDS standalone_sweep_aot_corpus ${CMAKE_CURRENT_SOURCE_DIR}/sweep_contexts.cmake + DEPENDS standalone_sweep_aot_corpus ${CMAKE_CURRENT_SOURCE_DIR}/sweep_contexts.cmake ${_sweep_files_list} COMMENT "Standalone sweep (C++): collecting the contexts that emitted" VERBATIM ) @@ -85,7 +87,7 @@ add_custom_target(run_standalone_sweep_aot if(NOT DAS_LLVM_DISABLED) add_custom_target(standalone_sweep_jit COMMAND ${CMAKE_COMMAND} -DDASLANG=$ -DROOT=${PROJECT_SOURCE_DIR} - -DOUT=${CMAKE_CURRENT_BINARY_DIR}/_lib "-DFILES=${_sweep_files_arg}" + -DOUT=${CMAKE_CURRENT_BINARY_DIR}/_lib -DFILES_LIST=${_sweep_files_list} -P ${CMAKE_CURRENT_SOURCE_DIR}/sweep_jit.cmake DEPENDS daslang WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} diff --git a/tests/standalone-sweep/sweep_contexts.cmake b/tests/standalone-sweep/sweep_contexts.cmake index 78a7b6b16e..8222b0156d 100644 --- a/tests/standalone-sweep/sweep_contexts.cmake +++ b/tests/standalone-sweep/sweep_contexts.cmake @@ -2,6 +2,7 @@ # rest as an X-macro. Contexts linking C++ modules run first and one is held open for the sweep - # they bind the thread environment in a base class, and the global AOT library pass needs it. +file(READ "${FILES_LIST}" FILES) string(REPLACE "|" ";" _files "${FILES}") set(_includes "") set(_list "") diff --git a/tests/standalone-sweep/sweep_jit.cmake b/tests/standalone-sweep/sweep_jit.cmake index 17e949c70f..0a14726158 100644 --- a/tests/standalone-sweep/sweep_jit.cmake +++ b/tests/standalone-sweep/sweep_jit.cmake @@ -1,16 +1,17 @@ # The JIT half of the standalone sweep, run by the standalone_sweep_jit target: -# cmake -DDASLANG= -DROOT= -DOUT= "-DFILES=a.das|b.das" -P sweep_jit.cmake +# cmake -DDASLANG= -DROOT= -DOUT= -DFILES_LIST= -P sweep_jit.cmake # Emission goes through utils/internal/jit/main.das, which takes many files per process - the # ~52-file dasLLVM load costs ~4.5s and is paid once per chunk, not once per library. Each library # is then loaded back by a generated host. A library that never emitted is tallied as refused; one # that emitted and cannot run sets the exit code. -foreach(_var DASLANG ROOT OUT FILES) +foreach(_var DASLANG ROOT OUT FILES_LIST) if(NOT DEFINED ${_var}) message(FATAL_ERROR "sweep_jit.cmake: -D${_var} is required") endif() endforeach() file(MAKE_DIRECTORY ${OUT}) +file(READ "${FILES_LIST}" FILES) string(REPLACE "|" ";" _files "${FILES}") list(LENGTH _files _total) From 31971b4eb7bb265ed9a5a5123f112a4c7a631bda Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Wed, 16 Sep 2026 19:53:40 +0300 Subject: [PATCH 05/12] ci: a PR that closes a nightly-failure issue runs the nightly Per-PR CI never walks the lanes the nightly owns - the sanitizer cells, windows Debug, mingw, clang-cl, the full AOT suite, the backend sweeps - so a change that can break one has no way to prove itself before it lands. pre_job resolves the PR's closing issues, its labels and a `#nightly` marker in its body into one flag that drives the matrix shape, the nightly-only jobs and the nightly-only steps. The body is read through the API and matched with jq, never interpolated into the shell: a PR body is attacker-controlled. The issue-filing job still gates on schedule alone, so an armed PR cannot file an issue at itself. make_pr's checklist says when to arm by hand. --- .github/workflows/build.yml | 49 ++++++++++++++++++++++++----- .github/workflows/nightly_issue.yml | 6 +++- skills/internal/make_pr.md | 1 + 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4a4ebcd81d..d594033a25 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,6 +42,7 @@ jobs: outputs: should_skip: ${{ steps.skip_check.outputs.should_skip }} matrix: ${{ steps.matrix.outputs.matrix }} + nightly: ${{ steps.nightly.outputs.nightly }} steps: - id: skip_check uses: fkirc/skip-duplicate-actions@v5 @@ -50,6 +51,38 @@ jobs: concurrent_skipping: 'same_content' do_not_skip: '["pull_request", "workflow_dispatch", "release"]' + - id: nightly + env: + GH_TOKEN: ${{ github.token }} + run: | + set -eu + nightly=false + case "${{ github.event_name }}" in + schedule|workflow_dispatch) nightly=true ;; + pull_request) + if gh api graphql -f owner='${{ github.repository_owner }}' -f name='${{ github.event.repository.name }}' \ + -F number=${{ github.event.pull_request.number }} -f query=' + query($owner:String!,$name:String!,$number:Int!){ + repository(owner:$owner,name:$name){ + pullRequest(number:$number){ + body + labels(first:100){nodes{name}} + closingIssuesReferences(first:20){nodes{labels(first:100){nodes{name}}}} + }}}' \ + --jq '.data.repository.pullRequest + | [ (.labels.nodes[].name), + (.closingIssuesReferences.nodes[].labels.nodes[].name) ] as $tags + | if ($tags | index("nightly-failure")) + or ($tags | index("run-nightly")) + or (((.body // "") | test("#nightly"; "i"))) + then "armed" else empty end' | grep -q . + then + nightly=true + fi + ;; + esac + echo "nightly=$nightly" >> "$GITHUB_OUTPUT" + # The build matrix is data in ci/ci_matrix.py, evaluated per event here (ci/test_ci_matrix.py pins it). - uses: actions/checkout@v4 with: @@ -58,7 +91,9 @@ jobs: # two statements: a substitution inside echo would hide the script's exit code run: | set -eu - matrix=$(python3 ci/ci_matrix.py build '${{ github.event_name }}') + event='${{ github.event_name }}' + if [ '${{ steps.nightly.outputs.nightly }}' = 'true' ]; then event=schedule; fi + matrix=$(python3 ci/ci_matrix.py build "$event") echo "matrix=$matrix" >> "$GITHUB_OUTPUT" - name: Cache LLVM @@ -394,7 +429,7 @@ jobs: # per-PR ctest is -L small, so only this step executes a generated # context. memory_model_4gb allocates a real 4 GB chunk and stays # local-only. - if: matrix.cmake_preset == 'Release' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') + if: matrix.cmake_preset == 'Release' && needs.pre_job.outputs.nightly == 'true' run: | set -eux case "${{ matrix.target }}${{ matrix.architecture }}" in @@ -419,7 +454,7 @@ jobs: # LLVM-AOT objects, and both standalone tiers - -ctx emits C++ a host # compiles, -lib emits a native library dasbind loads back. Same nightly # gate as the step above; 32-bit Windows has no AOT rail to sweep. - if: matrix.cmake_preset == 'Release' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') + if: matrix.cmake_preset == 'Release' && needs.pre_job.outputs.nightly == 'true' run: | set -eux case "${{ matrix.target }}${{ matrix.architecture }}" in @@ -444,7 +479,7 @@ jobs: needs: pre_job if: >- (github.event_name == 'schedule' && github.repository == 'GaijinEntertainment/daScript') - || github.event_name == 'workflow_dispatch' + || (github.event_name != 'schedule' && needs.pre_job.outputs.nightly == 'true') runs-on: windows-latest permissions: contents: read @@ -548,7 +583,7 @@ jobs: needs: pre_job if: >- (github.event_name == 'schedule' && github.repository == 'GaijinEntertainment/daScript') - || github.event_name == 'workflow_dispatch' + || (github.event_name != 'schedule' && needs.pre_job.outputs.nightly == 'true') runs-on: windows-latest permissions: contents: read @@ -754,7 +789,7 @@ jobs: # scheduled cron runs the toolchains only on the canonical repo, so forks # don't run (and fail) the nightly — that would email every fork owner. # Manual workflow_dispatch still runs them anywhere. - if: (github.event_name == 'schedule' && github.repository == 'GaijinEntertainment/daScript') || github.event_name == 'workflow_dispatch' + if: (github.event_name == 'schedule' && github.repository == 'GaijinEntertainment/daScript') || (github.event_name != 'schedule' && needs.pre_job.outputs.nightly == 'true') runs-on: windows-latest defaults: run: @@ -911,7 +946,7 @@ jobs: # scheduled cron runs the toolchains only on the canonical repo, so forks # don't run (and fail) the nightly — that would email every fork owner. # Manual workflow_dispatch still runs them anywhere. - if: (github.event_name == 'schedule' && github.repository == 'GaijinEntertainment/daScript') || github.event_name == 'workflow_dispatch' + if: (github.event_name == 'schedule' && github.repository == 'GaijinEntertainment/daScript') || (github.event_name != 'schedule' && needs.pre_job.outputs.nightly == 'true') runs-on: windows-latest steps: - name: "SCM Checkout" diff --git a/.github/workflows/nightly_issue.yml b/.github/workflows/nightly_issue.yml index e284fff8dd..7b4dee3b58 100644 --- a/.github/workflows/nightly_issue.yml +++ b/.github/workflows/nightly_issue.yml @@ -49,7 +49,11 @@ jobs: printf -- '* run: %s\n' "$RUN_URL" printf -- '* commit: `%s`\n\n' "$GITHUB_SHA" printf 'One issue for the whole nightly: while this one is open nothing else ' - printf 'is filed, whichever lane fails. Close it once the nightly is green again.\n' + printf 'is filed, whichever lane fails. Close it once the nightly is green again.\n\n' + printf 'A PR that closes this issue runs the nightly shape of CI on itself, so the fix ' + printf 'is proved by the lane that failed. Say `Closes #` in the PR body ' + printf 'before opening it, put `#nightly` anywhere in the body, or add the ' + printf '`run-nightly` label and push again.\n' } > "$BODY" gh issue create --title "$TITLE" --label nightly-failure --body-file "$BODY" diff --git a/skills/internal/make_pr.md b/skills/internal/make_pr.md index a656c3572a..f14b6d15fa 100644 --- a/skills/internal/make_pr.md +++ b/skills/internal/make_pr.md @@ -49,6 +49,7 @@ kills the chain's JIT loads, AOT links, and spawned tools mid-suite). | 5 Format | MCP `format_file` on all changed `.das` in ONE batched call | Only files in the PR, every era - it handles gen1 and `.das_project`, and CI fails on unformatted gen1; no folder arms comment stripping any more - comments are harvested (row 0a0), never formatter-deleted. Verify the files still compile. New comments written after 0a0 re-run that row before continuing. CI's `utils/das-fmt/dasfmt.das -- --path ./ --verify` wraps the same engine and the same policy | | 5 `.md` stop | `git diff --name-only origin/master..HEAD \| grep '\.md$'` | Any match: STOP, list the changes, ask the user to review BEFORE push | | 6 PR | GitHub MCP `create_pull_request` or `gh pr create` | Body follows the two-layer template below. On a squashed branch every later fix is `git commit --amend --no-edit` + force-push, never a new commit | +| 6 Nightly arm | `#nightly` in the PR body (or the `run-nightly` label) | Per-PR CI never walks the nightly lanes - the sanitizer cells, windows Debug, mingw, clang-cl, the full AOT suite and the backend sweeps. Arm them when the diff can break a lane per-PR CI does not run: anything under `src/` or `include/`, the pinned dasLLVM emitter set, AST node layout, the type system or generic binding, semantic-hash or AOT surface, a generator whose output is committed, or simply a diff too broad to reason about lane by lane. A one-line fix, a `.das`-only edit, docs or tests alone do not need it. A PR closing a `nightly-failure` issue arms itself. `#nightly` is alphabetic, so GitHub does not autolink it the way it does a bare `#N` | | 6a Babysit | continue into `skills/internal/babysit.md`; triage every comment per `skills/internal/review_triage.md` | Creating the PR does not end the workflow; the stop rule and merge gate are babysit sec.0's | | 7 Post-land sweep | `git ls-files --others --exclude-standard` | Babysit rounds mint debris after the `untracked` gate - sweep it per Workspace Hygiene in `CLAUDE.md` (probe scripts, dumps, `__pycache__`, ad-hoc logs, typically `_`-prefixed) | From 5deb26d8e9691d694b7c29aac13699a2538ebf80 Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Wed, 16 Sep 2026 19:53:41 +0300 Subject: [PATCH 06/12] dasVulkan: the boost emitter wraps the operation, not the block Four emitters wrapped a whole statement in `unsafe { }` where one or two operations inside it needed the permission. The wrap now goes on each addr/reinterpret the emitter writes, and the block is gone: the finalize destroyer, the opt_struct_ptr field view, the batch allocate call and the out-array enumerate call. The generated files are DO NOT EDIT, so narrowing them by hand would have survived only until the next regeneration - and nightly_vulkan.yml diffs the two ratchet reports, never the generated .das, so nothing would have caught the loss. Regenerating is deterministic and leaves skip_report.txt and copyability_report.txt byte-identical. --- modules/dasVulkan/daslib/vulkan_cmds.das | 212 ++----- modules/dasVulkan/daslib/vulkan_commands.das | 36 +- modules/dasVulkan/daslib/vulkan_handles.das | 196 ++---- modules/dasVulkan/daslib/vulkan_structs.das | 600 ++++++++---------- modules/dasVulkan/generator/vk_emit_boost.das | 35 +- 5 files changed, 376 insertions(+), 703 deletions(-) diff --git a/modules/dasVulkan/daslib/vulkan_cmds.das b/modules/dasVulkan/daslib/vulkan_cmds.das index 604349cad5..b6c75af357 100644 --- a/modules/dasVulkan/daslib/vulkan_cmds.das +++ b/modules/dasVulkan/daslib/vulkan_cmds.das @@ -18,9 +18,7 @@ def enumerate_physical_devices(instance : Instance; var result : VkResult? = nul var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkEnumeratePhysicalDevices(boost_value_to_vk(instance), vkcount, addr(vklist[0])), result) - } + vk_check(vkEnumeratePhysicalDevices(boost_value_to_vk(instance), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -37,9 +35,7 @@ def get_physical_device_queue_family_properties(physicalDevice : PhysicalDevice) var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vkGetPhysicalDeviceQueueFamilyProperties(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])) - } + vkGetPhysicalDeviceQueueFamilyProperties(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))) } return <- vklist } @@ -80,9 +76,7 @@ def enumerate_instance_layer_properties(var result : VkResult? = null) : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkEnumerateInstanceLayerProperties(vkcount, addr(vklist[0])), result) - } + vk_check(vkEnumerateInstanceLayerProperties(vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -93,9 +87,7 @@ def enumerate_instance_extension_properties(pLayerName : string; var result : Vk var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkEnumerateInstanceExtensionProperties(pLayerName, vkcount, addr(vklist[0])), result) - } + vk_check(vkEnumerateInstanceExtensionProperties(pLayerName, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -106,9 +98,7 @@ def enumerate_device_layer_properties(physicalDevice : PhysicalDevice; var resul var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkEnumerateDeviceLayerProperties(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])), result) - } + vk_check(vkEnumerateDeviceLayerProperties(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -119,9 +109,7 @@ def enumerate_device_extension_properties(physicalDevice : PhysicalDevice; pLaye var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkEnumerateDeviceExtensionProperties(boost_value_to_vk(physicalDevice), pLayerName, vkcount, addr(vklist[0])), result) - } + vk_check(vkEnumerateDeviceExtensionProperties(boost_value_to_vk(physicalDevice), pLayerName, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -203,9 +191,7 @@ def get_image_sparse_memory_requirements(device : Device; image : Image) : array var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vkGetImageSparseMemoryRequirements(boost_value_to_vk(device), boost_value_to_vk(image), vkcount, addr(vklist[0])) - } + vkGetImageSparseMemoryRequirements(boost_value_to_vk(device), boost_value_to_vk(image), vkcount, unsafe(addr(vklist[0]))) } return <- vklist } @@ -216,9 +202,7 @@ def get_physical_device_sparse_image_format_properties(physicalDevice : Physical var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vkGetPhysicalDeviceSparseImageFormatProperties(boost_value_to_vk(physicalDevice), format, type_, samples, usage, tiling, vkcount, addr(vklist[0])) - } + vkGetPhysicalDeviceSparseImageFormatProperties(boost_value_to_vk(physicalDevice), format, type_, samples, usage, tiling, vkcount, unsafe(addr(vklist[0]))) } return <- vklist } @@ -280,9 +264,7 @@ def get_pipeline_cache_data(device : Device; pipelineCache : PipelineCache; var var vklist : array vklist |> resize(int64(vkcount)) if (vkcount > 0ul) { - unsafe { - vk_check(vkGetPipelineCacheData(boost_value_to_vk(device), boost_value_to_vk(pipelineCache), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPipelineCacheData(boost_value_to_vk(device), boost_value_to_vk(pipelineCache), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -702,9 +684,7 @@ def get_physical_device_display_properties_k_h_r(physicalDevice : PhysicalDevice var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceDisplayPropertiesKHR(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceDisplayPropertiesKHR(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -715,9 +695,7 @@ def get_physical_device_display_plane_properties_k_h_r(physicalDevice : Physical var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceDisplayPlanePropertiesKHR(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceDisplayPlanePropertiesKHR(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -728,9 +706,7 @@ def get_display_plane_supported_displays_k_h_r(physicalDevice : PhysicalDevice; var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkGetDisplayPlaneSupportedDisplaysKHR(boost_value_to_vk(physicalDevice), planeIndex, vkcount, addr(vklist[0])), result) - } + vk_check(vkGetDisplayPlaneSupportedDisplaysKHR(boost_value_to_vk(physicalDevice), planeIndex, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -741,9 +717,7 @@ def get_display_mode_properties_k_h_r(physicalDevice : PhysicalDevice; display : var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkGetDisplayModePropertiesKHR(boost_value_to_vk(physicalDevice), boost_value_to_vk(display), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetDisplayModePropertiesKHR(boost_value_to_vk(physicalDevice), boost_value_to_vk(display), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -772,9 +746,7 @@ def get_physical_device_surface_formats_k_h_r(physicalDevice : PhysicalDevice; s var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceSurfaceFormatsKHR(boost_value_to_vk(physicalDevice), boost_value_to_vk(surface), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceSurfaceFormatsKHR(boost_value_to_vk(physicalDevice), boost_value_to_vk(surface), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -785,9 +757,7 @@ def get_physical_device_surface_present_modes_k_h_r(physicalDevice : PhysicalDev var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceSurfacePresentModesKHR(boost_value_to_vk(physicalDevice), boost_value_to_vk(surface), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceSurfacePresentModesKHR(boost_value_to_vk(physicalDevice), boost_value_to_vk(surface), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -798,9 +768,7 @@ def get_swapchain_images_k_h_r(device : Device; swapchain : SwapchainKHR; var re var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkGetSwapchainImagesKHR(boost_value_to_vk(device), boost_value_to_vk(swapchain), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetSwapchainImagesKHR(boost_value_to_vk(device), boost_value_to_vk(swapchain), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -956,9 +924,7 @@ def get_physical_device_queue_family_properties2(physicalDevice : PhysicalDevice vklist[vki] = VkQueueFamilyProperties2() } if (vkcount > 0u) { - unsafe { - vkGetPhysicalDeviceQueueFamilyProperties2(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])) - } + vkGetPhysicalDeviceQueueFamilyProperties2(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))) } return <- vklist } @@ -980,9 +946,7 @@ def get_physical_device_sparse_image_format_properties2(physicalDevice : Physica vklist[vki] = VkSparseImageFormatProperties2() } if (vkcount > 0u) { - unsafe { - vkGetPhysicalDeviceSparseImageFormatProperties2(boost_value_to_vk(physicalDevice), vkview_pFormatInfo, vkcount, addr(vklist[0])) - } + vkGetPhysicalDeviceSparseImageFormatProperties2(boost_value_to_vk(physicalDevice), vkview_pFormatInfo, vkcount, unsafe(addr(vklist[0]))) } return <- vklist } @@ -1099,9 +1063,7 @@ def enumerate_physical_device_groups(instance : Instance; var result : VkResult? vklist[vki] = VkPhysicalDeviceGroupProperties() } if (vkcount > 0u) { - unsafe { - vk_check(vkEnumeratePhysicalDeviceGroups(boost_value_to_vk(instance), vkcount, addr(vklist[0])), result) - } + vk_check(vkEnumeratePhysicalDeviceGroups(boost_value_to_vk(instance), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -1156,9 +1118,7 @@ def get_physical_device_present_rectangles_k_h_r(physicalDevice : PhysicalDevice var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDevicePresentRectanglesKHR(boost_value_to_vk(physicalDevice), boost_value_to_vk(surface), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDevicePresentRectanglesKHR(boost_value_to_vk(physicalDevice), boost_value_to_vk(surface), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -1192,9 +1152,7 @@ def get_past_presentation_timing_g_o_o_g_l_e(device : Device; swapchain : Swapch var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkGetPastPresentationTimingGOOGLE(boost_value_to_vk(device), boost_value_to_vk(swapchain), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPastPresentationTimingGOOGLE(boost_value_to_vk(device), boost_value_to_vk(swapchain), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -1260,9 +1218,7 @@ def get_physical_device_surface_formats2_k_h_r(physicalDevice : PhysicalDevice; vklist[vki] = VkSurfaceFormat2KHR() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceSurfaceFormats2KHR(boost_value_to_vk(physicalDevice), vkview_pSurfaceInfo, vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceSurfaceFormats2KHR(boost_value_to_vk(physicalDevice), vkview_pSurfaceInfo, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -1276,9 +1232,7 @@ def get_physical_device_display_properties2_k_h_r(physicalDevice : PhysicalDevic vklist[vki] = VkDisplayProperties2KHR() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceDisplayProperties2KHR(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceDisplayProperties2KHR(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -1292,9 +1246,7 @@ def get_physical_device_display_plane_properties2_k_h_r(physicalDevice : Physica vklist[vki] = VkDisplayPlaneProperties2KHR() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceDisplayPlaneProperties2KHR(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceDisplayPlaneProperties2KHR(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -1308,9 +1260,7 @@ def get_display_mode_properties2_k_h_r(physicalDevice : PhysicalDevice; display vklist[vki] = VkDisplayModeProperties2KHR() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetDisplayModeProperties2KHR(boost_value_to_vk(physicalDevice), boost_value_to_vk(display), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetDisplayModeProperties2KHR(boost_value_to_vk(physicalDevice), boost_value_to_vk(display), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -1350,9 +1300,7 @@ def get_image_sparse_memory_requirements2(device : Device; pInfo : ImageSparseMe vklist[vki] = VkSparseImageMemoryRequirements2() } if (vkcount > 0u) { - unsafe { - vkGetImageSparseMemoryRequirements2(boost_value_to_vk(device), vkview_pInfo, vkcount, addr(vklist[0])) - } + vkGetImageSparseMemoryRequirements2(boost_value_to_vk(device), vkview_pInfo, vkcount, unsafe(addr(vklist[0]))) } return <- vklist } @@ -1384,9 +1332,7 @@ def get_device_image_sparse_memory_requirements(device : Device; var pInfo : Dev vklist[vki] = VkSparseImageMemoryRequirements2() } if (vkcount > 0u) { - unsafe { - vkGetDeviceImageSparseMemoryRequirements(boost_value_to_vk(device), vkview_pInfo, vkcount, addr(vklist[0])) - } + vkGetDeviceImageSparseMemoryRequirements(boost_value_to_vk(device), vkview_pInfo, vkcount, unsafe(addr(vklist[0]))) } return <- vklist } @@ -1405,9 +1351,7 @@ def get_validation_cache_data_e_x_t(device : Device; validationCache : Validatio var vklist : array vklist |> resize(int64(vkcount)) if (vkcount > 0ul) { - unsafe { - vk_check(vkGetValidationCacheDataEXT(boost_value_to_vk(device), boost_value_to_vk(validationCache), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetValidationCacheDataEXT(boost_value_to_vk(device), boost_value_to_vk(validationCache), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -1432,9 +1376,7 @@ def get_shader_info_a_m_d(device : Device; pipeline : Pipeline; shaderStage : Vk var vklist : array vklist |> resize(int64(vkcount)) if (vkcount > 0ul) { - unsafe { - vk_check(vkGetShaderInfoAMD(boost_value_to_vk(device), boost_value_to_vk(pipeline), shaderStage, infoType, vkcount, addr(vklist[0])), result) - } + vk_check(vkGetShaderInfoAMD(boost_value_to_vk(device), boost_value_to_vk(pipeline), shaderStage, infoType, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -1449,9 +1391,7 @@ def get_physical_device_calibrateable_time_domains_k_h_r(physicalDevice : Physic var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceCalibrateableTimeDomainsKHR(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceCalibrateableTimeDomainsKHR(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -1559,9 +1499,7 @@ def get_queue_checkpoint_data_n_v(queue : Queue) : array { vklist[vki] = VkCheckpointDataNV() } if (vkcount > 0u) { - unsafe { - vkGetQueueCheckpointDataNV(boost_value_to_vk(queue), vkcount, addr(vklist[0])) - } + vkGetQueueCheckpointDataNV(boost_value_to_vk(queue), vkcount, unsafe(addr(vklist[0]))) } return <- vklist } @@ -1867,9 +1805,7 @@ def get_physical_device_supported_framebuffer_mixed_samples_combinations_n_v(phy vklist[vki] = VkFramebufferMixedSamplesCombinationNV() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -1936,9 +1872,7 @@ def get_pipeline_executable_properties_k_h_r(device : Device; pPipelineInfo : Pi vklist[vki] = VkPipelineExecutablePropertiesKHR() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPipelineExecutablePropertiesKHR(boost_value_to_vk(device), vkview_pPipelineInfo, vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPipelineExecutablePropertiesKHR(boost_value_to_vk(device), vkview_pPipelineInfo, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -1954,9 +1888,7 @@ def get_pipeline_executable_statistics_k_h_r(device : Device; pExecutableInfo : vklist[vki] = VkPipelineExecutableStatisticKHR() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPipelineExecutableStatisticsKHR(boost_value_to_vk(device), vkview_pExecutableInfo, vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPipelineExecutableStatisticsKHR(boost_value_to_vk(device), vkview_pExecutableInfo, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -1972,9 +1904,7 @@ def get_pipeline_executable_internal_representations_k_h_r(device : Device; pExe vklist[vki] = VkPipelineExecutableInternalRepresentationKHR() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPipelineExecutableInternalRepresentationsKHR(boost_value_to_vk(device), vkview_pExecutableInfo, vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPipelineExecutableInternalRepresentationsKHR(boost_value_to_vk(device), vkview_pExecutableInfo, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -1992,9 +1922,7 @@ def get_physical_device_tool_properties(physicalDevice : PhysicalDevice; var res vklist[vki] = VkPhysicalDeviceToolProperties() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceToolProperties(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceToolProperties(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -2350,9 +2278,7 @@ def get_physical_device_fragment_shading_rates_k_h_r(physicalDevice : PhysicalDe vklist[vki] = VkPhysicalDeviceFragmentShadingRateKHR() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceFragmentShadingRatesKHR(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceFragmentShadingRatesKHR(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -2444,9 +2370,7 @@ def get_queue_checkpoint_data2_n_v(queue : Queue) : array { vklist[vki] = VkCheckpointData2NV() } if (vkcount > 0u) { - unsafe { - vkGetQueueCheckpointData2NV(boost_value_to_vk(queue), vkcount, addr(vklist[0])) - } + vkGetQueueCheckpointData2NV(boost_value_to_vk(queue), vkcount, unsafe(addr(vklist[0]))) } return <- vklist } @@ -2487,9 +2411,7 @@ def get_physical_device_video_format_properties_k_h_r(physicalDevice : PhysicalD vklist[vki] = VkVideoFormatPropertiesKHR() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceVideoFormatPropertiesKHR(boost_value_to_vk(physicalDevice), vkview_pVideoFormatInfo, vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceVideoFormatPropertiesKHR(boost_value_to_vk(physicalDevice), vkview_pVideoFormatInfo, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -2517,9 +2439,7 @@ def get_video_session_memory_requirements_k_h_r(device : Device; videoSession : vklist[vki] = VkVideoSessionMemoryRequirementsKHR() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetVideoSessionMemoryRequirementsKHR(boost_value_to_vk(device), boost_value_to_vk(videoSession), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetVideoSessionMemoryRequirementsKHR(boost_value_to_vk(device), boost_value_to_vk(videoSession), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -2780,9 +2700,7 @@ def get_framebuffer_tile_properties_q_c_o_m(device : Device; framebuffer : Frame vklist[vki] = VkTilePropertiesQCOM() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetFramebufferTilePropertiesQCOM(boost_value_to_vk(device), boost_value_to_vk(framebuffer), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetFramebufferTilePropertiesQCOM(boost_value_to_vk(device), boost_value_to_vk(framebuffer), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -2806,9 +2724,7 @@ def get_physical_device_optical_flow_image_formats_n_v(physicalDevice : Physical vklist[vki] = VkOpticalFlowImageFormatPropertiesNV() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceOpticalFlowImageFormatsNV(boost_value_to_vk(physicalDevice), vkview_pOpticalFlowImageFormatInfo, vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceOpticalFlowImageFormatsNV(boost_value_to_vk(physicalDevice), vkview_pOpticalFlowImageFormatInfo, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -2832,9 +2748,7 @@ def get_device_fault_reports_k_h_r(device : Device; timeout : uint64; var result vklist[vki] = VkDeviceFaultInfoKHR() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetDeviceFaultReportsKHR(boost_value_to_vk(device), timeout, vkcount, addr(vklist[0])), result) - } + vk_check(vkGetDeviceFaultReportsKHR(boost_value_to_vk(device), timeout, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -2877,9 +2791,7 @@ def get_shader_binary_data_e_x_t(device : Device; shader : ShaderEXT; var result var vklist : array vklist |> resize(int64(vkcount)) if (vkcount > 0ul) { - unsafe { - vk_check(vkGetShaderBinaryDataEXT(boost_value_to_vk(device), boost_value_to_vk(shader), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetShaderBinaryDataEXT(boost_value_to_vk(device), boost_value_to_vk(shader), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -2905,9 +2817,7 @@ def get_physical_device_cooperative_matrix_properties_k_h_r(physicalDevice : Phy vklist[vki] = VkCooperativeMatrixPropertiesKHR() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -2954,9 +2864,7 @@ def get_gpa_session_results_a_m_d(device : Device; gpaSession : GpaSessionAMD; s var vklist : array vklist |> resize(int64(vkcount)) if (vkcount > 0ul) { - unsafe { - vk_check(vkGetGpaSessionResultsAMD(boost_value_to_vk(device), boost_value_to_vk(gpaSession), sampleID, vkcount, addr(vklist[0])), result) - } + vk_check(vkGetGpaSessionResultsAMD(boost_value_to_vk(device), boost_value_to_vk(gpaSession), sampleID, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -3076,9 +2984,7 @@ def get_physical_device_cooperative_matrix_flexible_dimensions_properties_n_v(ph vklist[vki] = VkCooperativeMatrixFlexibleDimensionsPropertiesNV() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -3092,9 +2998,7 @@ def get_physical_device_cooperative_vector_properties_n_v(physicalDevice : Physi vklist[vki] = VkCooperativeVectorPropertiesNV() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceCooperativeVectorPropertiesNV(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceCooperativeVectorPropertiesNV(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -3126,9 +3030,7 @@ def enumerate_physical_device_shader_instrumentation_metrics_a_r_m(physicalDevic vklist[vki] = VkShaderInstrumentationMetricDescriptionARM() } if (vkcount > 0u) { - unsafe { - vk_check(vkEnumeratePhysicalDeviceShaderInstrumentationMetricsARM(boost_value_to_vk(physicalDevice), vkcount, addr(vklist[0])), result) - } + vk_check(vkEnumeratePhysicalDeviceShaderInstrumentationMetricsARM(boost_value_to_vk(physicalDevice), vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -3197,9 +3099,7 @@ def get_data_graph_pipeline_session_bind_point_requirements_a_r_m(device : Devic vklist[vki] = VkDataGraphPipelineSessionBindPointRequirementARM() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetDataGraphPipelineSessionBindPointRequirementsARM(boost_value_to_vk(device), vkview_pInfo, vkcount, addr(vklist[0])), result) - } + vk_check(vkGetDataGraphPipelineSessionBindPointRequirementsARM(boost_value_to_vk(device), vkview_pInfo, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -3231,9 +3131,7 @@ def get_data_graph_pipeline_available_properties_a_r_m(device : Device; pPipelin var vklist : array vklist |> resize(int(vkcount)) if (vkcount > 0u) { - unsafe { - vk_check(vkGetDataGraphPipelineAvailablePropertiesARM(boost_value_to_vk(device), vkview_pPipelineInfo, vkcount, addr(vklist[0])), result) - } + vk_check(vkGetDataGraphPipelineAvailablePropertiesARM(boost_value_to_vk(device), vkview_pPipelineInfo, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -3247,9 +3145,7 @@ def get_physical_device_queue_family_data_graph_properties_a_r_m(physicalDevice vklist[vki] = VkQueueFamilyDataGraphPropertiesARM() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(boost_value_to_vk(physicalDevice), queueFamilyIndex, vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(boost_value_to_vk(physicalDevice), queueFamilyIndex, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } @@ -3446,9 +3342,7 @@ def get_physical_device_queue_family_data_graph_optical_flow_image_formats_a_r_m vklist[vki] = VkDataGraphOpticalFlowImageFormatPropertiesARM() } if (vkcount > 0u) { - unsafe { - vk_check(vkGetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM(boost_value_to_vk(physicalDevice), queueFamilyIndex, vkview_pQueueFamilyDataGraphProperties, vkview_pOpticalFlowImageFormatInfo, vkcount, addr(vklist[0])), result) - } + vk_check(vkGetPhysicalDeviceQueueFamilyDataGraphOpticalFlowImageFormatsARM(boost_value_to_vk(physicalDevice), queueFamilyIndex, vkview_pQueueFamilyDataGraphProperties, vkview_pOpticalFlowImageFormatInfo, vkcount, unsafe(addr(vklist[0]))), result) } return <- vklist } diff --git a/modules/dasVulkan/daslib/vulkan_commands.das b/modules/dasVulkan/daslib/vulkan_commands.das index b2be6ef0d2..2370392fc0 100644 --- a/modules/dasVulkan/daslib/vulkan_commands.das +++ b/modules/dasVulkan/daslib/vulkan_commands.das @@ -132,9 +132,7 @@ def create_graphics_pipelines(device : Device; pipelineCache : PipelineCache; va var vkout : array vkout |> resize(n) if (n > 0) { - unsafe { - vk_check(vkCreateGraphicsPipelines(boost_value_to_vk(device), boost_value_to_vk(pipelineCache), uint(n), addr(vkraw[0]), null, addr(vkout[0])), result) - } + vk_check(vkCreateGraphicsPipelines(boost_value_to_vk(device), boost_value_to_vk(pipelineCache), uint(n), unsafe(addr(vkraw[0])), null, unsafe(addr(vkout[0]))), result) } for (vkv in create_infos) { vk_view_destroy(vkv) } delete vkraw @@ -159,9 +157,7 @@ def create_compute_pipelines(device : Device; pipelineCache : PipelineCache; cre var vkout : array vkout |> resize(n) if (n > 0) { - unsafe { - vk_check(vkCreateComputePipelines(boost_value_to_vk(device), boost_value_to_vk(pipelineCache), uint(n), addr(vkraw[0]), null, addr(vkout[0])), result) - } + vk_check(vkCreateComputePipelines(boost_value_to_vk(device), boost_value_to_vk(pipelineCache), uint(n), unsafe(addr(vkraw[0])), null, unsafe(addr(vkout[0]))), result) } for (vkv in create_infos) { vk_view_destroy(vkv) } delete vkraw @@ -227,9 +223,7 @@ def allocate_descriptor_sets(device : Device; var create_info : DescriptorSetAll var vkout : array vkout |> resize(n) if (n > 0) { - unsafe { - vk_check(vkAllocateDescriptorSets(boost_value_to_vk(device), vci, addr(vkout[0])), result) - } + vk_check(vkAllocateDescriptorSets(boost_value_to_vk(device), vci, unsafe(addr(vkout[0]))), result) } var blist : array blist |> resize(n) @@ -282,9 +276,7 @@ def allocate_command_buffers(device : Device; create_info : CommandBufferAllocat var vkout : array vkout |> resize(n) if (n > 0) { - unsafe { - vk_check(vkAllocateCommandBuffers(boost_value_to_vk(device), vci, addr(vkout[0])), result) - } + vk_check(vkAllocateCommandBuffers(boost_value_to_vk(device), vci, unsafe(addr(vkout[0]))), result) } var blist : array blist |> resize(n) @@ -328,9 +320,7 @@ def create_shared_swapchains_k_h_r(device : Device; var create_infos : array vkout |> resize(n) if (n > 0) { - unsafe { - vk_check(vkCreateSharedSwapchainsKHR(boost_value_to_vk(device), uint(n), addr(vkraw[0]), null, addr(vkout[0])), result) - } + vk_check(vkCreateSharedSwapchainsKHR(boost_value_to_vk(device), uint(n), unsafe(addr(vkraw[0])), null, unsafe(addr(vkout[0]))), result) } for (vkv in create_infos) { vk_view_destroy(vkv) } delete vkraw @@ -443,9 +433,7 @@ def create_ray_tracing_pipelines_n_v(device : Device; pipelineCache : PipelineCa var vkout : array vkout |> resize(n) if (n > 0) { - unsafe { - vk_check(vkCreateRayTracingPipelinesNV(boost_value_to_vk(device), boost_value_to_vk(pipelineCache), uint(n), addr(vkraw[0]), null, addr(vkout[0])), result) - } + vk_check(vkCreateRayTracingPipelinesNV(boost_value_to_vk(device), boost_value_to_vk(pipelineCache), uint(n), unsafe(addr(vkraw[0])), null, unsafe(addr(vkout[0]))), result) } for (vkv in create_infos) { vk_view_destroy(vkv) } delete vkraw @@ -470,9 +458,7 @@ def create_ray_tracing_pipelines_k_h_r(device : Device; deferredOperation : Defe var vkout : array vkout |> resize(n) if (n > 0) { - unsafe { - vk_check(vkCreateRayTracingPipelinesKHR(boost_value_to_vk(device), boost_value_to_vk(deferredOperation), boost_value_to_vk(pipelineCache), uint(n), addr(vkraw[0]), null, addr(vkout[0])), result) - } + vk_check(vkCreateRayTracingPipelinesKHR(boost_value_to_vk(device), boost_value_to_vk(deferredOperation), boost_value_to_vk(pipelineCache), uint(n), unsafe(addr(vkraw[0])), null, unsafe(addr(vkout[0]))), result) } for (vkv in create_infos) { vk_view_destroy(vkv) } delete vkraw @@ -596,9 +582,7 @@ def create_shaders_e_x_t(device : Device; var create_infos : array vkout |> resize(n) if (n > 0) { - unsafe { - vk_check(vkCreateShadersEXT(boost_value_to_vk(device), uint(n), addr(vkraw[0]), null, addr(vkout[0])), result) - } + vk_check(vkCreateShadersEXT(boost_value_to_vk(device), uint(n), unsafe(addr(vkraw[0])), null, unsafe(addr(vkout[0]))), result) } for (vkv in create_infos) { vk_view_destroy(vkv) } delete vkraw @@ -678,9 +662,7 @@ def create_data_graph_pipelines_a_r_m(device : Device; deferredOperation : Defer var vkout : array vkout |> resize(n) if (n > 0) { - unsafe { - vk_check(vkCreateDataGraphPipelinesARM(boost_value_to_vk(device), boost_value_to_vk(deferredOperation), boost_value_to_vk(pipelineCache), uint(n), addr(vkraw[0]), null, addr(vkout[0])), result) - } + vk_check(vkCreateDataGraphPipelinesARM(boost_value_to_vk(device), boost_value_to_vk(deferredOperation), boost_value_to_vk(pipelineCache), uint(n), unsafe(addr(vkraw[0])), null, unsafe(addr(vkout[0]))), result) } for (vkv in create_infos) { vk_view_destroy(vkv) } delete vkraw diff --git a/modules/dasVulkan/daslib/vulkan_handles.das b/modules/dasVulkan/daslib/vulkan_handles.das index 38422e2e6e..7ffee3277d 100644 --- a/modules/dasVulkan/daslib/vulkan_handles.das +++ b/modules/dasVulkan/daslib/vulkan_handles.das @@ -15,9 +15,7 @@ struct Instance { } def finalize(var self : Instance) { if (self._needs_delete) { - unsafe { - vkDestroyInstance(reinterpret(self._vk), null) - } + vkDestroyInstance(unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -40,9 +38,7 @@ struct Device { } def finalize(var self : Device) { if (self._needs_delete) { - unsafe { - vkDestroyDevice(reinterpret(self._vk), null) - } + vkDestroyDevice(unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -78,9 +74,7 @@ struct DeviceMemory { } def finalize(var self : DeviceMemory) { if (self._needs_delete) { - unsafe { - vkFreeMemory(reinterpret(self._device), reinterpret(self._vk), null) - } + vkFreeMemory(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -94,9 +88,7 @@ struct CommandPool { } def finalize(var self : CommandPool) { if (self._needs_delete) { - unsafe { - vkDestroyCommandPool(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyCommandPool(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -110,9 +102,7 @@ struct Buffer { } def finalize(var self : Buffer) { if (self._needs_delete) { - unsafe { - vkDestroyBuffer(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyBuffer(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -126,9 +116,7 @@ struct BufferView { } def finalize(var self : BufferView) { if (self._needs_delete) { - unsafe { - vkDestroyBufferView(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyBufferView(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -142,9 +130,7 @@ struct Image { } def finalize(var self : Image) { if (self._needs_delete) { - unsafe { - vkDestroyImage(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyImage(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -158,9 +144,7 @@ struct ImageView { } def finalize(var self : ImageView) { if (self._needs_delete) { - unsafe { - vkDestroyImageView(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyImageView(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -174,9 +158,7 @@ struct ShaderModule { } def finalize(var self : ShaderModule) { if (self._needs_delete) { - unsafe { - vkDestroyShaderModule(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyShaderModule(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -190,9 +172,7 @@ struct Pipeline { } def finalize(var self : Pipeline) { if (self._needs_delete) { - unsafe { - vkDestroyPipeline(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyPipeline(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -206,9 +186,7 @@ struct PipelineLayout { } def finalize(var self : PipelineLayout) { if (self._needs_delete) { - unsafe { - vkDestroyPipelineLayout(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyPipelineLayout(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -222,9 +200,7 @@ struct Sampler { } def finalize(var self : Sampler) { if (self._needs_delete) { - unsafe { - vkDestroySampler(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroySampler(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -250,9 +226,7 @@ struct DescriptorSetLayout { } def finalize(var self : DescriptorSetLayout) { if (self._needs_delete) { - unsafe { - vkDestroyDescriptorSetLayout(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyDescriptorSetLayout(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -266,9 +240,7 @@ struct DescriptorPool { } def finalize(var self : DescriptorPool) { if (self._needs_delete) { - unsafe { - vkDestroyDescriptorPool(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyDescriptorPool(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -282,9 +254,7 @@ struct Fence { } def finalize(var self : Fence) { if (self._needs_delete) { - unsafe { - vkDestroyFence(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyFence(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -298,9 +268,7 @@ struct Semaphore { } def finalize(var self : Semaphore) { if (self._needs_delete) { - unsafe { - vkDestroySemaphore(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroySemaphore(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -314,9 +282,7 @@ struct Event { } def finalize(var self : Event) { if (self._needs_delete) { - unsafe { - vkDestroyEvent(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyEvent(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -330,9 +296,7 @@ struct QueryPool { } def finalize(var self : QueryPool) { if (self._needs_delete) { - unsafe { - vkDestroyQueryPool(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyQueryPool(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -346,9 +310,7 @@ struct Framebuffer { } def finalize(var self : Framebuffer) { if (self._needs_delete) { - unsafe { - vkDestroyFramebuffer(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyFramebuffer(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -362,9 +324,7 @@ struct RenderPass { } def finalize(var self : RenderPass) { if (self._needs_delete) { - unsafe { - vkDestroyRenderPass(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyRenderPass(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -378,9 +338,7 @@ struct PipelineCache { } def finalize(var self : PipelineCache) { if (self._needs_delete) { - unsafe { - vkDestroyPipelineCache(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyPipelineCache(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -394,9 +352,7 @@ struct PipelineBinaryKHR { } def finalize(var self : PipelineBinaryKHR) { if (self._needs_delete) { - unsafe { - vkDestroyPipelineBinaryKHR(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyPipelineBinaryKHR(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -410,9 +366,7 @@ struct IndirectCommandsLayoutNV { } def finalize(var self : IndirectCommandsLayoutNV) { if (self._needs_delete) { - unsafe { - vkDestroyIndirectCommandsLayoutNV(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyIndirectCommandsLayoutNV(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -426,9 +380,7 @@ struct IndirectCommandsLayoutEXT { } def finalize(var self : IndirectCommandsLayoutEXT) { if (self._needs_delete) { - unsafe { - vkDestroyIndirectCommandsLayoutEXT(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyIndirectCommandsLayoutEXT(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -442,9 +394,7 @@ struct IndirectExecutionSetEXT { } def finalize(var self : IndirectExecutionSetEXT) { if (self._needs_delete) { - unsafe { - vkDestroyIndirectExecutionSetEXT(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyIndirectExecutionSetEXT(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -458,9 +408,7 @@ struct DescriptorUpdateTemplate { } def finalize(var self : DescriptorUpdateTemplate) { if (self._needs_delete) { - unsafe { - vkDestroyDescriptorUpdateTemplate(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyDescriptorUpdateTemplate(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -474,9 +422,7 @@ struct SamplerYcbcrConversion { } def finalize(var self : SamplerYcbcrConversion) { if (self._needs_delete) { - unsafe { - vkDestroySamplerYcbcrConversion(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroySamplerYcbcrConversion(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -490,9 +436,7 @@ struct ValidationCacheEXT { } def finalize(var self : ValidationCacheEXT) { if (self._needs_delete) { - unsafe { - vkDestroyValidationCacheEXT(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyValidationCacheEXT(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -506,9 +450,7 @@ struct AccelerationStructureKHR { } def finalize(var self : AccelerationStructureKHR) { if (self._needs_delete) { - unsafe { - vkDestroyAccelerationStructureKHR(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyAccelerationStructureKHR(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -522,9 +464,7 @@ struct AccelerationStructureNV { } def finalize(var self : AccelerationStructureNV) { if (self._needs_delete) { - unsafe { - vkDestroyAccelerationStructureNV(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyAccelerationStructureNV(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -548,9 +488,7 @@ struct DeferredOperationKHR { } def finalize(var self : DeferredOperationKHR) { if (self._needs_delete) { - unsafe { - vkDestroyDeferredOperationKHR(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyDeferredOperationKHR(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -564,9 +502,7 @@ struct PrivateDataSlot { } def finalize(var self : PrivateDataSlot) { if (self._needs_delete) { - unsafe { - vkDestroyPrivateDataSlot(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyPrivateDataSlot(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -580,9 +516,7 @@ struct CuModuleNVX { } def finalize(var self : CuModuleNVX) { if (self._needs_delete) { - unsafe { - vkDestroyCuModuleNVX(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyCuModuleNVX(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -596,9 +530,7 @@ struct CuFunctionNVX { } def finalize(var self : CuFunctionNVX) { if (self._needs_delete) { - unsafe { - vkDestroyCuFunctionNVX(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyCuFunctionNVX(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -612,9 +544,7 @@ struct OpticalFlowSessionNV { } def finalize(var self : OpticalFlowSessionNV) { if (self._needs_delete) { - unsafe { - vkDestroyOpticalFlowSessionNV(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyOpticalFlowSessionNV(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -628,9 +558,7 @@ struct MicromapEXT { } def finalize(var self : MicromapEXT) { if (self._needs_delete) { - unsafe { - vkDestroyMicromapEXT(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyMicromapEXT(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -644,9 +572,7 @@ struct ShaderEXT { } def finalize(var self : ShaderEXT) { if (self._needs_delete) { - unsafe { - vkDestroyShaderEXT(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyShaderEXT(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -660,9 +586,7 @@ struct TensorARM { } def finalize(var self : TensorARM) { if (self._needs_delete) { - unsafe { - vkDestroyTensorARM(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyTensorARM(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -676,9 +600,7 @@ struct TensorViewARM { } def finalize(var self : TensorViewARM) { if (self._needs_delete) { - unsafe { - vkDestroyTensorViewARM(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyTensorViewARM(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -692,9 +614,7 @@ struct DataGraphPipelineSessionARM { } def finalize(var self : DataGraphPipelineSessionARM) { if (self._needs_delete) { - unsafe { - vkDestroyDataGraphPipelineSessionARM(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyDataGraphPipelineSessionARM(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -708,9 +628,7 @@ struct ShaderInstrumentationARM { } def finalize(var self : ShaderInstrumentationARM) { if (self._needs_delete) { - unsafe { - vkDestroyShaderInstrumentationARM(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyShaderInstrumentationARM(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -724,9 +642,7 @@ struct GpaSessionAMD { } def finalize(var self : GpaSessionAMD) { if (self._needs_delete) { - unsafe { - vkDestroyGpaSessionAMD(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyGpaSessionAMD(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -760,9 +676,7 @@ struct SurfaceKHR { } def finalize(var self : SurfaceKHR) { if (self._needs_delete) { - unsafe { - vkDestroySurfaceKHR(reinterpret(self._instance), reinterpret(self._vk), null) - } + vkDestroySurfaceKHR(unsafe(reinterpret(self._instance)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -776,9 +690,7 @@ struct SwapchainKHR { } def finalize(var self : SwapchainKHR) { if (self._needs_delete) { - unsafe { - vkDestroySwapchainKHR(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroySwapchainKHR(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -792,9 +704,7 @@ struct DebugReportCallbackEXT { } def finalize(var self : DebugReportCallbackEXT) { if (self._needs_delete) { - unsafe { - vkDestroyDebugReportCallbackEXT(reinterpret(self._instance), reinterpret(self._vk), null) - } + vkDestroyDebugReportCallbackEXT(unsafe(reinterpret(self._instance)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -808,9 +718,7 @@ struct DebugUtilsMessengerEXT { } def finalize(var self : DebugUtilsMessengerEXT) { if (self._needs_delete) { - unsafe { - vkDestroyDebugUtilsMessengerEXT(reinterpret(self._instance), reinterpret(self._vk), null) - } + vkDestroyDebugUtilsMessengerEXT(unsafe(reinterpret(self._instance)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -824,9 +732,7 @@ struct VideoSessionKHR { } def finalize(var self : VideoSessionKHR) { if (self._needs_delete) { - unsafe { - vkDestroyVideoSessionKHR(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyVideoSessionKHR(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -840,9 +746,7 @@ struct VideoSessionParametersKHR { } def finalize(var self : VideoSessionParametersKHR) { if (self._needs_delete) { - unsafe { - vkDestroyVideoSessionParametersKHR(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyVideoSessionParametersKHR(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } @@ -856,9 +760,7 @@ struct ExternalComputeQueueNV { } def finalize(var self : ExternalComputeQueueNV) { if (self._needs_delete) { - unsafe { - vkDestroyExternalComputeQueueNV(reinterpret(self._device), reinterpret(self._vk), null) - } + vkDestroyExternalComputeQueueNV(unsafe(reinterpret(self._device)), unsafe(reinterpret(self._vk)), null) } self._needs_delete = false } diff --git a/modules/dasVulkan/daslib/vulkan_structs.das b/modules/dasVulkan/daslib/vulkan_structs.das index aaac989e9d..cf83940908 100644 --- a/modules/dasVulkan/daslib/vulkan_structs.das +++ b/modules/dasVulkan/daslib/vulkan_structs.das @@ -1370,13 +1370,11 @@ def vk_view_create_unsafe(var b : PipelineShaderStageCreateInfo) : VkPipelineSha vk.stage = b.stage vk.module_ = boost_value_to_vk(b.module_) vk.pName = b.pName - unsafe { - if (b.pSpecializationInfo != null) { - b._vk_view_pSpecializationInfo_vk = vk_view_create_unsafe(*b.pSpecializationInfo) - b._vk_view_pSpecializationInfo_present = true - vk.pSpecializationInfo = addr(b._vk_view_pSpecializationInfo_vk) - b.pSpecializationInfo = null - } + if (b.pSpecializationInfo != null) { + b._vk_view_pSpecializationInfo_vk = vk_view_create_unsafe(*b.pSpecializationInfo) + b._vk_view_pSpecializationInfo_present = true + vk.pSpecializationInfo = unsafe(addr(b._vk_view_pSpecializationInfo_vk)) + b.pSpecializationInfo = null } return <- vk } @@ -1823,77 +1821,59 @@ def vk_view_create_unsafe(var b : GraphicsPipelineCreateInfo) : VkGraphicsPipeli vkv = vk_view_create_unsafe(vke) } vk.pStages = array_addr(b._vk_view_pStages) - unsafe { - if (b.pVertexInputState != null) { - b._vk_view_pVertexInputState_vk = vk_view_create_unsafe(*b.pVertexInputState) - b._vk_view_pVertexInputState_present = true - vk.pVertexInputState = addr(b._vk_view_pVertexInputState_vk) - b.pVertexInputState = null - } - } - unsafe { - if (b.pInputAssemblyState != null) { - b._vk_view_pInputAssemblyState_vk = vk_view_create_unsafe(*b.pInputAssemblyState) - b._vk_view_pInputAssemblyState_present = true - vk.pInputAssemblyState = addr(b._vk_view_pInputAssemblyState_vk) - b.pInputAssemblyState = null - } - } - unsafe { - if (b.pTessellationState != null) { - b._vk_view_pTessellationState_vk = vk_view_create_unsafe(*b.pTessellationState) - b._vk_view_pTessellationState_present = true - vk.pTessellationState = addr(b._vk_view_pTessellationState_vk) - b.pTessellationState = null - } - } - unsafe { - if (b.pViewportState != null) { - b._vk_view_pViewportState_vk = vk_view_create_unsafe(*b.pViewportState) - b._vk_view_pViewportState_present = true - vk.pViewportState = addr(b._vk_view_pViewportState_vk) - b.pViewportState = null - } - } - unsafe { - if (b.pRasterizationState != null) { - b._vk_view_pRasterizationState_vk = vk_view_create_unsafe(*b.pRasterizationState) - b._vk_view_pRasterizationState_present = true - vk.pRasterizationState = addr(b._vk_view_pRasterizationState_vk) - b.pRasterizationState = null - } - } - unsafe { - if (b.pMultisampleState != null) { - b._vk_view_pMultisampleState_vk = vk_view_create_unsafe(*b.pMultisampleState) - b._vk_view_pMultisampleState_present = true - vk.pMultisampleState = addr(b._vk_view_pMultisampleState_vk) - b.pMultisampleState = null - } - } - unsafe { - if (b.pDepthStencilState != null) { - b._vk_view_pDepthStencilState_vk = vk_view_create_unsafe(*b.pDepthStencilState) - b._vk_view_pDepthStencilState_present = true - vk.pDepthStencilState = addr(b._vk_view_pDepthStencilState_vk) - b.pDepthStencilState = null - } - } - unsafe { - if (b.pColorBlendState != null) { - b._vk_view_pColorBlendState_vk = vk_view_create_unsafe(*b.pColorBlendState) - b._vk_view_pColorBlendState_present = true - vk.pColorBlendState = addr(b._vk_view_pColorBlendState_vk) - b.pColorBlendState = null - } - } - unsafe { - if (b.pDynamicState != null) { - b._vk_view_pDynamicState_vk = vk_view_create_unsafe(*b.pDynamicState) - b._vk_view_pDynamicState_present = true - vk.pDynamicState = addr(b._vk_view_pDynamicState_vk) - b.pDynamicState = null - } + if (b.pVertexInputState != null) { + b._vk_view_pVertexInputState_vk = vk_view_create_unsafe(*b.pVertexInputState) + b._vk_view_pVertexInputState_present = true + vk.pVertexInputState = unsafe(addr(b._vk_view_pVertexInputState_vk)) + b.pVertexInputState = null + } + if (b.pInputAssemblyState != null) { + b._vk_view_pInputAssemblyState_vk = vk_view_create_unsafe(*b.pInputAssemblyState) + b._vk_view_pInputAssemblyState_present = true + vk.pInputAssemblyState = unsafe(addr(b._vk_view_pInputAssemblyState_vk)) + b.pInputAssemblyState = null + } + if (b.pTessellationState != null) { + b._vk_view_pTessellationState_vk = vk_view_create_unsafe(*b.pTessellationState) + b._vk_view_pTessellationState_present = true + vk.pTessellationState = unsafe(addr(b._vk_view_pTessellationState_vk)) + b.pTessellationState = null + } + if (b.pViewportState != null) { + b._vk_view_pViewportState_vk = vk_view_create_unsafe(*b.pViewportState) + b._vk_view_pViewportState_present = true + vk.pViewportState = unsafe(addr(b._vk_view_pViewportState_vk)) + b.pViewportState = null + } + if (b.pRasterizationState != null) { + b._vk_view_pRasterizationState_vk = vk_view_create_unsafe(*b.pRasterizationState) + b._vk_view_pRasterizationState_present = true + vk.pRasterizationState = unsafe(addr(b._vk_view_pRasterizationState_vk)) + b.pRasterizationState = null + } + if (b.pMultisampleState != null) { + b._vk_view_pMultisampleState_vk = vk_view_create_unsafe(*b.pMultisampleState) + b._vk_view_pMultisampleState_present = true + vk.pMultisampleState = unsafe(addr(b._vk_view_pMultisampleState_vk)) + b.pMultisampleState = null + } + if (b.pDepthStencilState != null) { + b._vk_view_pDepthStencilState_vk = vk_view_create_unsafe(*b.pDepthStencilState) + b._vk_view_pDepthStencilState_present = true + vk.pDepthStencilState = unsafe(addr(b._vk_view_pDepthStencilState_vk)) + b.pDepthStencilState = null + } + if (b.pColorBlendState != null) { + b._vk_view_pColorBlendState_vk = vk_view_create_unsafe(*b.pColorBlendState) + b._vk_view_pColorBlendState_present = true + vk.pColorBlendState = unsafe(addr(b._vk_view_pColorBlendState_vk)) + b.pColorBlendState = null + } + if (b.pDynamicState != null) { + b._vk_view_pDynamicState_vk = vk_view_create_unsafe(*b.pDynamicState) + b._vk_view_pDynamicState_present = true + vk.pDynamicState = unsafe(addr(b._vk_view_pDynamicState_vk)) + b.pDynamicState = null } vk.layout = boost_value_to_vk(b.layout) vk.renderPass = boost_value_to_vk(b.renderPass) @@ -2023,13 +2003,11 @@ def vk_view_create_unsafe(var b : PipelineBinaryCreateInfoKHR) : VkPipelineBinar var vk = VkPipelineBinaryCreateInfoKHR() vk.pNext = b.next vk.pipeline = boost_value_to_vk(b.pipeline) - unsafe { - if (b.pPipelineCreateInfo != null) { - b._vk_view_pPipelineCreateInfo_vk = vk_view_create_unsafe(*b.pPipelineCreateInfo) - b._vk_view_pPipelineCreateInfo_present = true - vk.pPipelineCreateInfo = addr(b._vk_view_pPipelineCreateInfo_vk) - b.pPipelineCreateInfo = null - } + if (b.pPipelineCreateInfo != null) { + b._vk_view_pPipelineCreateInfo_vk = vk_view_create_unsafe(*b.pPipelineCreateInfo) + b._vk_view_pPipelineCreateInfo_present = true + vk.pPipelineCreateInfo = unsafe(addr(b._vk_view_pPipelineCreateInfo_vk)) + b.pPipelineCreateInfo = null } return <- vk } @@ -2274,13 +2252,11 @@ def vk_view_create_unsafe(var b : CommandBufferBeginInfo) : VkCommandBufferBegin var vk = VkCommandBufferBeginInfo() vk.pNext = b.next vk.flags = b.flags - unsafe { - if (b.pInheritanceInfo != null) { - b._vk_view_pInheritanceInfo_vk = vk_view_create_unsafe(*b.pInheritanceInfo) - b._vk_view_pInheritanceInfo_present = true - vk.pInheritanceInfo = addr(b._vk_view_pInheritanceInfo_vk) - b.pInheritanceInfo = null - } + if (b.pInheritanceInfo != null) { + b._vk_view_pInheritanceInfo_vk = vk_view_create_unsafe(*b.pInheritanceInfo) + b._vk_view_pInheritanceInfo_present = true + vk.pInheritanceInfo = unsafe(addr(b._vk_view_pInheritanceInfo_vk)) + b.pInheritanceInfo = null } return <- vk } @@ -2396,13 +2372,11 @@ def vk_view_create_unsafe(var b : SubpassDescription) : VkSubpassDescription { vkv = vk_view_create_unsafe(vke) } vk.pResolveAttachments = array_addr(b._vk_view_pResolveAttachments) - unsafe { - if (b.pDepthStencilAttachment != null) { - b._vk_view_pDepthStencilAttachment_vk = vk_view_create_unsafe(*b.pDepthStencilAttachment) - b._vk_view_pDepthStencilAttachment_present = true - vk.pDepthStencilAttachment = addr(b._vk_view_pDepthStencilAttachment_vk) - b.pDepthStencilAttachment = null - } + if (b.pDepthStencilAttachment != null) { + b._vk_view_pDepthStencilAttachment_vk = vk_view_create_unsafe(*b.pDepthStencilAttachment) + b._vk_view_pDepthStencilAttachment_present = true + vk.pDepthStencilAttachment = unsafe(addr(b._vk_view_pDepthStencilAttachment_vk)) + b.pDepthStencilAttachment = null } b._vk_view_pPreserveAttachments := b.pPreserveAttachments vk.pPreserveAttachments = array_addr(b._vk_view_pPreserveAttachments) @@ -3974,21 +3948,17 @@ def vk_view_create_unsafe(var b : GraphicsShaderGroupCreateInfoNV) : VkGraphicsS vkv = vk_view_create_unsafe(vke) } vk.pStages = array_addr(b._vk_view_pStages) - unsafe { - if (b.pVertexInputState != null) { - b._vk_view_pVertexInputState_vk = vk_view_create_unsafe(*b.pVertexInputState) - b._vk_view_pVertexInputState_present = true - vk.pVertexInputState = addr(b._vk_view_pVertexInputState_vk) - b.pVertexInputState = null - } - } - unsafe { - if (b.pTessellationState != null) { - b._vk_view_pTessellationState_vk = vk_view_create_unsafe(*b.pTessellationState) - b._vk_view_pTessellationState_present = true - vk.pTessellationState = addr(b._vk_view_pTessellationState_vk) - b.pTessellationState = null - } + if (b.pVertexInputState != null) { + b._vk_view_pVertexInputState_vk = vk_view_create_unsafe(*b.pVertexInputState) + b._vk_view_pVertexInputState_present = true + vk.pVertexInputState = unsafe(addr(b._vk_view_pVertexInputState_vk)) + b.pVertexInputState = null + } + if (b.pTessellationState != null) { + b._vk_view_pTessellationState_vk = vk_view_create_unsafe(*b.pTessellationState) + b._vk_view_pTessellationState_present = true + vk.pTessellationState = unsafe(addr(b._vk_view_pTessellationState_vk)) + b.pTessellationState = null } vk.stageCount = uint(length(b.pStages)) return <- vk @@ -6326,13 +6296,11 @@ struct DeviceBufferMemoryRequirements { def vk_view_create_unsafe(var b : DeviceBufferMemoryRequirements) : VkDeviceBufferMemoryRequirements { var vk = VkDeviceBufferMemoryRequirements() vk.pNext = b.next - unsafe { - if (b.pCreateInfo != null) { - b._vk_view_pCreateInfo_vk = vk_view_create_unsafe(*b.pCreateInfo) - b._vk_view_pCreateInfo_present = true - vk.pCreateInfo = addr(b._vk_view_pCreateInfo_vk) - b.pCreateInfo = null - } + if (b.pCreateInfo != null) { + b._vk_view_pCreateInfo_vk = vk_view_create_unsafe(*b.pCreateInfo) + b._vk_view_pCreateInfo_present = true + vk.pCreateInfo = unsafe(addr(b._vk_view_pCreateInfo_vk)) + b.pCreateInfo = null } return <- vk } @@ -6380,13 +6348,11 @@ struct DeviceImageMemoryRequirements { def vk_view_create_unsafe(var b : DeviceImageMemoryRequirements) : VkDeviceImageMemoryRequirements { var vk = VkDeviceImageMemoryRequirements() vk.pNext = b.next - unsafe { - if (b.pCreateInfo != null) { - b._vk_view_pCreateInfo_vk = vk_view_create_unsafe(*b.pCreateInfo) - b._vk_view_pCreateInfo_present = true - vk.pCreateInfo = addr(b._vk_view_pCreateInfo_vk) - b.pCreateInfo = null - } + if (b.pCreateInfo != null) { + b._vk_view_pCreateInfo_vk = vk_view_create_unsafe(*b.pCreateInfo) + b._vk_view_pCreateInfo_present = true + vk.pCreateInfo = unsafe(addr(b._vk_view_pCreateInfo_vk)) + b.pCreateInfo = null } vk.planeAspect = b.planeAspect return <- vk @@ -8238,13 +8204,11 @@ def vk_view_create_unsafe(var b : SubpassDescription2) : VkSubpassDescription2 { vkv = vk_view_create_unsafe(vke) } vk.pResolveAttachments = array_addr(b._vk_view_pResolveAttachments) - unsafe { - if (b.pDepthStencilAttachment != null) { - b._vk_view_pDepthStencilAttachment_vk = vk_view_create_unsafe(*b.pDepthStencilAttachment) - b._vk_view_pDepthStencilAttachment_present = true - vk.pDepthStencilAttachment = addr(b._vk_view_pDepthStencilAttachment_vk) - b.pDepthStencilAttachment = null - } + if (b.pDepthStencilAttachment != null) { + b._vk_view_pDepthStencilAttachment_vk = vk_view_create_unsafe(*b.pDepthStencilAttachment) + b._vk_view_pDepthStencilAttachment_present = true + vk.pDepthStencilAttachment = unsafe(addr(b._vk_view_pDepthStencilAttachment_vk)) + b.pDepthStencilAttachment = null } b._vk_view_pPreserveAttachments := b.pPreserveAttachments vk.pPreserveAttachments = array_addr(b._vk_view_pPreserveAttachments) @@ -8794,13 +8758,11 @@ def vk_view_create_unsafe(var b : SubpassDescriptionDepthStencilResolve) : VkSub vk.pNext = b.next vk.depthResolveMode = b.depthResolveMode vk.stencilResolveMode = b.stencilResolveMode - unsafe { - if (b.pDepthStencilResolveAttachment != null) { - b._vk_view_pDepthStencilResolveAttachment_vk = vk_view_create_unsafe(*b.pDepthStencilResolveAttachment) - b._vk_view_pDepthStencilResolveAttachment_present = true - vk.pDepthStencilResolveAttachment = addr(b._vk_view_pDepthStencilResolveAttachment_vk) - b.pDepthStencilResolveAttachment = null - } + if (b.pDepthStencilResolveAttachment != null) { + b._vk_view_pDepthStencilResolveAttachment_vk = vk_view_create_unsafe(*b.pDepthStencilResolveAttachment) + b._vk_view_pDepthStencilResolveAttachment_present = true + vk.pDepthStencilResolveAttachment = unsafe(addr(b._vk_view_pDepthStencilResolveAttachment_vk)) + b.pDepthStencilResolveAttachment = null } return <- vk } @@ -9568,29 +9530,23 @@ def vk_view_create_unsafe(var b : RayTracingPipelineCreateInfoKHR) : VkRayTracin } vk.pGroups = array_addr(b._vk_view_pGroups) vk.maxPipelineRayRecursionDepth = b.maxPipelineRayRecursionDepth - unsafe { - if (b.pLibraryInfo != null) { - b._vk_view_pLibraryInfo_vk = vk_view_create_unsafe(*b.pLibraryInfo) - b._vk_view_pLibraryInfo_present = true - vk.pLibraryInfo = addr(b._vk_view_pLibraryInfo_vk) - b.pLibraryInfo = null - } - } - unsafe { - if (b.pLibraryInterface != null) { - b._vk_view_pLibraryInterface_vk = vk_view_create_unsafe(*b.pLibraryInterface) - b._vk_view_pLibraryInterface_present = true - vk.pLibraryInterface = addr(b._vk_view_pLibraryInterface_vk) - b.pLibraryInterface = null - } - } - unsafe { - if (b.pDynamicState != null) { - b._vk_view_pDynamicState_vk = vk_view_create_unsafe(*b.pDynamicState) - b._vk_view_pDynamicState_present = true - vk.pDynamicState = addr(b._vk_view_pDynamicState_vk) - b.pDynamicState = null - } + if (b.pLibraryInfo != null) { + b._vk_view_pLibraryInfo_vk = vk_view_create_unsafe(*b.pLibraryInfo) + b._vk_view_pLibraryInfo_present = true + vk.pLibraryInfo = unsafe(addr(b._vk_view_pLibraryInfo_vk)) + b.pLibraryInfo = null + } + if (b.pLibraryInterface != null) { + b._vk_view_pLibraryInterface_vk = vk_view_create_unsafe(*b.pLibraryInterface) + b._vk_view_pLibraryInterface_present = true + vk.pLibraryInterface = unsafe(addr(b._vk_view_pLibraryInterface_vk)) + b.pLibraryInterface = null + } + if (b.pDynamicState != null) { + b._vk_view_pDynamicState_vk = vk_view_create_unsafe(*b.pDynamicState) + b._vk_view_pDynamicState_present = true + vk.pDynamicState = unsafe(addr(b._vk_view_pDynamicState_vk)) + b.pDynamicState = null } vk.layout = boost_value_to_vk(b.layout) vk.basePipelineHandle = boost_value_to_vk(b.basePipelineHandle) @@ -13665,13 +13621,11 @@ struct FragmentShadingRateAttachmentInfoKHR { def vk_view_create_unsafe(var b : FragmentShadingRateAttachmentInfoKHR) : VkFragmentShadingRateAttachmentInfoKHR { var vk = VkFragmentShadingRateAttachmentInfoKHR() vk.pNext = b.next - unsafe { - if (b.pFragmentShadingRateAttachment != null) { - b._vk_view_pFragmentShadingRateAttachment_vk = vk_view_create_unsafe(*b.pFragmentShadingRateAttachment) - b._vk_view_pFragmentShadingRateAttachment_present = true - vk.pFragmentShadingRateAttachment = addr(b._vk_view_pFragmentShadingRateAttachment_vk) - b.pFragmentShadingRateAttachment = null - } + if (b.pFragmentShadingRateAttachment != null) { + b._vk_view_pFragmentShadingRateAttachment_vk = vk_view_create_unsafe(*b.pFragmentShadingRateAttachment) + b._vk_view_pFragmentShadingRateAttachment_present = true + vk.pFragmentShadingRateAttachment = unsafe(addr(b._vk_view_pFragmentShadingRateAttachment_vk)) + b.pFragmentShadingRateAttachment = null } vk.shadingRateAttachmentTexelSize = b.shadingRateAttachmentTexelSize return <- vk @@ -14506,13 +14460,11 @@ def vk_view_create_unsafe(var b : PipelineViewportDepthClampControlCreateInfoEXT var vk = VkPipelineViewportDepthClampControlCreateInfoEXT() vk.pNext = b.next vk.depthClampMode = b.depthClampMode - unsafe { - if (b.pDepthClampRange != null) { - b._vk_view_pDepthClampRange_vk = vk_view_create_unsafe(*b.pDepthClampRange) - b._vk_view_pDepthClampRange_present = true - vk.pDepthClampRange = addr(b._vk_view_pDepthClampRange_vk) - b.pDepthClampRange = null - } + if (b.pDepthClampRange != null) { + b._vk_view_pDepthClampRange_vk = vk_view_create_unsafe(*b.pDepthClampRange) + b._vk_view_pDepthClampRange_present = true + vk.pDepthClampRange = unsafe(addr(b._vk_view_pDepthClampRange_vk)) + b.pDepthClampRange = null } return <- vk } @@ -15479,13 +15431,11 @@ def vk_view_create_unsafe(var b : VideoReferenceSlotInfoKHR) : VkVideoReferenceS var vk = VkVideoReferenceSlotInfoKHR() vk.pNext = b.next vk.slotIndex = b.slotIndex - unsafe { - if (b.pPictureResource != null) { - b._vk_view_pPictureResource_vk = vk_view_create_unsafe(*b.pPictureResource) - b._vk_view_pPictureResource_present = true - vk.pPictureResource = addr(b._vk_view_pPictureResource_vk) - b.pPictureResource = null - } + if (b.pPictureResource != null) { + b._vk_view_pPictureResource_vk = vk_view_create_unsafe(*b.pPictureResource) + b._vk_view_pPictureResource_present = true + vk.pPictureResource = unsafe(addr(b._vk_view_pPictureResource_vk)) + b.pPictureResource = null } return <- vk } @@ -15544,13 +15494,11 @@ def vk_view_create_unsafe(var b : VideoDecodeInfoKHR) : VkVideoDecodeInfoKHR { vk.srcBufferOffset = b.srcBufferOffset vk.srcBufferRange = b.srcBufferRange vk.dstPictureResource = b.dstPictureResource - unsafe { - if (b.pSetupReferenceSlot != null) { - b._vk_view_pSetupReferenceSlot_vk = vk_view_create_unsafe(*b.pSetupReferenceSlot) - b._vk_view_pSetupReferenceSlot_present = true - vk.pSetupReferenceSlot = addr(b._vk_view_pSetupReferenceSlot_vk) - b.pSetupReferenceSlot = null - } + if (b.pSetupReferenceSlot != null) { + b._vk_view_pSetupReferenceSlot_vk = vk_view_create_unsafe(*b.pSetupReferenceSlot) + b._vk_view_pSetupReferenceSlot_present = true + vk.pSetupReferenceSlot = unsafe(addr(b._vk_view_pSetupReferenceSlot_vk)) + b.pSetupReferenceSlot = null } b._vk_view_pReferenceSlots |> resize(length(b.pReferenceSlots)) for (vkv, vke in b._vk_view_pReferenceSlots, b.pReferenceSlots) { @@ -15651,26 +15599,22 @@ def vk_view_create_unsafe(var b : VideoSessionCreateInfoKHR) : VkVideoSessionCre vk.pNext = b.next vk.queueFamilyIndex = b.queueFamilyIndex vk.flags = b.flags - unsafe { - if (b.pVideoProfile != null) { - b._vk_view_pVideoProfile_vk = vk_view_create_unsafe(*b.pVideoProfile) - b._vk_view_pVideoProfile_present = true - vk.pVideoProfile = addr(b._vk_view_pVideoProfile_vk) - b.pVideoProfile = null - } + if (b.pVideoProfile != null) { + b._vk_view_pVideoProfile_vk = vk_view_create_unsafe(*b.pVideoProfile) + b._vk_view_pVideoProfile_present = true + vk.pVideoProfile = unsafe(addr(b._vk_view_pVideoProfile_vk)) + b.pVideoProfile = null } vk.pictureFormat = b.pictureFormat vk.maxCodedExtent = b.maxCodedExtent vk.referencePictureFormat = b.referencePictureFormat vk.maxDpbSlots = b.maxDpbSlots vk.maxActiveReferencePictures = b.maxActiveReferencePictures - unsafe { - if (b.pStdHeaderVersion != null) { - b._vk_view_pStdHeaderVersion_vk = vk_view_create_unsafe(*b.pStdHeaderVersion) - b._vk_view_pStdHeaderVersion_present = true - vk.pStdHeaderVersion = addr(b._vk_view_pStdHeaderVersion_vk) - b.pStdHeaderVersion = null - } + if (b.pStdHeaderVersion != null) { + b._vk_view_pStdHeaderVersion_vk = vk_view_create_unsafe(*b.pStdHeaderVersion) + b._vk_view_pStdHeaderVersion_present = true + vk.pStdHeaderVersion = unsafe(addr(b._vk_view_pStdHeaderVersion_vk)) + b.pStdHeaderVersion = null } return <- vk } @@ -15840,13 +15784,11 @@ def vk_view_create_unsafe(var b : VideoEncodeInfoKHR) : VkVideoEncodeInfoKHR { vk.dstBufferOffset = b.dstBufferOffset vk.dstBufferRange = b.dstBufferRange vk.srcPictureResource = b.srcPictureResource - unsafe { - if (b.pSetupReferenceSlot != null) { - b._vk_view_pSetupReferenceSlot_vk = vk_view_create_unsafe(*b.pSetupReferenceSlot) - b._vk_view_pSetupReferenceSlot_present = true - vk.pSetupReferenceSlot = addr(b._vk_view_pSetupReferenceSlot_vk) - b.pSetupReferenceSlot = null - } + if (b.pSetupReferenceSlot != null) { + b._vk_view_pSetupReferenceSlot_vk = vk_view_create_unsafe(*b.pSetupReferenceSlot) + b._vk_view_pSetupReferenceSlot_present = true + vk.pSetupReferenceSlot = unsafe(addr(b._vk_view_pSetupReferenceSlot_vk)) + b.pSetupReferenceSlot = null } b._vk_view_pReferenceSlots |> resize(length(b.pReferenceSlots)) for (vkv, vke in b._vk_view_pReferenceSlots, b.pReferenceSlots) { @@ -15949,13 +15891,11 @@ struct PhysicalDeviceVideoEncodeQualityLevelInfoKHR { def vk_view_create_unsafe(var b : PhysicalDeviceVideoEncodeQualityLevelInfoKHR) : VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR { var vk = VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR() vk.pNext = b.next - unsafe { - if (b.pVideoProfile != null) { - b._vk_view_pVideoProfile_vk = vk_view_create_unsafe(*b.pVideoProfile) - b._vk_view_pVideoProfile_present = true - vk.pVideoProfile = addr(b._vk_view_pVideoProfile_vk) - b.pVideoProfile = null - } + if (b.pVideoProfile != null) { + b._vk_view_pVideoProfile_vk = vk_view_create_unsafe(*b.pVideoProfile) + b._vk_view_pVideoProfile_present = true + vk.pVideoProfile = unsafe(addr(b._vk_view_pVideoProfile_vk)) + b.pVideoProfile = null } vk.qualityLevel = b.qualityLevel return <- vk @@ -16618,13 +16558,11 @@ def vk_view_create_unsafe(var b : CommandBufferInheritanceViewportScissorInfoNV) vk.pNext = b.next vk.viewportScissor2D = b.viewportScissor2D vk.viewportDepthCount = b.viewportDepthCount - unsafe { - if (b.pViewportDepths != null) { - b._vk_view_pViewportDepths_vk = vk_view_create_unsafe(*b.pViewportDepths) - b._vk_view_pViewportDepths_present = true - vk.pViewportDepths = addr(b._vk_view_pViewportDepths_vk) - b.pViewportDepths = null - } + if (b.pViewportDepths != null) { + b._vk_view_pViewportDepths_vk = vk_view_create_unsafe(*b.pViewportDepths) + b._vk_view_pViewportDepths_present = true + vk.pViewportDepths = unsafe(addr(b._vk_view_pViewportDepths_vk)) + b.pViewportDepths = null } return <- vk } @@ -17500,21 +17438,17 @@ def vk_view_create_unsafe(var b : RenderingInfo) : VkRenderingInfo { vkv = vk_view_create_unsafe(vke) } vk.pColorAttachments = array_addr(b._vk_view_pColorAttachments) - unsafe { - if (b.pDepthAttachment != null) { - b._vk_view_pDepthAttachment_vk = vk_view_create_unsafe(*b.pDepthAttachment) - b._vk_view_pDepthAttachment_present = true - vk.pDepthAttachment = addr(b._vk_view_pDepthAttachment_vk) - b.pDepthAttachment = null - } - } - unsafe { - if (b.pStencilAttachment != null) { - b._vk_view_pStencilAttachment_vk = vk_view_create_unsafe(*b.pStencilAttachment) - b._vk_view_pStencilAttachment_present = true - vk.pStencilAttachment = addr(b._vk_view_pStencilAttachment_vk) - b.pStencilAttachment = null - } + if (b.pDepthAttachment != null) { + b._vk_view_pDepthAttachment_vk = vk_view_create_unsafe(*b.pDepthAttachment) + b._vk_view_pDepthAttachment_present = true + vk.pDepthAttachment = unsafe(addr(b._vk_view_pDepthAttachment_vk)) + b.pDepthAttachment = null + } + if (b.pStencilAttachment != null) { + b._vk_view_pStencilAttachment_vk = vk_view_create_unsafe(*b.pStencilAttachment) + b._vk_view_pStencilAttachment_present = true + vk.pStencilAttachment = unsafe(addr(b._vk_view_pStencilAttachment_vk)) + b.pStencilAttachment = null } vk.colorAttachmentCount = uint(length(b.pColorAttachments)) return <- vk @@ -19728,21 +19662,17 @@ struct DeviceImageSubresourceInfo { def vk_view_create_unsafe(var b : DeviceImageSubresourceInfo) : VkDeviceImageSubresourceInfo { var vk = VkDeviceImageSubresourceInfo() vk.pNext = b.next - unsafe { - if (b.pCreateInfo != null) { - b._vk_view_pCreateInfo_vk = vk_view_create_unsafe(*b.pCreateInfo) - b._vk_view_pCreateInfo_present = true - vk.pCreateInfo = addr(b._vk_view_pCreateInfo_vk) - b.pCreateInfo = null - } + if (b.pCreateInfo != null) { + b._vk_view_pCreateInfo_vk = vk_view_create_unsafe(*b.pCreateInfo) + b._vk_view_pCreateInfo_present = true + vk.pCreateInfo = unsafe(addr(b._vk_view_pCreateInfo_vk)) + b.pCreateInfo = null } - unsafe { - if (b.pSubresource != null) { - b._vk_view_pSubresource_vk = vk_view_create_unsafe(*b.pSubresource) - b._vk_view_pSubresource_present = true - vk.pSubresource = addr(b._vk_view_pSubresource_vk) - b.pSubresource = null - } + if (b.pSubresource != null) { + b._vk_view_pSubresource_vk = vk_view_create_unsafe(*b.pSubresource) + b._vk_view_pSubresource_present = true + vk.pSubresource = unsafe(addr(b._vk_view_pSubresource_vk)) + b.pSubresource = null } return <- vk } @@ -19912,13 +19842,11 @@ def vk_view_create_unsafe(var b : ShaderCreateInfoEXT) : VkShaderCreateInfoEXT { vkv = vk_view_create_unsafe(vke) } vk.pPushConstantRanges = array_addr(b._vk_view_pPushConstantRanges) - unsafe { - if (b.pSpecializationInfo != null) { - b._vk_view_pSpecializationInfo_vk = vk_view_create_unsafe(*b.pSpecializationInfo) - b._vk_view_pSpecializationInfo_present = true - vk.pSpecializationInfo = addr(b._vk_view_pSpecializationInfo_vk) - b.pSpecializationInfo = null - } + if (b.pSpecializationInfo != null) { + b._vk_view_pSpecializationInfo_vk = vk_view_create_unsafe(*b.pSpecializationInfo) + b._vk_view_pSpecializationInfo_present = true + vk.pSpecializationInfo = unsafe(addr(b._vk_view_pSpecializationInfo_vk)) + b.pSpecializationInfo = null } vk.codeSize = uint64(long_length(b.pCode)) vk.setLayoutCount = b.setLayoutCount != 0u ? b.setLayoutCount : uint(length(b.pSetLayouts)) @@ -20074,13 +20002,11 @@ def vk_view_create_unsafe(var b : AntiLagDataAMD) : VkAntiLagDataAMD { vk.pNext = b.next vk.mode = b.mode vk.maxFPS = b.maxFPS - unsafe { - if (b.pPresentationInfo != null) { - b._vk_view_pPresentationInfo_vk = vk_view_create_unsafe(*b.pPresentationInfo) - b._vk_view_pPresentationInfo_present = true - vk.pPresentationInfo = addr(b._vk_view_pPresentationInfo_vk) - b.pPresentationInfo = null - } + if (b.pPresentationInfo != null) { + b._vk_view_pPresentationInfo_vk = vk_view_create_unsafe(*b.pPresentationInfo) + b._vk_view_pPresentationInfo_present = true + vk.pPresentationInfo = unsafe(addr(b._vk_view_pPresentationInfo_vk)) + b.pPresentationInfo = null } return <- vk } @@ -21720,13 +21646,11 @@ def vk_view_create_unsafe(var b : TensorCreateInfoARM) : VkTensorCreateInfoARM { var vk = VkTensorCreateInfoARM() vk.pNext = b.next vk.flags = b.flags - unsafe { - if (b.pDescription != null) { - b._vk_view_pDescription_vk = vk_view_create_unsafe(*b.pDescription) - b._vk_view_pDescription_present = true - vk.pDescription = addr(b._vk_view_pDescription_vk) - b.pDescription = null - } + if (b.pDescription != null) { + b._vk_view_pDescription_vk = vk_view_create_unsafe(*b.pDescription) + b._vk_view_pDescription_present = true + vk.pDescription = unsafe(addr(b._vk_view_pDescription_vk)) + b.pDescription = null } vk.sharingMode = b.sharingMode b._vk_view_pQueueFamilyIndices := b.pQueueFamilyIndices @@ -21944,13 +21868,11 @@ struct DeviceTensorMemoryRequirementsARM { def vk_view_create_unsafe(var b : DeviceTensorMemoryRequirementsARM) : VkDeviceTensorMemoryRequirementsARM { var vk = VkDeviceTensorMemoryRequirementsARM() vk.pNext = b.next - unsafe { - if (b.pCreateInfo != null) { - b._vk_view_pCreateInfo_vk = vk_view_create_unsafe(*b.pCreateInfo) - b._vk_view_pCreateInfo_present = true - vk.pCreateInfo = addr(b._vk_view_pCreateInfo_vk) - b.pCreateInfo = null - } + if (b.pCreateInfo != null) { + b._vk_view_pCreateInfo_vk = vk_view_create_unsafe(*b.pCreateInfo) + b._vk_view_pCreateInfo_present = true + vk.pCreateInfo = unsafe(addr(b._vk_view_pCreateInfo_vk)) + b.pCreateInfo = null } return <- vk } @@ -22132,13 +22054,11 @@ def vk_view_create_unsafe(var b : PhysicalDeviceExternalTensorInfoARM) : VkPhysi var vk = VkPhysicalDeviceExternalTensorInfoARM() vk.pNext = b.next vk.flags = b.flags - unsafe { - if (b.pDescription != null) { - b._vk_view_pDescription_vk = vk_view_create_unsafe(*b.pDescription) - b._vk_view_pDescription_present = true - vk.pDescription = addr(b._vk_view_pDescription_vk) - b.pDescription = null - } + if (b.pDescription != null) { + b._vk_view_pDescription_vk = vk_view_create_unsafe(*b.pDescription) + b._vk_view_pDescription_present = true + vk.pDescription = unsafe(addr(b._vk_view_pDescription_vk)) + b.pDescription = null } vk.handleType = b.handleType return <- vk @@ -22563,13 +22483,11 @@ struct DataGraphPipelineBuiltinModelCreateInfoQCOM { def vk_view_create_unsafe(var b : DataGraphPipelineBuiltinModelCreateInfoQCOM) : VkDataGraphPipelineBuiltinModelCreateInfoQCOM { var vk = VkDataGraphPipelineBuiltinModelCreateInfoQCOM() vk.pNext = b.next - unsafe { - if (b.pOperation != null) { - b._vk_view_pOperation_vk = vk_view_create_unsafe(*b.pOperation) - b._vk_view_pOperation_present = true - vk.pOperation = addr(b._vk_view_pOperation_vk) - b.pOperation = null - } + if (b.pOperation != null) { + b._vk_view_pOperation_vk = vk_view_create_unsafe(*b.pOperation) + b._vk_view_pOperation_present = true + vk.pOperation = unsafe(addr(b._vk_view_pOperation_vk)) + b.pOperation = null } return <- vk } @@ -22935,13 +22853,11 @@ struct ImageDescriptorInfoEXT { def vk_view_create_unsafe(var b : ImageDescriptorInfoEXT) : VkImageDescriptorInfoEXT { var vk = VkImageDescriptorInfoEXT() vk.pNext = b.next - unsafe { - if (b.pView != null) { - b._vk_view_pView_vk = vk_view_create_unsafe(*b.pView) - b._vk_view_pView_present = true - vk.pView = addr(b._vk_view_pView_vk) - b.pView = null - } + if (b.pView != null) { + b._vk_view_pView_vk = vk_view_create_unsafe(*b.pView) + b._vk_view_pView_present = true + vk.pView = unsafe(addr(b._vk_view_pView_vk)) + b.pView = null } vk.layout = b.layout return <- vk @@ -22981,13 +22897,11 @@ def vk_view_create_unsafe(var b : DescriptorMappingSourceConstantOffsetEXT) : Vk var vk = VkDescriptorMappingSourceConstantOffsetEXT() vk.heapOffset = b.heapOffset vk.heapArrayStride = b.heapArrayStride - unsafe { - if (b.pEmbeddedSampler != null) { - b._vk_view_pEmbeddedSampler_vk = vk_view_create_unsafe(*b.pEmbeddedSampler) - b._vk_view_pEmbeddedSampler_present = true - vk.pEmbeddedSampler = addr(b._vk_view_pEmbeddedSampler_vk) - b.pEmbeddedSampler = null - } + if (b.pEmbeddedSampler != null) { + b._vk_view_pEmbeddedSampler_vk = vk_view_create_unsafe(*b.pEmbeddedSampler) + b._vk_view_pEmbeddedSampler_present = true + vk.pEmbeddedSampler = unsafe(addr(b._vk_view_pEmbeddedSampler_vk)) + b.pEmbeddedSampler = null } vk.samplerHeapOffset = b.samplerHeapOffset vk.samplerHeapArrayStride = b.samplerHeapArrayStride @@ -23019,13 +22933,11 @@ def vk_view_create_unsafe(var b : DescriptorMappingSourcePushIndexEXT) : VkDescr vk.pushOffset = b.pushOffset vk.heapIndexStride = b.heapIndexStride vk.heapArrayStride = b.heapArrayStride - unsafe { - if (b.pEmbeddedSampler != null) { - b._vk_view_pEmbeddedSampler_vk = vk_view_create_unsafe(*b.pEmbeddedSampler) - b._vk_view_pEmbeddedSampler_present = true - vk.pEmbeddedSampler = addr(b._vk_view_pEmbeddedSampler_vk) - b.pEmbeddedSampler = null - } + if (b.pEmbeddedSampler != null) { + b._vk_view_pEmbeddedSampler_vk = vk_view_create_unsafe(*b.pEmbeddedSampler) + b._vk_view_pEmbeddedSampler_present = true + vk.pEmbeddedSampler = unsafe(addr(b._vk_view_pEmbeddedSampler_vk)) + b.pEmbeddedSampler = null } vk.useCombinedImageSamplerIndex = b.useCombinedImageSamplerIndex vk.samplerHeapOffset = b.samplerHeapOffset @@ -23063,13 +22975,11 @@ def vk_view_create_unsafe(var b : DescriptorMappingSourceIndirectIndexEXT) : VkD vk.addressOffset = b.addressOffset vk.heapIndexStride = b.heapIndexStride vk.heapArrayStride = b.heapArrayStride - unsafe { - if (b.pEmbeddedSampler != null) { - b._vk_view_pEmbeddedSampler_vk = vk_view_create_unsafe(*b.pEmbeddedSampler) - b._vk_view_pEmbeddedSampler_present = true - vk.pEmbeddedSampler = addr(b._vk_view_pEmbeddedSampler_vk) - b.pEmbeddedSampler = null - } + if (b.pEmbeddedSampler != null) { + b._vk_view_pEmbeddedSampler_vk = vk_view_create_unsafe(*b.pEmbeddedSampler) + b._vk_view_pEmbeddedSampler_present = true + vk.pEmbeddedSampler = unsafe(addr(b._vk_view_pEmbeddedSampler_vk)) + b.pEmbeddedSampler = null } vk.useCombinedImageSamplerIndex = b.useCombinedImageSamplerIndex vk.samplerHeapOffset = b.samplerHeapOffset @@ -23105,13 +23015,11 @@ def vk_view_create_unsafe(var b : DescriptorMappingSourceIndirectIndexArrayEXT) vk.pushOffset = b.pushOffset vk.addressOffset = b.addressOffset vk.heapIndexStride = b.heapIndexStride - unsafe { - if (b.pEmbeddedSampler != null) { - b._vk_view_pEmbeddedSampler_vk = vk_view_create_unsafe(*b.pEmbeddedSampler) - b._vk_view_pEmbeddedSampler_present = true - vk.pEmbeddedSampler = addr(b._vk_view_pEmbeddedSampler_vk) - b.pEmbeddedSampler = null - } + if (b.pEmbeddedSampler != null) { + b._vk_view_pEmbeddedSampler_vk = vk_view_create_unsafe(*b.pEmbeddedSampler) + b._vk_view_pEmbeddedSampler_present = true + vk.pEmbeddedSampler = unsafe(addr(b._vk_view_pEmbeddedSampler_vk)) + b.pEmbeddedSampler = null } vk.useCombinedImageSamplerIndex = b.useCombinedImageSamplerIndex vk.samplerHeapOffset = b.samplerHeapOffset @@ -23160,13 +23068,11 @@ def vk_view_create_unsafe(var b : DescriptorMappingSourceShaderRecordIndexEXT) : vk.shaderRecordOffset = b.shaderRecordOffset vk.heapIndexStride = b.heapIndexStride vk.heapArrayStride = b.heapArrayStride - unsafe { - if (b.pEmbeddedSampler != null) { - b._vk_view_pEmbeddedSampler_vk = vk_view_create_unsafe(*b.pEmbeddedSampler) - b._vk_view_pEmbeddedSampler_present = true - vk.pEmbeddedSampler = addr(b._vk_view_pEmbeddedSampler_vk) - b.pEmbeddedSampler = null - } + if (b.pEmbeddedSampler != null) { + b._vk_view_pEmbeddedSampler_vk = vk_view_create_unsafe(*b.pEmbeddedSampler) + b._vk_view_pEmbeddedSampler_present = true + vk.pEmbeddedSampler = unsafe(addr(b._vk_view_pEmbeddedSampler_vk)) + b.pEmbeddedSampler = null } vk.useCombinedImageSamplerIndex = b.useCombinedImageSamplerIndex vk.samplerHeapOffset = b.samplerHeapOffset @@ -23265,13 +23171,11 @@ struct OpaqueCaptureDataCreateInfoEXT { def vk_view_create_unsafe(var b : OpaqueCaptureDataCreateInfoEXT) : VkOpaqueCaptureDataCreateInfoEXT { var vk = VkOpaqueCaptureDataCreateInfoEXT() vk.pNext = b.next - unsafe { - if (b.pData != null) { - b._vk_view_pData_vk = vk_view_create_unsafe(*b.pData) - b._vk_view_pData_present = true - vk.pData = addr(b._vk_view_pData_vk) - b.pData = null - } + if (b.pData != null) { + b._vk_view_pData_vk = vk_view_create_unsafe(*b.pData) + b._vk_view_pData_present = true + vk.pData = unsafe(addr(b._vk_view_pData_vk)) + b.pData = null } return <- vk } diff --git a/modules/dasVulkan/generator/vk_emit_boost.das b/modules/dasVulkan/generator/vk_emit_boost.das index 2ffe27b532..80b1bfc8a2 100644 --- a/modules/dasVulkan/generator/vk_emit_boost.das +++ b/modules/dasVulkan/generator/vk_emit_boost.das @@ -173,13 +173,11 @@ def private emit_handles_boost(reg : VkRegistry; em : EmitModel; out_dir : strin fprint(f, "def finalize(var self : {oi.boost}) \{\n") if (!empty(oi.destroyer) && !oi.pool_owned) { fprint(f, " if (self._needs_delete) \{\n") - fprint(f, " unsafe \{\n") - fprint(f, " {oi.destroyer}(") + fprint(f, " {oi.destroyer}(") for (pf in oi.parents) { - fprint(f, "reinterpret<{pf.vktype}>(self.{pf.field}), ") + fprint(f, "unsafe(reinterpret<{pf.vktype}>(self.{pf.field})), ") } - fprint(f, "reinterpret<{oi.handle}>(self._vk), null)\n") - fprint(f, " \}\n") + fprint(f, "unsafe(reinterpret<{oi.handle}>(self._vk)), null)\n") fprint(f, " \}\n") } fprint(f, " self._needs_delete = false\n") @@ -691,13 +689,11 @@ def private emit_structs_boost(reg : VkRegistry; em : EmitModel; out_dir : strin fprint(f, " vk.{bf.name} = array_addr(b._vk_view_{bf.name})\n") } elif (bf.kind == FieldKind.opt_struct_ptr) { // viewed where the caller keeps it, so this struct embeds only the raw view and stays copyable - fprint(f, " unsafe {OB}\n") - fprint(f, " if (b.{bf.name} != null) {OB}\n") - fprint(f, " b._vk_view_{bf.name}_vk = vk_view_create_unsafe(*b.{bf.name})\n") - fprint(f, " b._vk_view_{bf.name}_present = true\n") - fprint(f, " vk.{bf.name} = addr(b._vk_view_{bf.name}_vk)\n") - fprint(f, " b.{bf.name} = null\n") - fprint(f, " {CB}\n") + fprint(f, " if (b.{bf.name} != null) {OB}\n") + fprint(f, " b._vk_view_{bf.name}_vk = vk_view_create_unsafe(*b.{bf.name})\n") + fprint(f, " b._vk_view_{bf.name}_present = true\n") + fprint(f, " vk.{bf.name} = unsafe(addr(b._vk_view_{bf.name}_vk))\n") + fprint(f, " b.{bf.name} = null\n") fprint(f, " {CB}\n") } } @@ -904,11 +900,11 @@ def private batch_call_arg(a : BatchArg) : string { } elif (a.kind == BatchArgKind.count) { return "uint(n)" } elif (a.kind == BatchArgKind.create_infos) { - return "addr(vkraw[0])" + return "unsafe(addr(vkraw[0]))" } elif (a.kind == BatchArgKind.create_info) { return "vci" } elif (a.kind == BatchArgKind.out_handles) { - return "addr(vkout[0])" + return "unsafe(addr(vkout[0]))" } return "null" // allocator } @@ -943,8 +939,7 @@ def private emit_batch_creator(f : file; ci : CreatorInfo; scratch_types : table fprint(f, " var vkout : array<{ci.handle}>\n") fprint(f, " vkout |> resize(n)\n") fprint(f, " if (n > 0) \{\n") - fprint(f, " unsafe \{\n") - fprint(f, " vk_check({ci.command}(") + fprint(f, " vk_check({ci.command}(") var first = true for (a in ci.batch_call) { fprint(f, ", ") if (!first) @@ -952,7 +947,6 @@ def private emit_batch_creator(f : file; ci : CreatorInfo; scratch_types : table fprint(f, batch_call_arg(a)) } fprint(f, "), result)\n") - fprint(f, " \}\n") fprint(f, " \}\n") if (ci.shape_a) { fprint(f, " for (vkv in create_infos) \{ vk_view_destroy(vkv) \}\n") @@ -1436,13 +1430,10 @@ def private emit_plain_commands_boost(reg : VkRegistry; em : EmitModel; out_dir fprint(f, " {CB}\n") } fprint(f, " if (vkcount > {plan.count_is_64 ? "0ul" : "0u"}) {OB}\n") - fprint(f, " unsafe {OB}\n") - fprint(f, " {lhs_open}{plan.command}(") - // already inside `unsafe`, so the byte payload cast takes no wrap of its own + fprint(f, " {lhs_open}{plan.command}(") emit_call_args(f, plan, plan.out_array_is_bytes - ? "addr(vklist[0])" : "addr(vklist[0])") + ? "unsafe(addr(vklist[0]))" : "unsafe(addr(vklist[0]))") fprint(f, "){lhs_close}\n") - fprint(f, " {CB}\n") fprint(f, " {CB}\n") emit_scratch_cleanup(f, plan) fprint(f, " return <- vklist\n") From e999e2559d58b15f2cbb34f28c123706a66d0e95 Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Wed, 16 Sep 2026 19:57:12 +0300 Subject: [PATCH 07/12] style: narrow the unsafe wraps to the operation that needs them STYLE024 and STYLE025 went blind on the tool path until the unsafe-scope rules were repaired, so the tree carries wraps around bodies that need no permission and blocks broader than the one operation inside them. A redundant wrap goes and the body dedents; a broad one collapses onto the operation the compiler names - addr, reinterpret, pointer index, pointer arithmetic, an unsafe builtin - which is the only way to find it, since the finding says a narrowing is possible without saying of what. An assignment takes `lhs = unsafe(rhs)`, a pointer index on the left takes `unsafe(p[i]) = v`, and a call with a block wraps whole, closing brace included. The rules stop reporting wraps the compiler requires. A declaration owns its permission - a stack class local, a smart_ptr local without inscope, a local of a non-local type - and `unsafe()` is an expression form with nothing to wrap: `let d = unsafe(Derived())` still reports error[31017] on `d`. A delete lowers to builtin`finalize_dim` as well as builtin`finalize`, and whether it needs the wrap is TypeDecl::isSafeToDelete, now bound so this side can read it. A module `with` survives infer under the lint's own policies, so it marks when the file carries with_module_is_unsafe. Reading isSafeToDelete also stops a safe delete from counting as the reason for its wrap, which uncovered redundant wraps the unconditional marking had hidden - six in tests/language/smart_ptr.das and one in the STYLE024 fixture, whose expectation moves from 5 to 6 because it was pinning the over-marking rather than the rule. One site keeps a nolint: `_fold` rewrites its chain and erases the `each` whose unsafeOutsideOfFor required the wrap, leaving nothing in the tree to mark. llvm_jit.das, llvm_macro.das and llvm_jit_link.das are in the pinned emitter set, so the pin moves with them. An unsafe wrapper is a compile-time permission scope the fold removes before codegen, so emitted code is unchanged and LLVM_JIT_CODEGEN_VERSION holds. --- daslib/style_lint.das | 48 +++- dastest/dastest.das | 2 +- doc/source/reference/language/lint.rst | 5 + ...__rq_isSafeToDelete-0x39575a71bd440d4d.rst | 1 + examples/debugapi/allocation_tracking.das | 6 +- examples/debugapi/hw_breakpoint.das | 24 +- examples/debugapi/stack_walker.das | 6 +- examples/pathTracer/toy_path_tracer.das | 4 +- .../pathTracer/toy_path_tracer_profile.das | 6 +- .../one_source_path_tracer/pt_reference.das | 9 +- modules/dasGlsl/glsl/glsl_internal.das | 13 +- modules/dasHV/example/telnet.das | 9 +- modules/dasLLAMA/REVIEW.das | 2 +- .../dasLLAMA/benchmarks/setup_lcpp_ref.das | 10 +- .../dasllama/dasllama_arch_qwen35.das | 26 +-- modules/dasLLAMA/dasllama/dasllama_batch.das | 28 +-- modules/dasLLAMA/dasllama/dasllama_common.das | 4 +- modules/dasLLAMA/dasllama/dasllama_image.das | 16 +- .../dasLLAMA/dasllama/dasllama_kv_codec.das | 12 +- modules/dasLLAMA/dasllama/dasllama_load.das | 4 +- modules/dasLLAMA/dasllama/dasllama_moe.das | 8 +- .../dasLLAMA/dasllama/dasllama_mtp_gemma.das | 8 +- modules/dasLLAMA/dasllama/dasllama_pocket.das | 4 +- modules/dasLLAMA/dasllama/dasllama_rope.das | 4 +- .../dasLLAMA/dasllama/dasllama_tts_blocks.das | 16 +- .../dasLLAMA/dasllama/dasllama_whisper.das | 16 +- modules/dasLLAMA/harness/batch_rows_probe.das | 4 +- modules/dasLLAMA/harness/dasllama_tuner.das | 22 +- modules/dasLLAMA/harness/tune_kernels.das | 32 +-- modules/dasLLAMA/performance/box_ident.das | 12 +- .../performance/coopmat_mulmm_port.das | 8 +- .../performance/coopmat_mulmm_reference.das | 8 +- modules/dasLLAMA/tests/test_deltanet.das | 4 +- modules/dasLLAMA/tests/test_repack.das | 24 +- .../tests/test_repack_lane_context.das | 6 +- modules/dasLLAMA/tests/test_rope_apply.das | 16 +- .../dasLLAMA/tests/test_tower_asr_kernels.das | 8 +- modules/dasLLAMA/tests/test_tower_helpers.das | 12 +- modules/dasLLAMA/tests/test_tts_blocks.das | 6 +- .../dasLLAMA/tests/test_tune_interrupt.das | 14 +- modules/dasLLVM/daslib/llvm_jit.das | 18 +- modules/dasLLVM/daslib/llvm_jit_link.das | 4 +- modules/dasLLVM/daslib/llvm_jit_run.das | 8 +- modules/dasLLVM/daslib/llvm_macro.das | 4 +- modules/dasLLVM/tests/llvm_jit_baseline.das | 21 +- modules/dasLLVM/tests/llvm_tune_fat.das | 21 +- modules/dasLLVM/tests/llvm_tune_manifest.das | 39 ++-- modules/dasLLVM/tests/llvm_tune_modes.das | 21 +- modules/dasLLVM/tests/llvm_tune_profiles.das | 21 +- modules/dasLLVM/tests/llvm_tune_scope.das | 29 +-- modules/dasLLVM/tests/test_tuned.das | 22 +- modules/dasOpenGL/opengl/opengl_boost.das | 12 +- modules/dasOpenGL/opengl/opengl_ttf.das | 12 +- modules/dasPEG/peg/parser_generator.das | 11 +- modules/dasTerminal/daslib/terminal.das | 4 +- modules/dasTerminal/tests/app_compat.das | 24 +- .../dasTerminal/tests/ownership_semantics.das | 2 +- modules/dasVulkan/daslib/vulkan_assets.das | 20 +- modules/dasVulkan/daslib/vulkan_boost.das | 218 +++++------------- modules/dasVulkan/daslib/vulkan_gltf.das | 48 ++-- modules/dasVulkan/daslib/vulkan_live.das | 18 +- modules/dasVulkan/daslib/vulkan_reflect.das | 2 +- modules/dasVulkan/daslib/vulkan_runtime.das | 4 +- modules/dasVulkan/daslib/vulkan_window.das | 24 +- modules/dasVulkan/examples/compute.das | 30 +-- modules/dasVulkan/examples/device_probe.das | 22 +- modules/dasVulkan/examples/enumerate.das | 8 +- .../dasVulkan/examples/offscreen_triangle.das | 76 ++---- modules/dasVulkan/examples/smoke.das | 8 +- .../tests/integration/scene_helpers.das | 30 +-- .../test_bindless_descriptor_array.das | 4 +- .../integration/test_compute_features.das | 4 +- .../tests/integration/test_compute_shared.das | 24 +- .../tests/integration/test_nonuniform_ext.das | 4 +- .../test_opt_ptr_view_semantics.das | 4 +- .../integration/test_os_video_memory.das | 4 +- .../tests/integration/test_ubo_nested.das | 4 +- .../window/mandelbrot_compute.das | 2 +- .../dasVulkan/tutorials/03_sdf/sdf_tut.das | 40 ++-- .../03_sdf/window/resident_compute.das | 2 +- .../dasVulkan/tutorials/04_cube/cube_tut.das | 44 ++-- .../05_instancing/instancing_tut.das | 38 ++- .../tutorials/06_skybox/skybox_tut.das | 56 +++-- .../tutorials/07_particles/particles_tut.das | 54 ++--- .../tutorials/08_shadow/shadow_tut.das | 60 +++-- .../dasVulkan/tutorials/09_msaa/msaa_tut.das | 48 ++-- .../tutorials/10_deferred/deferred_tut.das | 106 ++++----- .../dasVulkan/tutorials/11_hdr/hdr_tut.das | 84 ++++--- .../12_gpu_driven/gpu_driven_tut.das | 98 ++++---- .../tutorials/14_teapot/teapot_tut.das | 50 ++-- .../tutorials/recording/tutorial_record.das | 4 +- skills/daslang/references/everything.md | 1 + .../module_builtin_ast_annotations_1.cpp | 1 + tests/aot/test_int64_ptr_index.das | 4 +- tests/ast/test_any_long_size.das | 12 +- .../test_bool_array_iterator_crash.das | 4 +- tests/dasPUGIXML/test_serial_table.das | 4 +- tests/dasPUGIXML/test_serial_variant.das | 4 +- tests/daslib/eval_single_expression_test.das | 40 ++-- tests/data_walker/test_walk_containers.das | 48 +--- tests/data_walker/test_walk_edge_cases.das | 56 ++--- tests/data_walker/test_walk_filtering.das | 24 +- tests/data_walker/test_walk_lattice.das | 12 +- tests/data_walker/test_walk_mutation.das | 20 +- tests/data_walker/test_walk_scalars.das | 74 ++---- tests/data_walker/test_walk_structs.das | 28 +-- .../data_walker/test_walk_tuples_variants.das | 20 +- .../data_walker/test_walk_vectors_ranges.das | 52 ++--- .../debug_agent/test_callback_threadlock.das | 16 +- tests/debug_agent/test_invoke_in_context.das | 16 +- tests/debug_agent/test_invoke_method.das | 20 +- tests/debug_agent/test_lifecycle.das | 4 +- tests/debug_agent/test_on_log.das | 20 +- tests/debug_agent/test_state_collection.das | 16 +- tests/debug_agent/test_threadlock.das | 12 +- tests/decs/test_gc.das | 16 +- tests/fio/fio_dwrite.das | 8 +- tests/fio/fio_exit_now.das | 4 +- tests/fio/fio_fmap_rw.das | 8 +- tests/fio/fio_prefetch.das | 4 +- tests/fixed_array/test_layout.das | 4 +- tests/gc/gc_typedecl.das | 8 +- tests/gc/lattice_escape_tests.das | 6 +- tests/gc/test_gc_coverage.das | 4 +- tests/gc/test_gc_deep_recursion.das | 4 +- tests/gc/test_gc_escape_free.das | 22 +- tests/jit_tests/aarch64_neon.das | 24 +- tests/jit_tests/const_arg_readonly.das | 54 ++--- tests/jit_tests/cross_target_folds.das | 20 +- tests/jit_tests/exe_host_cpu.das | 21 +- tests/jit_tests/jit_exe.das | 10 +- tests/jit_tests/jit_lib.das | 21 +- tests/jit_tests/llvm_compile_only.das | 23 +- tests/jit_tests/llvm_split_modules.das | 21 +- tests/jit_tests/memset.das | 24 +- tests/jit_tests/new_ascend_and_delete.das | 30 +-- tests/jit_tests/pointer.das | 12 +- tests/jit_tests/trap_block_ann.das | 10 +- tests/jit_tests/variant.das | 4 +- tests/jobque/test_jobque_jobs.das | 18 +- tests/jobque/test_jobque_tracking.das | 44 ++-- tests/json/test_sscan_json.das | 30 +-- tests/jsonrpc/test_request_ownership.das | 4 +- tests/language/addr_cast_sugar.das | 8 +- tests/language/annotation_info.das | 16 +- tests/language/cast.das | 8 +- .../const_strip_write_through_passthrough.das | 22 +- tests/language/container_finalize.das | 8 +- tests/language/container_init_off.das | 12 +- tests/language/each_ref.das | 4 +- tests/language/lock_array.das | 8 +- tests/language/new_delete.das | 8 +- .../offset_pointer_write_through_helper.das | 2 +- .../optimization_auto_inline_functions.das | 4 +- tests/language/optimization_inline_unsafe.das | 8 +- tests/language/pointers.das | 76 +++--- tests/language/properties.das | 14 +- tests/language/safe_ptr_at.das | 86 ++----- tests/language/serialization.das | 34 ++- tests/language/smart_ptr.das | 26 +-- tests/language/string_ops.das | 4 +- tests/language/test_rtti_init_mnh.das | 4 +- tests/language/to_array.das | 26 +-- tests/language/tuple.das | 16 +- tests/language/variant.das | 16 +- tests/linq/test_linq_fold.das | 146 ++++++------ tests/linq/test_linq_fold_order_family.das | 110 ++++----- tests/linq/test_linq_fold_terminal_select.das | 218 +++++++----------- .../test_linq_fold_theme2_trailing_where.das | 202 +++++++--------- ..._fold_theme3_c1_c5_distinct_order_take.das | 66 +++--- ..._linq_fold_theme3_c2_group_by_order_by.das | 56 +++-- ...est_linq_fold_theme3_decs_join_groupby.das | 108 ++++----- .../test_linq_fold_theme45_quick_wins.das | 162 ++++++------- ...test_linq_fold_theme6_decs_bridge_warn.das | 8 +- ..._fold_theme6_decs_bridge_warn_silenced.das | 6 +- .../test_linq_fold_theme8_fusion_arms.das | 68 +++--- tests/linq/test_linq_from_decs.das | 16 +- tests/linq/test_linq_table_source.das | 36 ++- .../test_dim_int64_indexing.das | 22 +- .../test_huge_array_iterate.das | 8 +- .../long_array_table/test_huge_temp_array.das | 10 +- .../long_array_table/test_long_iterators.das | 8 +- tests/match/all_matches.das | 4 +- tests/math/mat_let_handle.das | 6 +- tests/mcp/test_mcp_jsonrpc.das | 21 +- tests/mcp/test_popen_argv_pipe.das | 47 ++-- tests/module_tests/test_modules.das | 8 +- tests/network/test_client.das | 12 +- tests/stbimage/test_apng.das | 17 +- tests/strings/delete_strings.das | 20 +- tests/table_packed/test_packed.das | 18 +- tests/table_packed/test_packed_constkey.das | 10 +- tests/table_packed/test_packed_large.das | 16 +- tests/type_traits/test_iterator_variance.das | 6 +- tutorials/dasPUGIXML/05_linq_over_xml.das | 12 +- tutorials/language/22_unsafe.das | 24 +- tutorials/language/36_pointers.das | 46 ++-- tutorials/language/44_compile_and_run.das | 28 +-- tutorials/language/44_helper.das | 4 +- tutorials/language/45_debug_agents.das | 30 +-- tutorials/language/47_data_walker.das | 60 ++--- tutorials/macros/structure_macro_mod.das | 24 +- utils/benchctl/utils.das | 12 +- utils/dap/dap_bridge.das | 6 +- utils/das-fmt/dasfmt.das | 16 +- utils/dasllama-server/model_catalog.das | 4 +- utils/daspkg/index.das | 20 +- utils/daspkg/test_daspkg.das | 4 +- utils/jobque-timeline/tl_launch.das | 16 +- utils/jobque-timeline/tl_loader.das | 5 +- .../lint/tests/style024_redundant_unsafe.das | 6 +- .../tests/style025_unsafe_block_narrow.das | 11 + utils/mcp/mcp_core.das | 4 +- utils/mcp/protocol_core.das | 2 +- utils/mcp/tools/grep_usage.das | 24 +- utils/mcp/tools/outline.das | 20 +- 216 files changed, 1930 insertions(+), 3241 deletions(-) create mode 100644 doc/source/stdlib/handmade/function-ast-_dot__rq_isSafeToDelete-0x39575a71bd440d4d.rst diff --git a/daslib/style_lint.das b/daslib/style_lint.das index 3808580e18..a76f64a2e3 100644 --- a/daslib/style_lint.das +++ b/daslib/style_lint.das @@ -113,6 +113,7 @@ class StyleLintVisitor : AstVisitor { compile_time_errors : bool comment_hygiene : bool = false ascii_strings : bool = false + with_module_is_unsafe : bool = false warning_count : int = 0 collect_warnings : bool = false warnings : array @@ -2680,6 +2681,7 @@ class StyleLintVisitor : AstVisitor { def override preVisitExprLet(expr : ExprLet?) : void { //! Mirror `isLocalOrGlobal` check from ast_infer_type.cpp:4989 — `let v & = E` requires unsafe at statement level when `E` is non-local-non-temporary. Mark the let's frame so the enclosing `unsafe { ... }` block can detect it (STYLE025 must stay silent when narrowing would leave the let-ref binding unsatisfied). if (expr.genFlags.generated) return + if (declaration_owns_unsafe(expr)) mark_unsafe_in_stack() for (v in expr.variables) { continue if ( v._type == null || @@ -2702,13 +2704,36 @@ class StyleLintVisitor : AstVisitor { } def override preVisitExprDelete(expr : ExprDelete?) : void { - if (!expr.genFlags.generated) mark_unsafe_in_stack() + if (expr.genFlags.generated) return + if (expr.subexpr == null || expr.subexpr._type == null || !expr.subexpr._type.isSafeToDelete) { + mark_unsafe_in_stack() + } } def is_lowered_unsafe_delete(expr : ExpressionPtr) : bool { return expr is ExprCall && lowered_unsafe_delete(expr as ExprCall) } + def variable_owns_unsafe(v : VariablePtr) : bool { + let vt = v._type + return false if (v.flags.generated || vt == null) + return ((!vt.flags.ref && (vt.hasClasses + || (vt.isStructure && vt.structType != null && vt.structType.flags.isClass))) + || (!vt.isLocal && !vt.isGoodBlockType) + || (vt.flags.smartPtr && !v.flags.inScope) + || (v.flags.inScope && vt.isPointer && vt.firstType != null + && vt.firstType.isStructure && vt.firstType.structType != null + && vt.firstType.structType.flags.isClass)) + } + + def declaration_owns_unsafe(expr : ExpressionPtr) : bool { + return false if (!(expr is ExprLet)) + for (v in (expr as ExprLet).variables) { + return true if (variable_owns_unsafe(v)) + } + return false + } + //! `unsafe(delete p)` does not parse, so a block holding a delete anywhere in it has no narrow //! form to offer, whichever of its statements the one unsafe operation turns out to be. def block_holds_delete(blk : ExprBlock?) : bool { @@ -2734,7 +2759,11 @@ class StyleLintVisitor : AstVisitor { def lowered_unsafe_delete(expr : ExprCall?) : bool { return false if (expr.func == null || length(expr.arguments) != 1) let fname = string(expr.func.name) - return (expr.func.flags.generated && fname == "finalize") || starts_with(fname, "builtin`finalize`") + let is_finalize = ((expr.func.flags.generated && fname == "finalize") + || starts_with(fname, "builtin`finalize`") || starts_with(fname, "builtin`finalize_dim`")) + return false if (!is_finalize) + let at = expr.arguments[0]._type + return at == null || !at.isSafeToDelete } def override preVisitExprAddr(expr : ExprAddr?) : void { @@ -2894,6 +2923,16 @@ class StyleLintVisitor : AstVisitor { } } + def is_module_with(expr : ExpressionPtr) : bool { + return expr is ExprWith && !empty((expr as ExprWith).moduleName) + } + + def override preVisitExprWith(var expr : ExprWith?) : void { + if (with_module_is_unsafe && !expr.genFlags.generated && !empty(expr.moduleName)) { + mark_unsafe_in_stack() + } + } + def override visitExprUnsafe(var expr : ExprUnsafe?) : ExpressionPtr { let n = length(unsafe_block_stack) if (n > 0) { @@ -2913,6 +2952,8 @@ class StyleLintVisitor : AstVisitor { blk.list[0] is ExprNew || blk.list[0] is ExprClone || is_lowered_unsafe_clone(blk.list[0]) || + declaration_owns_unsafe(blk.list[0]) || + is_module_with(blk.list[0]) || block_holds_delete(blk)) && !frame.has_non_local_let_ref) { var narrowable = true @@ -2998,6 +3039,7 @@ def public style_lint(prog : ProgramPtr; compile_time_errors : bool; disabled_co astVisitor.max_complexity = max_complexity_for(prog) astVisitor.max_function_length = max_function_length_for(prog) astVisitor.ascii_strings = ascii_strings_for(prog) + astVisitor.with_module_is_unsafe = (prog._options |> find_arg("with_module_is_unsafe")) ?as tBool ?? false astVisitor.this_module = prog.getThisModule let empty_enabled : table astVisitor.analyze_requires = astVisitor.this_module != null && require_analysis_enabled(disabled_codes, empty_enabled) @@ -3037,6 +3079,7 @@ def public style_lint_collect(prog : ProgramPtr; var warnings : array; astVisitor.max_complexity = max_complexity_for(prog) astVisitor.max_function_length = max_function_length_for(prog) astVisitor.ascii_strings = ascii_strings_for(prog) + astVisitor.with_module_is_unsafe = (prog._options |> find_arg("with_module_is_unsafe")) ?as tBool ?? false astVisitor.this_module = prog.getThisModule astVisitor.analyze_requires = astVisitor.this_module != null && require_analysis_enabled(disabled_codes, enabled_codes) make_visitor(*astVisitor) $(astVisitorAdapter) { @@ -3068,6 +3111,7 @@ def public style_lint_collect_issues(prog : ProgramPtr; var issues : array find_arg("with_module_is_unsafe")) ?as tBool ?? false astVisitor.this_module = prog.getThisModule astVisitor.analyze_requires = astVisitor.this_module != null && require_analysis_enabled(disabled_codes, enabled_codes) make_visitor(*astVisitor) $(astVisitorAdapter) { diff --git a/dastest/dastest.das b/dastest/dastest.das index 3c05f0a7a0..cb136e3410 100644 --- a/dastest/dastest.das +++ b/dastest/dastest.das @@ -703,7 +703,7 @@ def main() : int { // nolint:STYLE037,STYLE038 - CLI dispatch, one arm per mode bSingles |> push(build_iso_cmd([clone_string(file)], cmdPrefix, cmdSuffix)) } let bCmd = build_iso_cmd(bFiles, cmdPrefix, cmdSuffix) - unsafe { delete bFiles } + delete bFiles batches |> emplace(IsoInput(uris <- bUris, batchCmd = clone_string(bCmd), singleCmds <- bSingles)) bidx = hi } diff --git a/doc/source/reference/language/lint.rst b/doc/source/reference/language/lint.rst index 7d87667c8c..afe6b4c72a 100644 --- a/doc/source/reference/language/lint.rst +++ b/doc/source/reference/language/lint.rst @@ -2830,6 +2830,11 @@ unsafe, the block scope is too broad. Narrow it to the expression form ``unsafe()`` wrapping just the operation that requires it. When two or more statements need unsafe the block is justified and stays silent. +The rule also stays silent where no narrow form exists. A declaration owns its +own permission and ``unsafe()`` wraps an expression, so a stack-constructed +class local, a ``smart_ptr`` local without ``inscope``, and an ``inscope`` +local whose generated delete is unsafe all keep the block. + .. das-doc: alt .. code-block:: das diff --git a/doc/source/stdlib/handmade/function-ast-_dot__rq_isSafeToDelete-0x39575a71bd440d4d.rst b/doc/source/stdlib/handmade/function-ast-_dot__rq_isSafeToDelete-0x39575a71bd440d4d.rst new file mode 100644 index 0000000000..48e6f92f6a --- /dev/null +++ b/doc/source/stdlib/handmade/function-ast-_dot__rq_isSafeToDelete-0x39575a71bd440d4d.rst @@ -0,0 +1 @@ +Returns whether a value of the given type is safe to delete, meaning that deleting it does not require an unsafe block. Raw pointers to a typed value, blocks and lambdas are never safe to delete, and a structure, tuple, variant, array or table is safe only when everything it holds is. diff --git a/examples/debugapi/allocation_tracking.das b/examples/debugapi/allocation_tracking.das index fb039fe981..f634b582ff 100644 --- a/examples/debugapi/allocation_tracking.das +++ b/examples/debugapi/allocation_tracking.das @@ -173,10 +173,8 @@ def main() { // 4. Print summary — tracker lives in the agent context, // so we invoke our helper there via the named agent - unsafe { - invoke_in_context(get_debug_agent_context("alloc_tracker"), - "print_tracker_summary") - } + unsafe(invoke_in_context(get_debug_agent_context("alloc_tracker"), + "print_tracker_summary")) delete_debug_agent_context("alloc_tracker") } diff --git a/examples/debugapi/hw_breakpoint.das b/examples/debugapi/hw_breakpoint.das index 0e914880df..a01e768cc0 100644 --- a/examples/debugapi/hw_breakpoint.das +++ b/examples/debugapi/hw_breakpoint.das @@ -83,9 +83,7 @@ def demo_watch_int() { print(" after write: target = {target}\n") // Clear the breakpoint — further writes are silent - unsafe { - clear_hw_breakpoint(bp) - } + unsafe(clear_hw_breakpoint(bp)) print(" breakpoint cleared\n") target = 50 @@ -121,9 +119,7 @@ def demo_watch_struct_field() { pos.y = 3.0 print(" pos.y = {pos.y} (triggered again)\n") - unsafe { - clear_hw_breakpoint(bp) - } + unsafe(clear_hw_breakpoint(bp)) print(" breakpoint cleared\n") } @@ -136,9 +132,7 @@ def demo_watch_struct_field() { def watch_variable(var ctx : Context; data : void?; size : int; blk : block) { let bp = unsafe(set_hw_breakpoint(ctx, data, size, true)) invoke(blk) - unsafe { - clear_hw_breakpoint(bp) - } + unsafe(clear_hw_breakpoint(bp)) } def demo_scoped_breakpoint() { @@ -146,13 +140,11 @@ def demo_scoped_breakpoint() { var value = 100 - unsafe { - watch_variable(this_context(), addr(value), 4) { - value = 200 - print(" inside scope: value = {value}\n") - value = 300 - print(" inside scope: value = {value}\n") - } + watch_variable(this_context(), unsafe(addr(value)), 4) { + value = 200 + print(" inside scope: value = {value}\n") + value = 300 + print(" inside scope: value = {value}\n") } // After the scope, no breakpoint — writes are silent diff --git a/examples/debugapi/stack_walker.das b/examples/debugapi/stack_walker.das index 349257a164..0d79e20045 100644 --- a/examples/debugapi/stack_walker.das +++ b/examples/debugapi/stack_walker.das @@ -199,10 +199,8 @@ class DiagnosticAgent : DapiDebugAgent { def override onVariable(var ctx : Context; category, name : string; info : TypeInfo; data : void?) : void { - unsafe { - let value = sprint_data(data, addr(info), print_flags.singleLine) - print(" reported {category}: {name} = {value}\n") - } + let value = sprint_data(data, unsafe(addr(info)), print_flags.singleLine) + print(" reported {category}: {name} = {value}\n") } } diff --git a/examples/pathTracer/toy_path_tracer.das b/examples/pathTracer/toy_path_tracer.das index 60cf536d62..180e4e6a08 100644 --- a/examples/pathTracer/toy_path_tracer.das +++ b/examples/pathTracer/toy_path_tracer.das @@ -120,7 +120,5 @@ def main { // nolint:STYLE038 - one arm per Mode; the four tracing strategies pixels |> push <| RGBA_TO_UCOLOR(srgb) } } - unsafe { - stbi_write_png("{get_das_root()}/examples/pathTracer/path_tracer.png", width, height, 4, addr(pixels[0]), width * 4) - } + stbi_write_png("{get_das_root()}/examples/pathTracer/path_tracer.png", width, height, 4, unsafe(addr(pixels[0])), width * 4) } diff --git a/examples/pathTracer/toy_path_tracer_profile.das b/examples/pathTracer/toy_path_tracer_profile.das index 246ece6d95..4f2f2c6a24 100644 --- a/examples/pathTracer/toy_path_tracer_profile.das +++ b/examples/pathTracer/toy_path_tracer_profile.das @@ -39,8 +39,6 @@ def main { } } let path = "{get_das_root()}/examples/pathTracer/path_tracer.png" - unsafe { - stbi_write_png(path, width, height, 4, addr(pixels[0]), width * 4) - print("image saved to {path}\n") - } + stbi_write_png(path, width, height, 4, unsafe(addr(pixels[0])), width * 4) + print("image saved to {path}\n") } diff --git a/examples/vulkan/one_source_path_tracer/pt_reference.das b/examples/vulkan/one_source_path_tracer/pt_reference.das index 1004d6959a..cfba502bac 100644 --- a/examples/vulkan/one_source_path_tracer/pt_reference.das +++ b/examples/vulkan/one_source_path_tracer/pt_reference.das @@ -24,10 +24,7 @@ def main { accum |> resize(WIDTH * HEIGHT) let nThreads = get_total_hw_threads() let t0 = ref_time_ticks() - var pbb : array? - unsafe { - pbb = addr(accum) - } + var pbb = unsafe(addr(accum)) with_job_status(nThreads) $(status) { let chunk = (HEIGHT + nThreads - 1) / nThreads for (c in range(nThreads)) { @@ -56,8 +53,6 @@ def main { let b = uint(clamp(srgb.z, 0.0, 1.0) * 255.0 + 0.5) pixels |> push(r | (g << 8u) | (b << 16u) | 0xFF000000) } - unsafe { - stbi_write_png("pt_reference.png", WIDTH, HEIGHT, 4, addr(pixels[0]), WIDTH * 4) - } + stbi_write_png("pt_reference.png", WIDTH, HEIGHT, 4, unsafe(addr(pixels[0])), WIDTH * 4) print("wrote pt_reference.png\n") } diff --git a/modules/dasGlsl/glsl/glsl_internal.das b/modules/dasGlsl/glsl/glsl_internal.das index 26d16548d6..5a838ea1c0 100644 --- a/modules/dasGlsl/glsl/glsl_internal.das +++ b/modules/dasGlsl/glsl/glsl_internal.das @@ -429,9 +429,7 @@ class GlslExport : AstVisitor { inout_stub : string inout_decl : string def GlslExport(var w : StringBuilderWriter; sht : ShaderType; ver : int; cls : int3; cp : ShaderExportCaps) { - unsafe { - writer = addr(w) - } + writer = unsafe(addr(w)) shaderType = sht version = ver compute_local_size = cls @@ -661,9 +659,7 @@ class GlslExport : AstVisitor { def describe_subexpression(expr : ExpressionPtr) { let oldWriter = writer let st = build_string() $(var newWriter) { - unsafe { - writer = addr(newWriter) - } + writer = unsafe(addr(newWriter)) visit(expr, astVisitorAdapter) } writer = oldWriter @@ -1424,10 +1420,7 @@ class GlslExport : AstVisitor { *writer |> write("texture(") return } - var fnName : string - unsafe { - fnName = glsl_function_name(reinterpret(expr.func)) - } + var fnName = glsl_function_name(unsafe(reinterpret(expr.func))) // 16/8-bit lattice values crossing a call: ctors/converts are name-mapped below and user // functions declare through describe_glsl_type_ex — but the saturating narrows have no // GLSL builtin (clamp-expansion is a later wave) and CPU-only widths never emit. diff --git a/modules/dasHV/example/telnet.das b/modules/dasHV/example/telnet.das index 9fa5df2378..d1b6c79afe 100644 --- a/modules/dasHV/example/telnet.das +++ b/modules/dasHV/example/telnet.das @@ -35,19 +35,14 @@ class TelnetServer : Server { } def override onData(msg : uint8?; size : int) { for (i in range(size)) { - var ch : uint8 - unsafe { - ch = msg[i] - } + let ch = unsafe(msg[i]) let ich = int(ch) if (ich == '\r') { continue } elif (ich == '\n') { print("`{string(current_string)}` length={length(current_string)}\n") var new_msg = "length = {length(current_string)}\n" - unsafe { - self.send(reinterpret(new_msg), length(new_msg)) - } + self.send(unsafe(reinterpret(new_msg)), length(new_msg)) var str = string(current_string) if (str == "quit") { done = true diff --git a/modules/dasLLAMA/REVIEW.das b/modules/dasLLAMA/REVIEW.das index 7be1539625..0827c6dc8d 100644 --- a/modules/dasLLAMA/REVIEW.das +++ b/modules/dasLLAMA/REVIEW.das @@ -546,7 +546,7 @@ let private TTS_BLOCKS_FILE = "modules/dasLLAMA/dasllama/dasllama_tts_blocks.das // lines, hashed in file order. A closure change with IMAGE_VERSION unmoved is red; the finding prints the // value to re-stamp with. let private IMAGE_LAYOUT_STAMP_VERSION = 38 -let private IMAGE_LAYOUT_STAMP_HASH = 0xb3ed0680a8048a57ul +let private IMAGE_LAYOUT_STAMP_HASH = 0x745d5e7db3dc10c5ul // The helpers that decide WHERE bytes land: the page pad, the plane and total sizing, the // writer's append / zero-fill / header patch, and the header's scalar stores. Changing one diff --git a/modules/dasLLAMA/benchmarks/setup_lcpp_ref.das b/modules/dasLLAMA/benchmarks/setup_lcpp_ref.das index 379c7426e9..7374c8dc11 100644 --- a/modules/dasLLAMA/benchmarks/setup_lcpp_ref.das +++ b/modules/dasLLAMA/benchmarks/setup_lcpp_ref.das @@ -43,13 +43,11 @@ struct Args { // Run `cmd`, return its trimmed stdout (pipe-safe fread; stderr stays on the console). def private capture_out(cmd : string) : string { var out = "" - unsafe { - popen(cmd) $(f) { - if (f != null) { // popen returns null on spawn failure (missing git / bad PATH) — don't deref - out = fread(f) - } + unsafe(popen(cmd) $(f) { + if (f != null) { // popen returns null on spawn failure (missing git / bad PATH) — don't deref + out = fread(f) } - } + }) return strip(out) } diff --git a/modules/dasLLAMA/dasllama/dasllama_arch_qwen35.das b/modules/dasLLAMA/dasllama/dasllama_arch_qwen35.das index a72ce7fcd0..6f998ae829 100644 --- a/modules/dasLLAMA/dasllama/dasllama_arch_qwen35.das +++ b/modules/dasLLAMA/dasllama/dasllama_arch_qwen35.das @@ -887,33 +887,27 @@ def private attention_qwen35_gated_prefill(t : Model; var s : Session; l : int64 let vtq4 = s.kv_dtype_v == KVDtype.tq4 if (ktq4 || vtq4) { // tq4 basis change (attention_std_prefill's twin); xb_b un-rotates below let ts_rot = prof_ticks() - unsafe { - let sgp = addr < float const? >(s.kv_signs[0]) - if (ktq4) { - tq4_rotate_batch(s.q_b, npos, qd, head_size, sgp) - tq4_rotate_batch(s.k_b, npos, kv_dim, head_size, sgp) - } - if (vtq4) { - tq4_rotate_batch(s.v_b, npos, kv_dim, head_size, sgp) - } + let sgp = unsafe(addr < float const? >(s.kv_signs[0])) + if (ktq4) { + tq4_rotate_batch(s.q_b, npos, qd, head_size, sgp) + tq4_rotate_batch(s.k_b, npos, kv_dim, head_size, sgp) + } + if (vtq4) { + tq4_rotate_batch(s.v_b, npos, kv_dim, head_size, sgp) } prof_add("tq4_rot", ts_rot) } let ts_kv = prof_ticks() let store_nrun = kv_runs(s, start_pos, start_pos + npos, s.kv_runs) - unsafe { - kv_store_batch(kcl, vcl, s.kv_dtype_k, s.kv_dtype_v, s.k_b, s.v_b, - addr < KVRun const? >(s.kv_runs[0]), store_nrun, start_pos, npos, kv_dim) - } + kv_store_batch(kcl, vcl, s.kv_dtype_k, s.kv_dtype_v, s.k_b, s.v_b, + unsafe(addr < KVRun const? >(s.kv_runs[0])), store_nrun, start_pos, npos, kv_dim) prof_add("kv_store", ts_kv) let ts_attn = prof_ticks() prefill_attention(s, kcl, vcl, npos, start_pos, head_size, qd, kv_dim, n_heads, kv_mul, scale, false, 0l, c.attn_logit_softcap, null) prof_add("attn", ts_attn) if (vtq4) { // un-rotate every position's xb before the out-gate (gate is in the original basis) - unsafe { - tq4_unrotate_batch(s.xb_b, npos, qd, head_size, addr < float const? >(s.kv_signs[0])) - } + tq4_unrotate_batch(s.xb_b, npos, qd, head_size, unsafe(addr < float const? >(s.kv_signs[0]))) } // threaded + exp4: serial scalar loop was npos·qd (2.1M @pp512) libm exps, ~10ms all-lane hole/layer let ts_gate = prof_ticks() diff --git a/modules/dasLLAMA/dasllama/dasllama_batch.das b/modules/dasLLAMA/dasllama/dasllama_batch.das index c110f197e5..f036fdaa17 100644 --- a/modules/dasLLAMA/dasllama/dasllama_batch.das +++ b/modules/dasLLAMA/dasllama/dasllama_batch.das @@ -90,18 +90,16 @@ def private attention_batch_decode(t : Model; var ws : BatchWorkspace; sessions if (ktq4 || vtq4) { // tq4 basis change at the RoPE seam (see attention_std_decode); xb_b un-rotates below let ts_rot = prof_ticks() - unsafe { - let sgp = addr < float const? >(ws.scr.kv_signs[0]) - if (ktq4) { - tq4_rotate_batch(ws.scr.q_b, nrows, qd, head_size, sgp) - if (!kv_shared) { - tq4_rotate_batch(ws.scr.k_b, nrows, kv_dim, head_size, sgp) - } - } - if (vtq4 && !kv_shared) { - tq4_rotate_batch(ws.scr.v_b, nrows, kv_dim, head_size, sgp) + let sgp = unsafe(addr < float const? >(ws.scr.kv_signs[0])) + if (ktq4) { + tq4_rotate_batch(ws.scr.q_b, nrows, qd, head_size, sgp) + if (!kv_shared) { + tq4_rotate_batch(ws.scr.k_b, nrows, kv_dim, head_size, sgp) } } + if (vtq4 && !kv_shared) { + tq4_rotate_batch(ws.scr.v_b, nrows, kv_dim, head_size, sgp) + } prof_add("tq4_rot", ts_rot) } if (kdt == KVDtype.q8_0 || ktq4) { @@ -176,9 +174,7 @@ def private attention_batch_decode(t : Model; var ws : BatchWorkspace; sessions } prof_add("attn", ts_attn) if (vtq4) { // tq4 V: xb_b rows accumulated in the rotated basis — un-rotate per (row, head) - unsafe { - tq4_unrotate_batch(ws.scr.xb_b, nrows, qd, head_size, addr < float const? >(ws.scr.kv_signs[0])) - } + tq4_unrotate_batch(ws.scr.xb_b, nrows, qd, head_size, unsafe(addr < float const? >(ws.scr.kv_signs[0]))) } attn_out_suffix(t, ws.scr, l, nrows) } @@ -234,10 +230,8 @@ def verify_batch_step(t : Model; var ws : BatchWorkspace; var s : Session; token return false } g_verify_sessions |> grow_resize(nrows) - unsafe { - for (i in range64(nrows)) { - g_verify_sessions[i] = addr(s) - } + for (i in range64(nrows)) { + g_verify_sessions[i] = unsafe(addr(s)) } ws.scr.kv_dtype_k = s.kv_dtype_k ws.scr.kv_dtype_v = s.kv_dtype_v diff --git a/modules/dasLLAMA/dasllama/dasllama_common.das b/modules/dasLLAMA/dasllama/dasllama_common.das index 88bc6e4591..544c7094b2 100644 --- a/modules/dasLLAMA/dasllama/dasllama_common.das +++ b/modules/dasLLAMA/dasllama/dasllama_common.das @@ -2496,9 +2496,7 @@ def eval_(t : Model; var s : Session; tokens : array) { var private g_tensor_crowns : table def public set_metal_tensor_crowns(list : string) { - unsafe { - delete g_tensor_crowns - } + delete g_tensor_crowns for (f in split(list, ",")) { if (!empty(f)) { g_tensor_crowns |> insert(f) diff --git a/modules/dasLLAMA/dasllama/dasllama_image.das b/modules/dasLLAMA/dasllama/dasllama_image.das index ee7f223983..e45d64449d 100644 --- a/modules/dasLLAMA/dasllama/dasllama_image.das +++ b/modules/dasLLAMA/dasllama/dasllama_image.das @@ -427,9 +427,7 @@ def w_append(var w : ImgWriter; p : void?; nbytes : uint64) { w.ok = false return } - unsafe { - memcpy(mem_at(w.chunk_base, w.cur), p, nbytes) - } + unsafe(memcpy(mem_at(w.chunk_base, w.cur), p, nbytes)) } elif (!unsafe(dwrite_append(w.dwrite_h, p, nbytes))) { w.ok = false // a dead save stays dead — don't keep pushing bytes at a full disk return @@ -444,9 +442,7 @@ def w_zeros(var w : ImgWriter; n : uint64) { var z : array z |> reserve(int64(n)) z |> resize(int64(n)) - unsafe { - w_append(w, addr(z[0]), n) - } + w_append(w, unsafe(addr(z[0])), n) delete z } @@ -602,9 +598,7 @@ def serialize_strings(var arch : Archive; var a : array) { var at = 0 for (n, s in lens, a) { if (n > 0) { - unsafe { - s = string(temp_array(addr(blob[at]), n, type)) - } + s = string(unsafe(temp_array(unsafe(addr(blob[at])), n, type))) } else { s = "" } @@ -1432,9 +1426,7 @@ def private write_metal_blob_plane(var t : Model; var w : ImgWriter; var section while (b0 < sh.blocks && w.ok) { let n = min(METAL_BAND_BLOCKS, sh.blocks - b0) metal_blob_fill_blocks(t, b0, n, band) - unsafe { - w_append(w, addr(band[0]), uint64(n * sh.stride)) - } + w_append(w, unsafe(addr(band[0])), uint64(n * sh.stride)) b0 += n } delete band diff --git a/modules/dasLLAMA/dasllama/dasllama_kv_codec.das b/modules/dasLLAMA/dasllama/dasllama_kv_codec.das index 42dfc43e52..da326ddbe2 100644 --- a/modules/dasLLAMA/dasllama/dasllama_kv_codec.das +++ b/modules/dasLLAMA/dasllama/dasllama_kv_codec.das @@ -393,19 +393,13 @@ def kv_head_off(p : TQ4B const?; elems : int64) : int64 => elems / 32l * 18l // Bulk one-row dequant into f32 scratch — the flash pack's per-row primitive (and any future // codec's bulk-dequant seam: q8_0 adds a cvt overload here, never a new pack shape). def kv_row_to_f32(var d : float?; p : float const?; base, n : int64) { - unsafe { - copy_floats(d, p + base, n) - } + copy_floats(d, unsafe(p + base), n) } def kv_row_to_f32(var d : float?; p : uint16 const?; base, n : int64) { - unsafe { - cvt_f16_to_f32(d, p + base, n) - } + cvt_f16_to_f32(d, unsafe(p + base), n) } def kv_row_to_f32(var d : float?; p : uint8 const?; base, n : int64) { - unsafe { - cvt_q8kv_to_f32(d, p + base, n) - } + cvt_q8kv_to_f32(d, unsafe(p + base), n) } def kv_row_to_f32(var d : float?; p : TQ4B const?; base, n : int64) { unsafe { diff --git a/modules/dasLLAMA/dasllama/dasllama_load.das b/modules/dasLLAMA/dasllama/dasllama_load.das index 0c8afa2719..9c686a6dea 100644 --- a/modules/dasLLAMA/dasllama/dasllama_load.das +++ b/modules/dasLLAMA/dasllama/dasllama_load.das @@ -896,9 +896,7 @@ def private stream_zero_fill(gap : int64; var zeros : array; } while (left > 0l) { let chunk = min(left, long_length(zeros)) - unsafe { - invoke(append, addr(zeros[0]), uint64(chunk)) - } + invoke(append, unsafe(addr(zeros[0])), uint64(chunk)) left -= chunk } } diff --git a/modules/dasLLAMA/dasllama/dasllama_moe.das b/modules/dasLLAMA/dasllama/dasllama_moe.das index bad9e2dc59..5e3eaab7b3 100644 --- a/modules/dasLLAMA/dasllama/dasllama_moe.das +++ b/modules/dasLLAMA/dasllama/dasllama_moe.das @@ -481,11 +481,9 @@ def moe_experts_apply(t : Model; var s : Session; l : int64) { // nolint:STYLE03 } if (s.tail_next1 == l + 1l) { s.tail_next1 = 0l - unsafe { - matmul_moe_gpu_ffn_tail(s.moe_offs1, s.moe_offs3, s.moe_offs2, k, s.moe_gxq, s.moe_gxs, dim, nfe, k, - int(f1), int(f3), int(f2), c.ffn_act == FfnAct.gelu, s.moe_w, s.x, t.wq_offs[l + 1l], int(fmt_at(t.wq_fmt, l + 1l)), - addr(t.fblob[t.rms_att_off + (l + 1l) * dim]), c.norm_eps) - } + matmul_moe_gpu_ffn_tail(s.moe_offs1, s.moe_offs3, s.moe_offs2, k, s.moe_gxq, s.moe_gxs, dim, nfe, k, + int(f1), int(f3), int(f2), c.ffn_act == FfnAct.gelu, s.moe_w, s.x, t.wq_offs[l + 1l], int(fmt_at(t.wq_fmt, l + 1l)), + unsafe(addr(t.fblob[t.rms_att_off + (l + 1l) * dim])), c.norm_eps) s.tail_taken = true moe_chained = true } else { diff --git a/modules/dasLLAMA/dasllama/dasllama_mtp_gemma.das b/modules/dasLLAMA/dasllama/dasllama_mtp_gemma.das index 5ce3bde26e..057b376423 100644 --- a/modules/dasLLAMA/dasllama/dasllama_mtp_gemma.das +++ b/modules/dasLLAMA/dasllama/dasllama_mtp_gemma.das @@ -463,9 +463,7 @@ def private drafter_attention(t : Model; var s : Session; dr : GemmaDrafter; l, let sub = (hq / kv_mul) * hs for (j in range64(lo, anchor)) { let prow = kv_phys_row(s, j) - unsafe { - kv_load_row(kcl, s.kv_dtype_k, kv_dim, prow, sub, hs, addr(kvrow[0])) - } + kv_load_row(kcl, s.kv_dtype_k, kv_dim, prow, sub, hs, unsafe(addr(kvrow[0]))) var acc = 0.0 for (i in range64(hs)) { acc += q[qoff + i] * kvrow[i] @@ -478,9 +476,7 @@ def private drafter_attention(t : Model; var s : Session; dr : GemmaDrafter; l, } for (j in range64(lo, anchor)) { let prow = kv_phys_row(s, j) - unsafe { - kv_load_row(vcl, s.kv_dtype_v, kv_dim, prow, sub, hs, addr(kvrow[0])) - } + kv_load_row(vcl, s.kv_dtype_v, kv_dim, prow, sub, hs, unsafe(addr(kvrow[0]))) let w = scores[j - lo] for (i in range64(hs)) { attn[qoff + i] += w * kvrow[i] diff --git a/modules/dasLLAMA/dasllama/dasllama_pocket.das b/modules/dasLLAMA/dasllama/dasllama_pocket.das index e375084135..5fc06e1b95 100644 --- a/modules/dasLLAMA/dasllama/dasllama_pocket.das +++ b/modules/dasLLAMA/dasllama/dasllama_pocket.das @@ -1189,9 +1189,7 @@ def pocket_synthesize(m : PocketModel; ids : array; var vs : PocketVoiceS let n_txt = long_length(ids) let clock = ref_time_ticks() caches_ready(vs, n_txt) - unsafe { - scratch_resize(sc.rows, n_txt * d) - } + unsafe(scratch_resize(sc.rows, n_txt * d)) for (r in range64(n_txt)) { let src = ids[r] * d for (j in range64(d)) { diff --git a/modules/dasLLAMA/dasllama/dasllama_rope.das b/modules/dasLLAMA/dasllama/dasllama_rope.das index c1cb6abc9d..6390a7f1ab 100644 --- a/modules/dasLLAMA/dasllama/dasllama_rope.das +++ b/modules/dasLLAMA/dasllama/dasllama_rope.das @@ -23,9 +23,7 @@ require math def private rope_freq_j(j, head_size : int64; theta : float; ffp : float const?) : float { var freq = 1.0 / pow(theta, float(2l * j) / float(head_size)) if (ffp != null) { - unsafe { - freq /= ffp[j] - } + freq /= unsafe(ffp[j]) } return freq } diff --git a/modules/dasLLAMA/dasllama/dasllama_tts_blocks.das b/modules/dasLLAMA/dasllama/dasllama_tts_blocks.das index 2e68a80888..a71bd9c7bc 100644 --- a/modules/dasLLAMA/dasllama/dasllama_tts_blocks.das +++ b/modules/dasLLAMA/dasllama/dasllama_tts_blocks.das @@ -62,9 +62,7 @@ def bind_span(blob : PlaneF; span : TtsSpan; var a : array) { //! Forget a borrowed view or delete an owned buffer - the one teardown for a weight array. def release_weight(var a : array) { if (lock_count(a) != 0) { - unsafe { - _builtin_forget_temp_array(a) - } + unsafe(_builtin_forget_temp_array(a)) } else { delete a } @@ -117,9 +115,7 @@ def bind_span_q8(qplane : PlaneI8; span : TtsSpan; var a : array) { //! `release_weight` for an int8 quant array. def release_weight_q8(var a : array) { if (lock_count(a) != 0) { - unsafe { - _builtin_forget_temp_array(a) - } + unsafe(_builtin_forget_temp_array(a)) } else { delete a } @@ -138,9 +134,7 @@ def weight_slot_q8(var io : TtsBlobIo; var a : array; var span : TtsSpan) //! `release_weight` for a byte plane (a K-quant quant or scale plane). def release_weight_u8(var a : array) { if (lock_count(a) != 0) { - unsafe { - _builtin_forget_temp_array(a) - } + unsafe(_builtin_forget_temp_array(a)) } else { delete a } @@ -1019,9 +1013,7 @@ def private conv1d_rows_dense_q8(c : TtsConv1d; x : array; t_in : int64; } } } - unsafe { - invoke(g_mm_q8q8_batch, yp + r0 * cout, wqp, wsp, xstp, xssp, kc, cout, rows) - } + invoke(g_mm_q8q8_batch, unsafe(yp + r0 * cout), wqp, wsp, xstp, xssp, kc, cout, rows) if (nbias > 0l) { maybe_parallel_for(0, int(rows), lanes_for_work(rows * cout, 0)) $(rb, re) { unsafe { diff --git a/modules/dasLLAMA/dasllama/dasllama_whisper.das b/modules/dasLLAMA/dasllama/dasllama_whisper.das index 152231df1d..c0d99fddf4 100644 --- a/modules/dasLLAMA/dasllama/dasllama_whisper.das +++ b/modules/dasLLAMA/dasllama/dasllama_whisper.das @@ -1536,11 +1536,9 @@ def private whisper_force_ts_rule(w : WhisperModel; var logits : array) { // filter suite and the force-timestamp rule (plog = logit − this) def private logits_lse(logits : array) : float { let n = long_length(logits) - unsafe { - let p = addr(logits[0]) - let m = hmax(p, n) - return log(exp_sum4(p, n, m)) + m - } + let p = unsafe(addr(logits[0])) + let m = hmax(p, n) + return log(exp_sum4(p, n, m)) + m } // greedy argmax over all filtered logits + argmax over the timestamp region (tid); plog uses @@ -1576,11 +1574,9 @@ def private sample_greedy(w : WhisperModel; logits : array; lse : float) // reads p[nosp] off the prompt decode before any filtering def private token_prob(logits : array; id : int) : float { let n = long_length(logits) - unsafe { - let p = addr(logits[0]) - let m = hmax(p, n) - return exp(logits[id] - m) / exp_sum4(p, n, m) - } + let p = unsafe(addr(logits[0])) + let m = hmax(p, n) + return exp(logits[id] - m) / exp_sum4(p, n, m) } // Build and emit one segment off toks[i0..i1) at [t0, t1] — text = concat of the text-range diff --git a/modules/dasLLAMA/harness/batch_rows_probe.das b/modules/dasLLAMA/harness/batch_rows_probe.das index 315d9b0879..d545b6ebde 100644 --- a/modules/dasLLAMA/harness/batch_rows_probe.das +++ b/modules/dasLLAMA/harness/batch_rows_probe.das @@ -95,9 +95,7 @@ def private time_rows(t : Model; prompt : array; nb, steps : int64; sames ptrs |> reserve(nb) cur |> reserve(nb) for (i in range64(nb)) { - unsafe { - ptrs |> push(addr(sess[i])) - } + ptrs |> push(unsafe(addr(sess[i]))) cur |> push(prompt[i % long_length(prompt)]) } var t0 = 0l diff --git a/modules/dasLLAMA/harness/dasllama_tuner.das b/modules/dasLLAMA/harness/dasllama_tuner.das index c64015e160..6e03961e51 100644 --- a/modules/dasLLAMA/harness/dasllama_tuner.das +++ b/modules/dasLLAMA/harness/dasllama_tuner.das @@ -135,20 +135,18 @@ def private run_half(name : string; paranoid : bool) : bool { print("dasllama_tuner: {cmd}\n") var rc : int var noiseRefused = false - unsafe { - rc = popen_timeout(full, 3600.0) $(f) { - if (f == null) { - return - } - while (!feof(f)) { - let ln = fgets(f) - if (find(ln, "NOISE GATE") >= 0) { - noiseRefused = true - } - print(ln) + rc = unsafe(popen_timeout(full, 3600.0) $(f) { + if (f == null) { + return + } + while (!feof(f)) { + let ln = fgets(f) + if (find(ln, "NOISE GATE") >= 0) { + noiseRefused = true } + print(ln) } - } + }) let elapsed_ms = get_time_usec(t0) / 1000 g_half_ms[name] = elapsed_ms print("dasllama_tuner: {name} finished in {elapsed_ms} ms (rc={rc})\n") diff --git a/modules/dasLLAMA/harness/tune_kernels.das b/modules/dasLLAMA/harness/tune_kernels.das index 03fa7e8fd7..3765a5c8f0 100644 --- a/modules/dasLLAMA/harness/tune_kernels.das +++ b/modules/dasLLAMA/harness/tune_kernels.das @@ -118,9 +118,7 @@ def private aligned_f32(@scratch var arr : array; n : int64) : float? { var p = unsafe(addr(arr[0])) let mis = int64(unsafe(reinterpret(p)) & uint64(PROBE_ALIGN - 1l)) if (mis != 0l) { - unsafe { - p = p + (PROBE_ALIGN - mis) / 4l - } + p = unsafe(p + (PROBE_ALIGN - mis) / 4l) } return p } @@ -131,17 +129,13 @@ let STREAM_STAGGER = (4096l + 64l) / 4l // floats: 4KB + one cache line // one bench never share a page offset - the same geometry every run, and not the all-aliased one def private aligned_stream(@scratch var arr : array; n : int64; slot : int) : float? { var p = aligned_f32(arr, n + STREAM_STAGGER * 8l) - unsafe { - p = p + STREAM_STAGGER * int64(slot) - } + p = unsafe(p + STREAM_STAGGER * int64(slot)) return p } def private reset_stream(var dp : float?; d0 : array) { - unsafe { - for (j in range64(length(d0))) { - dp[j] = d0[j] - } + for (j in range64(length(d0))) { + unsafe(dp[j]) = d0[j] } } @@ -743,10 +737,8 @@ def bench_binary(kernel : string; vs : array>; var inscope sb : array var dp = aligned_stream(db, N, 0) var sp = aligned_stream(sb, N, 1) - unsafe { - for (j in range64(N)) { - sp[j] = s[j] - } + for (j in range64(N)) { + unsafe(sp[j]) = s[j] } var inscope names : array @@ -1977,10 +1969,8 @@ def bench_quantize() : string { let f = vs[i]._1 let t0 = ref_time_ticks() for (_rep in range(reps_of(i) / REPS_BASE)) { // whole walks: the window is sized in walks - unsafe { - for (p in range64(npos)) { - invoke(f, srcp + p * N, N, qp, sp, p * N, p * nb) - } + for (p in range64(npos)) { + invoke(f, unsafe(srcp + p * N), N, qp, sp, p * N, p * nb) } } record_sample(round, i, double(get_time_usec(t0)), best) @@ -2186,10 +2176,8 @@ def bench_gemm_tile() : string { for (i in range(nv)) { names[i] = vs[i]._0 best[i] = 1.0e30lf - unsafe { - for (j in range64(4l * NN)) { - cp[j] = 0.0f - } + for (j in range64(4l * NN)) { + unsafe(cp[j]) = 0.0f } let f = vs[i]._1 invoke(f, cp, ap, bp, 0l, 0l, K, NN) diff --git a/modules/dasLLAMA/performance/box_ident.das b/modules/dasLLAMA/performance/box_ident.das index 7495b3b23e..8037d88167 100644 --- a/modules/dasLLAMA/performance/box_ident.das +++ b/modules/dasLLAMA/performance/box_ident.das @@ -38,14 +38,12 @@ def private box_from_cpu(cpu : string) : string { def private capture_line(cmd : string) : string { var out = "" - unsafe { - popen(cmd) $(f) { - if (f != null) { - let ln = fgets(f) - out = strip(ln) - } + unsafe(popen(cmd) $(f) { + if (f != null) { + let ln = fgets(f) + out = strip(ln) } - } + }) return out } diff --git a/modules/dasLLAMA/performance/coopmat_mulmm_port.das b/modules/dasLLAMA/performance/coopmat_mulmm_port.das index 38c614a673..caca1be727 100644 --- a/modules/dasLLAMA/performance/coopmat_mulmm_port.das +++ b/modules/dasLLAMA/performance/coopmat_mulmm_port.das @@ -248,17 +248,13 @@ def private staging_roundtrip(var device : Device; phys : VkPhysicalDevice; var run_cmd_sync(device, pool, queue) $(cmd) { var region : VkBufferCopy region.size = uint64(db.bytes) - unsafe { - vkCmdCopyBuffer(boost_value_to_vk(cmd), boost_value_to_vk(stage), boost_value_to_vk(db.buf), 1u, addr(region)) - } + vkCmdCopyBuffer(boost_value_to_vk(cmd), boost_value_to_vk(stage), boost_value_to_vk(db.buf), 1u, unsafe(addr(region))) } } else { run_cmd_sync(device, pool, queue) $(cmd) { var region : VkBufferCopy region.size = uint64(db.bytes) - unsafe { - vkCmdCopyBuffer(boost_value_to_vk(cmd), boost_value_to_vk(db.buf), boost_value_to_vk(stage), 1u, addr(region)) - } + vkCmdCopyBuffer(boost_value_to_vk(cmd), boost_value_to_vk(db.buf), boost_value_to_vk(stage), 1u, unsafe(addr(region))) } unsafe { vk_check(vkMapMemory(boost_value_to_vk(device), boost_value_to_vk(smem), 0ul, uint64(db.bytes), mf, addr(mapped)), null) diff --git a/modules/dasLLAMA/performance/coopmat_mulmm_reference.das b/modules/dasLLAMA/performance/coopmat_mulmm_reference.das index 4a1ffa4f84..a2a0610850 100644 --- a/modules/dasLLAMA/performance/coopmat_mulmm_reference.das +++ b/modules/dasLLAMA/performance/coopmat_mulmm_reference.das @@ -108,17 +108,13 @@ def private staging_roundtrip(var device : Device; phys : VkPhysicalDevice; var run_cmd_sync(device, pool, queue) $(cmd) { var region : VkBufferCopy region.size = uint64(db.bytes) - unsafe { - vkCmdCopyBuffer(boost_value_to_vk(cmd), boost_value_to_vk(stage), boost_value_to_vk(db.buf), 1u, addr(region)) - } + vkCmdCopyBuffer(boost_value_to_vk(cmd), boost_value_to_vk(stage), boost_value_to_vk(db.buf), 1u, unsafe(addr(region))) } } else { run_cmd_sync(device, pool, queue) $(cmd) { var region : VkBufferCopy region.size = uint64(db.bytes) - unsafe { - vkCmdCopyBuffer(boost_value_to_vk(cmd), boost_value_to_vk(db.buf), boost_value_to_vk(stage), 1u, addr(region)) - } + vkCmdCopyBuffer(boost_value_to_vk(cmd), boost_value_to_vk(db.buf), boost_value_to_vk(stage), 1u, unsafe(addr(region))) } unsafe { vk_check(vkMapMemory(boost_value_to_vk(device), boost_value_to_vk(smem), 0ul, uint64(db.bytes), mf, addr(mapped)), null) diff --git a/modules/dasLLAMA/tests/test_deltanet.das b/modules/dasLLAMA/tests/test_deltanet.das index d48d107e53..dc7d089d15 100644 --- a/modules/dasLLAMA/tests/test_deltanet.das +++ b/modules/dasLLAMA/tests/test_deltanet.das @@ -182,9 +182,7 @@ def test_deltanet_owner_release(t : T?) { let c = small_deltanet_config() var s <- make_run_state(c) var lo = 0ul - unsafe { - lo = intptr(addr(s.dn_state[0])) - } + lo = intptr(unsafe(addr(s.dn_state[0]))) let hi = lo + uint64(long_length(s.dn_state) * 4l) t |> equal(s.dn_owner.state_lo, lo, "the token's low bound is the state's host address") t |> equal(s.dn_owner.state_hi, hi, "the token's high bound is the state's end") diff --git a/modules/dasLLAMA/tests/test_repack.das b/modules/dasLLAMA/tests/test_repack.das index f6c56a18fd..bd10980eb2 100644 --- a/modules/dasLLAMA/tests/test_repack.das +++ b/modules/dasLLAMA/tests/test_repack.das @@ -67,11 +67,9 @@ def test_extractors(t : T?) { row[int(js * 32l + i)] = uint8(lo | (hi << 4u)) } } - unsafe { - let rp = addr(row[0]) - for (k in range64(128l)) { - t |> equal(int(k45_nib(rp, k)), int(k % 16l)) - } + let rp = unsafe(addr(row[0])) + for (k in range64(128l)) { + t |> equal(int(k45_nib(rp, k)), int(k % 16l)) } } t |> run("k5_hbit reads the ggml k5 qh packing") @(t : T?) { @@ -91,11 +89,9 @@ def test_extractors(t : T?) { } qh[int(i)] = uint8(b) } - unsafe { - let hp = addr(qh[0]) - for (k in range64(128l)) { - t |> equal(int(k5_hbit(hp, k)), int((k * 7l + 3l) & 1l)) - } + let hp = unsafe(addr(qh[0])) + for (k in range64(128l)) { + t |> equal(int(k5_hbit(hp, k)), int((k * 7l + 3l) & 1l)) } } t |> run("k6_nib reads the ggml k6 ql packing") @(t : T?) { @@ -117,11 +113,9 @@ def test_extractors(t : T?) { } } } - unsafe { - let rp = addr(row[0]) - for (k in range64(256l)) { - t |> equal(int(k6_nib(rp, k)), int((k * 5l + 1l) % 16l)) - } + let rp = unsafe(addr(row[0])) + for (k in range64(256l)) { + t |> equal(int(k6_nib(rp, k)), int((k * 5l + 1l) % 16l)) } } } diff --git a/modules/dasLLAMA/tests/test_repack_lane_context.das b/modules/dasLLAMA/tests/test_repack_lane_context.das index fb2a629473..e9d9b37684 100644 --- a/modules/dasLLAMA/tests/test_repack_lane_context.das +++ b/modules/dasLLAMA/tests/test_repack_lane_context.das @@ -55,10 +55,8 @@ def test_repack_slot_is_context_proof(t : T?) { var dp = addr(done) parallel_for(0, 1, 1) $(rb, re, wg) { feint("{rb} {re}") - unsafe { - invoke(rq8, qp, sp, n, d) - dp[0] = 1 - } + invoke(rq8, qp, sp, n, d) + unsafe(dp[0]) = 1 wg |> notify_and_release } t |> equal(done, 1) diff --git a/modules/dasLLAMA/tests/test_rope_apply.das b/modules/dasLLAMA/tests/test_rope_apply.das index b608213b61..a9722637a5 100644 --- a/modules/dasLLAMA/tests/test_rope_apply.das +++ b/modules/dasLLAMA/tests/test_rope_apply.das @@ -268,9 +268,7 @@ def private part_gate(t : T?; pos, hs, rot, nh : int64; theta, fscale, mscale : ref_neox(v, want, pos, hs, rot, n, theta, fscale, mscale, ff, false) var got : array copy_vec(v, got, n) - unsafe { - rope_scaled_neox_part(addr(got[0]), pos, hs, rot, n, theta, fscale, false, null, mscale) - } + rope_scaled_neox_part(unsafe(addr(got[0])), pos, hs, rot, n, theta, fscale, false, null, mscale) cmp_bar(t, got, want, n, ROPE_BAR, "rope_scaled_neox_part hs={int(hs)} rot={int(rot)} pos={int(pos)}") var compact : array compact |> resize(nh * rot) @@ -314,9 +312,7 @@ def private tab_part_gate(t : T?; pos, hs, rot, nh : int64; theta, fscale, mscal ref_neox(v, want, pos, hs, rot, n, theta, fscale, mscale, ff, false) var direct : array copy_vec(v, direct, n) - unsafe { - rope_scaled_neox_part(addr(direct[0]), pos, hs, rot, n, theta, fscale, false, null, mscale) - } + rope_scaled_neox_part(unsafe(addr(direct[0])), pos, hs, rot, n, theta, fscale, false, null, mscale) var ct : array var st : array build_rope_tabs(ct, st, theta, fscale, mscale, ff, true, pos, 1l, rot) @@ -370,9 +366,7 @@ def test_rope_apply_dispatch(t : T?) { } var pform : array copy_vec(v, pform, n) - unsafe { - rope_apply(addr(pform[0]), pos, hs, n, 10000.0, 1.0, false, null, neox, 1.19) - } + rope_apply(unsafe(addr(pform[0])), pos, hs, n, 10000.0, 1.0, false, null, neox, 1.19) cmp_exact(t, pform, leaf, n, "rope_apply(ptr, neox={neox}) == the leaf") var aform : array copy_vec(v, aform, n) @@ -442,9 +436,7 @@ def private ff_gate(t : T?; pos, hs, nh : int64; neox : bool) { } var got : array copy_vec(v, got, n) - unsafe { - rope_apply(addr(got[0]), pos, hs, n, 500000.0, 1.0, true, ff_ptr(ff), neox, 1.0) - } + rope_apply(unsafe(addr(got[0])), pos, hs, n, 500000.0, 1.0, true, ff_ptr(ff), neox, 1.0) cmp_bar(t, got, want, n, ROPE_BAR, "freq-factors (neox={neox}) hs={int(hs)} pos={int(pos)}") var ones : array ones |> resize(hs / 2l) diff --git a/modules/dasLLAMA/tests/test_tower_asr_kernels.das b/modules/dasLLAMA/tests/test_tower_asr_kernels.das index 4d0f9c427e..cfc2fb4093 100644 --- a/modules/dasLLAMA/tests/test_tower_asr_kernels.das +++ b/modules/dasLLAMA/tests/test_tower_asr_kernels.das @@ -104,18 +104,14 @@ def private report_poison(t : T?; r : KCase) { def private plane_f(a : array) : PlaneF { var p = PlaneF() - unsafe { - p.p = addr(a[0]) - } + p.p = unsafe(addr(a[0])) p.n = long_length(a) return p } def private plane_u16(a : array) : PlaneU16 { var p = PlaneU16() - unsafe { - p.p = addr(a[0]) - } + p.p = unsafe(addr(a[0])) p.n = long_length(a) return p } diff --git a/modules/dasLLAMA/tests/test_tower_helpers.das b/modules/dasLLAMA/tests/test_tower_helpers.das index cc33cc6f86..f22c696bab 100644 --- a/modules/dasLLAMA/tests/test_tower_helpers.das +++ b/modules/dasLLAMA/tests/test_tower_helpers.das @@ -56,10 +56,8 @@ def test_empty_inputs(t : T?) { var b : array var w <- [1.0] var wp = PlaneF() - unsafe { - wp.p = addr(w[0]) - wp.n = 1l - } + wp.p = unsafe(addr(w[0])) + wp.n = 1l clamp_rows(a, b, 0l, -1.0, 1.0) rms_rows(a, b, wp, 0l, 4l, 0l, 1e-6) rms_rows_weightless(a, 4l, 0l, 1e-6) @@ -78,10 +76,8 @@ def test_rms_rows(t : T?) { var x <- [1.0, 2.0, 3.0, 4.0, -1.0, 0.5, 2.0, -2.0, 3.0, 3.0, 3.0, 3.0, 0.0, 0.0, 1.0, 0.0] var w <- [2.0, 1.0, 0.5, -1.0] var wp = PlaneF() - unsafe { - wp.p = addr(w[0]) - wp.n = 4l - } + wp.p = unsafe(addr(w[0])) + wp.n = 4l var out : array out |> resize(16) rms_rows(out, x, wp, 0l, 4l, 4l, 1e-6) diff --git a/modules/dasLLAMA/tests/test_tts_blocks.das b/modules/dasLLAMA/tests/test_tts_blocks.das index 945c78cfa2..22c8ad6110 100644 --- a/modules/dasLLAMA/tests/test_tts_blocks.das +++ b/modules/dasLLAMA/tests/test_tts_blocks.das @@ -1396,10 +1396,8 @@ def test_rope_rows_and_var_scale_norm(t : T?) { var inscope rx : array rand_fill(r, rx, 6l * 64l, 1.0) var inscope want_rope := rx - unsafe { - for (row in range64(6l)) { - rope_scaled(addr(want_rope[row * 64l]), 100l + row, 16l, 64l, 10000.0, 1.0, false, null) - } + for (row in range64(6l)) { + rope_scaled(unsafe(addr(want_rope[row * 64l])), 100l + row, 16l, 64l, 10000.0, 1.0, false, null) } rope_rows(rx, 6l, 64l, 16l, 100l, 10000.0) var rope_diffs = 0 diff --git a/modules/dasLLAMA/tests/test_tune_interrupt.das b/modules/dasLLAMA/tests/test_tune_interrupt.das index e089aaf00e..d81c6f3df1 100644 --- a/modules/dasLLAMA/tests/test_tune_interrupt.das +++ b/modules/dasLLAMA/tests/test_tune_interrupt.das @@ -23,17 +23,15 @@ def private run_probe(control_env : string) : string { : "DAS_TUNE_CONTROL=\"{control_env}\" ")) let cmd = "{envs}\"{get_das_exe()}\" \"modules/dasLLAMA/tests/_interrupt_probe.das\" -dasroot \"{get_das_root()}\" 2>&1" var out = "" - unsafe { - popen(cmd) $(f) { - if (f != null) { - out = build_string() $(w) { - while (!feof(f)) { - w |> write(fgets(f)) - } + unsafe(popen(cmd) $(f) { + if (f != null) { + out = build_string() $(w) { + while (!feof(f)) { + w |> write(fgets(f)) } } } - } + }) return out } diff --git a/modules/dasLLVM/daslib/llvm_jit.das b/modules/dasLLVM/daslib/llvm_jit.das index 5e6661fa8c..7e63063028 100644 --- a/modules/dasLLVM/daslib/llvm_jit.das +++ b/modules/dasLLVM/daslib/llvm_jit.das @@ -5110,9 +5110,7 @@ class public LlvmJitVisitor : AstVisitor { var ann_vals : array ann_vals |> reserve(int(vi.annotation_argument_count)) for (i in range(int(vi.annotation_argument_count))) { - unsafe { - ann_vals |> push <| create_annotation_argument_info(get_annotation_argument(*vi, i)) - } + ann_vals |> push <| create_annotation_argument_info(get_annotation_argument(*vi, i)) } let n = vi.annotation_argument_count let ann_global = LLVMAddGlobal(g_mod, LLVMArrayType(ann_ty, n), "varinfo_annotations") @@ -5204,12 +5202,7 @@ class public LlvmJitVisitor : AstVisitor { var struct_info_global = LLVMAddGlobal(g_mod, ty, "enuminfo_{ei.module_name}_{ei.name}") set_globalvar_linkage(struct_info_global) enuminfo_cache[ei] = struct_info_global - var ann_vals : array - for (i in range(int(ei.annotation_count))) { - unsafe { - ann_vals |> push <| create_annotation_info_value(get_annotation(*ei, i)) // nolint:PERF006 count known small - } - } + var ann_vals <- [for (i in range(int(ei.annotation_count))); create_annotation_info_value(get_annotation(*ei, i))] var (ann_ptr, ann_count) = pack_annotation_list(ann_vals) var init_values <- [ get_string_constant_ptr(g_builder, ei.name), @@ -5231,12 +5224,7 @@ class public LlvmJitVisitor : AstVisitor { var struct_info_global = LLVMAddGlobal(g_mod, ty, "si_{si.name}") set_globalvar_linkage(struct_info_global) structinfo_cache[si] = struct_info_global - var ann_vals : array - for (i in range(int(si.annotation_count))) { - unsafe { - ann_vals |> push <| create_annotation_info_value(get_annotation(*si, i)) // nolint:PERF006 count known small - } - } + var ann_vals <- [for (i in range(int(si.annotation_count))); create_annotation_info_value(get_annotation(*si, i))] var (ann_ptr, ann_count) = pack_annotation_list(ann_vals) var init_values <- [ get_string_constant_ptr(g_builder, si.name), diff --git a/modules/dasLLVM/daslib/llvm_jit_link.das b/modules/dasLLVM/daslib/llvm_jit_link.das index 9ff1aeea65..d20d3629d3 100644 --- a/modules/dasLLVM/daslib/llvm_jit_link.das +++ b/modules/dasLLVM/daslib/llvm_jit_link.das @@ -124,9 +124,7 @@ def public free_jit_context { if (emitter == null || !has_macro_context(emitter)) { panic("LLVM JIT: an in-memory engine exists but the emitter module is not in the process") } - unsafe { - invoke_in_context(find_macro_context(emitter), "free_jit_engine", ee, ctx) - } + unsafe(invoke_in_context(find_macro_context(emitter), "free_jit_engine", ee, ctx)) } } } diff --git a/modules/dasLLVM/daslib/llvm_jit_run.das b/modules/dasLLVM/daslib/llvm_jit_run.das index 39a8af9014..4868644070 100644 --- a/modules/dasLLVM/daslib/llvm_jit_run.das +++ b/modules/dasLLVM/daslib/llvm_jit_run.das @@ -37,7 +37,7 @@ var LINK_WHOLE_LIB = false // when true, standalone exe links against the whole // Read by tests-cpp/small/test_jit_emitter_pin.cpp: FNV-1a64 of the emitter sources // (normalized to LF; file list in the test) -let LLVM_JIT_EMITTER_HASH : uint64 = 0xbf8412b8bfc82374ul +let LLVM_JIT_EMITTER_HASH : uint64 = 0x6eeb529c1bd2a8ful def private apply_fast_math_to_module(m : LLVMOpaqueModule?) { var fn = LLVMGetFirstFunction(m) @@ -157,12 +157,16 @@ def private add_debug_module_flags(debug_info : bool; target_triple : string) { LLVMAddModuleFlag(g_mod, LLVMModuleFlagBehavior.Warning, div_key, uint64(long_length(div_key)), LLVMValueAsMetadata(LLVMConstInt(LLVMInt32TypeInContext(g_ctx), 3ul, 0))) // host_jit_triple() is "" on MSVC hosts — LLVM's default triple is the actual host answer - let triple = (target_triple |> empty()) ? LLVMGetDefaultTargetTriple() : target_triple + let triple_owned = target_triple |> empty() + let triple = triple_owned ? LLVMGetDefaultTargetTriple() : target_triple if (triple |> find("windows") != -1) { let cv_key = "CodeView" LLVMAddModuleFlag(g_mod, LLVMModuleFlagBehavior.Warning, cv_key, uint64(long_length(cv_key)), LLVMValueAsMetadata(LLVMConstInt(LLVMInt32TypeInContext(g_ctx), 1ul, 0))) } + if (triple_owned) { + LLVMDisposeMessage(triple) + } } // irgen one function set into the current g_mod, with the per-function verifier panics diff --git a/modules/dasLLVM/daslib/llvm_macro.das b/modules/dasLLVM/daslib/llvm_macro.das index b1782b107d..953724296a 100644 --- a/modules/dasLLVM/daslib/llvm_macro.das +++ b/modules/dasLLVM/daslib/llvm_macro.das @@ -21,9 +21,7 @@ def private llvm_macro_context { //! the whole codegen pipeline for a simulated program; `ok` is `run_jit`'s answer [export] def public run_jit_codegen(prog : Program?; var ctx : Context?; var ok : bool?) { - unsafe { - *ok = run_jit(prog, ctx) - } + *ok = run_jit(prog, ctx) } //! the in-memory engine's teardown; the finalizer in `llvm_jit_link` delegates here diff --git a/modules/dasLLVM/tests/llvm_jit_baseline.das b/modules/dasLLVM/tests/llvm_jit_baseline.das index 0fbc5d385f..267114f327 100644 --- a/modules/dasLLVM/tests/llvm_jit_baseline.das +++ b/modules/dasLLVM/tests/llvm_jit_baseline.das @@ -63,20 +63,17 @@ def private env_prefix(baseline : string) : string { } def private spawn_child(cmd : string; var lines : array) : int { - var rc : int - unsafe { - rc = popen_timeout("{cmd} 2>&1", 300.0) $(f) { - if (f == null) { - return - } - while (!feof(f)) { - let ln = strip(fgets(f)) - if (!empty(ln)) { - lines |> push("{ln}") - } + let rc = unsafe(popen_timeout("{cmd} 2>&1", 300.0) $(f) { + if (f == null) { + return + } + while (!feof(f)) { + let ln = strip(fgets(f)) + if (!empty(ln)) { + lines |> push("{ln}") } } - } + }) return rc } diff --git a/modules/dasLLVM/tests/llvm_tune_fat.das b/modules/dasLLVM/tests/llvm_tune_fat.das index cbe4d3025d..d46d44720b 100644 --- a/modules/dasLLVM/tests/llvm_tune_fat.das +++ b/modules/dasLLVM/tests/llvm_tune_fat.das @@ -24,20 +24,17 @@ def private tune_env_prefix(mode, baseline, pin : string) : string { } def private spawn_child(cmd : string; var lines : array) : int { - var rc : int - unsafe { - rc = popen_timeout("{cmd} 2>&1", 300.0) $(f) { - if (f == null) { - return - } - while (!feof(f)) { - let ln = strip(fgets(f)) - if (!empty(ln)) { - lines |> push("{ln}") - } + let rc = unsafe(popen_timeout("{cmd} 2>&1", 300.0) $(f) { + if (f == null) { + return + } + while (!feof(f)) { + let ln = strip(fgets(f)) + if (!empty(ln)) { + lines |> push("{ln}") } } - } + }) return rc } diff --git a/modules/dasLLVM/tests/llvm_tune_manifest.das b/modules/dasLLVM/tests/llvm_tune_manifest.das index ba91bd42e9..8900f4fdca 100644 --- a/modules/dasLLVM/tests/llvm_tune_manifest.das +++ b/modules/dasLLVM/tests/llvm_tune_manifest.das @@ -27,21 +27,18 @@ def private spawn_client(cmd : string; var lines : array) : int { // cmd.exe /c strips the first and last quote of a line that starts with a quote — but the env // prefix now leads, so the line never starts with a quote and no sacrificial wrap is needed let full = "{env}{cmd}" - var rc : int - unsafe { - rc = popen_timeout(full, 300.0) $(f) { - if (f == null) { - return - } - while (!feof(f)) { - let ln = fgets(f) - if (ln |> starts_with("WRITE ") || ln |> starts_with("RESULT ") || ln |> starts_with("KV ") - || ln |> starts_with("OTHER ") || ln |> starts_with("REF ") || ln |> starts_with("llvm_tune:")) { - lines |> push(strip("{ln}")) - } + let rc = unsafe(popen_timeout(full, 300.0) $(f) { + if (f == null) { + return + } + while (!feof(f)) { + let ln = fgets(f) + if (ln |> starts_with("WRITE ") || ln |> starts_with("RESULT ") || ln |> starts_with("KV ") + || ln |> starts_with("OTHER ") || ln |> starts_with("REF ") || ln |> starts_with("llvm_tune:")) { + lines |> push(strip("{ln}")) } } - } + }) return rc } @@ -139,11 +136,9 @@ def test_llvm_tune_manifest_roundtrip(t : T?) { // nolint:STYLE038 - flat sequ // asserted on the parsed value, not the JSON text: a Windows home is escaped there let recorded_binary = "{jdoc?["provenance"]?["binary"] ?? ""}" t |> success(!empty(recorded_binary) && tilde_home(recorded_binary) == recorded_binary, "a minted sidecar names no home directory - the binary path is spelled ~: {recorded_binary}") - unsafe { - var prov = jdoc?["provenance"] - if (prov != null) { - update(prov, "box", JV("some-other-box|foreign-arch|foreign-hw")) - } + var prov = jdoc?["provenance"] + if (prov != null) { + update(prov, "box", JV("some-other-box|foreign-arch|foreign-hw")) } fwrite(sidecarPath, write_json(jdoc)) delete_json(jdoc) @@ -166,11 +161,9 @@ def test_llvm_tune_manifest_roundtrip(t : T?) { // nolint:STYLE038 - flat sequ var jerr2 = "" var jdoc2 = read_json(fread(sidecarPath), jerr2) t |> success(jdoc2 != null, "foreign sidecar parses: {jerr2}") - unsafe { - var prov2 = jdoc2?["provenance"] - if (prov2 != null) { - update(prov2, "applied_box", JV(tune_box_identity())) - } + var prov2 = jdoc2?["provenance"] + if (prov2 != null) { + update(prov2, "applied_box", JV(tune_box_identity())) } fwrite(sidecarPath, write_json(jdoc2)) delete_json(jdoc2) diff --git a/modules/dasLLVM/tests/llvm_tune_modes.das b/modules/dasLLVM/tests/llvm_tune_modes.das index ca85406ac1..19b0d40287 100644 --- a/modules/dasLLVM/tests/llvm_tune_modes.das +++ b/modules/dasLLVM/tests/llvm_tune_modes.das @@ -28,20 +28,17 @@ def test_llvm_tune_grid_mode(t : T?) { // popen goes through cmd.exe / /bin/sh — set the env inside the command line let cmd = get_platform_name() == "windows" ? "set DAS_TUNE_MODE=test&& {inner}" : "DAS_TUNE_MODE=test {inner}" var lines : array - var rc : int - unsafe { - rc = popen_timeout(cmd, 300.0) $(f) { - if (f == null) { - return - } - while (!feof(f)) { - let ln = fgets(f) - if (ln |> starts_with("VARIANT ") || ln |> starts_with("KVARIANT ")) { - lines |> push("{ln}") - } + let rc = unsafe(popen_timeout(cmd, 300.0) $(f) { + if (f == null) { + return + } + while (!feof(f)) { + let ln = fgets(f) + if (ln |> starts_with("VARIANT ") || ln |> starts_with("KVARIANT ")) { + lines |> push("{ln}") } } - } + }) t |> equal(rc, 0) var seen : table for (ln in lines) { diff --git a/modules/dasLLVM/tests/llvm_tune_profiles.das b/modules/dasLLVM/tests/llvm_tune_profiles.das index d5eddb6563..7059a6ebdf 100644 --- a/modules/dasLLVM/tests/llvm_tune_profiles.das +++ b/modules/dasLLVM/tests/llvm_tune_profiles.das @@ -33,20 +33,17 @@ def private tune_env_prefix(relaunch : string) : string { } def private spawn_child(cmd : string; var lines : array) : int { - var rc : int - unsafe { - rc = popen_timeout("{cmd} 2>&1", 300.0) $(f) { - if (f == null) { - return - } - while (!feof(f)) { - let ln = strip(fgets(f)) - if (!empty(ln)) { - lines |> push("{ln}") - } + let rc = unsafe(popen_timeout("{cmd} 2>&1", 300.0) $(f) { + if (f == null) { + return + } + while (!feof(f)) { + let ln = strip(fgets(f)) + if (!empty(ln)) { + lines |> push("{ln}") } } - } + }) return rc } diff --git a/modules/dasLLVM/tests/llvm_tune_scope.das b/modules/dasLLVM/tests/llvm_tune_scope.das index 6280b0da29..1acbb8eec5 100644 --- a/modules/dasLLVM/tests/llvm_tune_scope.das +++ b/modules/dasLLVM/tests/llvm_tune_scope.das @@ -28,20 +28,17 @@ def private tune_env(policy : string) : string { // env prefix leads, so no sacrificial-quote wrap is needed (cmd.exe only strips a LEADING quote) def private spawn_child(cmd : string; var lines : array) : int { - var rc : int - unsafe { - rc = popen_timeout("{cmd} 2>&1", 300.0) $(f) { - if (f == null) { - return - } - while (!feof(f)) { - let ln = strip(fgets(f)) - if (!empty(ln)) { - lines |> push("{ln}") - } + let rc = unsafe(popen_timeout("{cmd} 2>&1", 300.0) $(f) { + if (f == null) { + return + } + while (!feof(f)) { + let ln = strip(fgets(f)) + if (!empty(ln)) { + lines |> push("{ln}") } } - } + }) return rc } @@ -261,11 +258,9 @@ def test_llvm_tune_scope_policy(t : T?) { // nolint:STYLE038 - flat numbered p var verr = "" var vdoc = read_json(fread(verSidecar), verr) t |> success(vdoc != null, "ver sidecar parses: {verr}") - unsafe { - var vprov = vdoc?["provenance"] - if (vprov != null) { - update(vprov, "testver", JV("1")) - } + var vprov = vdoc?["provenance"] + if (vprov != null) { + update(vprov, "testver", JV("1")) } fwrite(verSidecar, write_json(vdoc)) delete_json(vdoc) diff --git a/modules/dasLLVM/tests/test_tuned.das b/modules/dasLLVM/tests/test_tuned.das index 5f30cc117f..969cea1e52 100644 --- a/modules/dasLLVM/tests/test_tuned.das +++ b/modules/dasLLVM/tests/test_tuned.das @@ -64,14 +64,11 @@ def test_tuned_stale_sidecar_perm(t : T?) { : "DAS_TUNE_MANIFEST='{manifest}' ") let cmd = "{env}\"{bin}\" \"{client}\"" var outp = "" - var rc : int - unsafe { - rc = popen_timeout(cmd, 300.0) $(f) { - if (f != null) { - outp = fread(f) - } + let rc = unsafe(popen_timeout(cmd, 300.0) $(f) { + if (f != null) { + outp = fread(f) } - } + }) t |> equal(rc, 0, "the stale-sidecar client compiles and runs") t |> success(find(outp, "stale mint?") >= 0, "the fallback stamp is announced (got: {outp})") t |> success(find(outp, "STALE_CLIENT_OK") >= 0, "the client ran to completion (got: {outp})") @@ -80,14 +77,11 @@ def test_tuned_stale_sidecar_perm(t : T?) { def private spawn_capture(cmd : string; var outp : string&) : int { outp = "" - var rc : int - unsafe { - rc = popen_timeout(cmd, 300.0) $(f) { - if (f != null) { - outp = fread(f) - } + let rc = unsafe(popen_timeout(cmd, 300.0) $(f) { + if (f != null) { + outp = fread(f) } - } + }) return rc } diff --git a/modules/dasOpenGL/opengl/opengl_boost.das b/modules/dasOpenGL/opengl/opengl_boost.das index 366295b3a8..cc8f6f0e36 100644 --- a/modules/dasOpenGL/opengl/opengl_boost.das +++ b/modules/dasOpenGL/opengl/opengl_boost.das @@ -165,15 +165,11 @@ def glUniformAny(location : int; value : int4) { } def glUniformMatrix4fv(location : int; value : float4x4) { - unsafe { - glUniformMatrix4fv(location, 1, false, addr(value[0][0])) - } + glUniformMatrix4fv(location, 1, false, unsafe(addr(value[0][0]))) } def glUniformMatrix3fv(location : int; value : float3x3) { - unsafe { - glUniformMatrix3fv(location, 1, false, addr(value[0][0])) - } + glUniformMatrix3fv(location, 1, false, unsafe(addr(value[0][0]))) } [expect_any_array(arr)] @@ -265,9 +261,7 @@ def std140_release_all() { } def glVertexAttribPointer(index : uint; size : int; tp : GLenum; normalized : bool; stride : int; offset : int) { - unsafe { - glVertexAttribPointer(index, size, tp, normalized, stride, reinterpret(offset)) - } + glVertexAttribPointer(index, size, tp, normalized, stride, unsafe(reinterpret(offset))) } def glVertexAttribPointer(index : uint; size : int; tp : GLenum; normalized : bool; stride : int; ptrd : void?; offset : int) { diff --git a/modules/dasOpenGL/opengl/opengl_ttf.das b/modules/dasOpenGL/opengl/opengl_ttf.das index 22e7f9b9e6..bc5b4531e2 100644 --- a/modules/dasOpenGL/opengl/opengl_ttf.das +++ b/modules/dasOpenGL/opengl/opengl_ttf.das @@ -50,10 +50,8 @@ def public upload_font_texture(var font : Font) { var tex = 0u glGenTextures(1, safe_addr(tex)) glBindTexture(GL_TEXTURE_2D, tex) - unsafe { - glTexImage2D(GL_TEXTURE_2D, 0, int(GL_R8), font.bitmap.width, font.bitmap.height, - 0, GL_RED, GL_UNSIGNED_BYTE, addr(font.bitmap.bytes[0])) - } + glTexImage2D(GL_TEXTURE_2D, 0, int(GL_R8), font.bitmap.width, font.bitmap.height, + 0, GL_RED, GL_UNSIGNED_BYTE, unsafe(addr(font.bitmap.bytes[0]))) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) font.tex = uint64(tex) @@ -86,10 +84,8 @@ def public create_quads(font : Font; text : string; at : float2 = float2(0.)) { for (ch in text) { let idx = ch - first if (idx >= 0 && idx < num_chars) { - unsafe { - stbtt_GetPackedQuad(addr(font.chardata[0]), bw, bh, idx, - safe_addr(x), safe_addr(y), safe_addr(q), 0) - } + stbtt_GetPackedQuad(unsafe(addr(font.chardata[0])), bw, bh, idx, + safe_addr(x), safe_addr(y), safe_addr(q), 0) quads |> push(FontVertex(xy = float2(q.x0, q.y0), uv = float2(q.s0, q.t0))) quads |> push(FontVertex(xy = float2(q.x1, q.y0), uv = float2(q.s1, q.t0))) quads |> push(FontVertex(xy = float2(q.x1, q.y1), uv = float2(q.s1, q.t1))) diff --git a/modules/dasPEG/peg/parser_generator.das b/modules/dasPEG/peg/parser_generator.das index d19a6c867a..92a0f0fbb5 100644 --- a/modules/dasPEG/peg/parser_generator.das +++ b/modules/dasPEG/peg/parser_generator.das @@ -429,12 +429,11 @@ def set_rule_handle(var subrule_ : Rule_?; handle : string) { match (subrule_variant) { if (Rule(nonterminal = $v(nonterm))) { - unsafe {// Moving values that contain smart pointers is generally unsafe - // But here we know that the contained variant is nonterminal (string) and cannot - // possibly contain valid smart pointer. Therefore it should be safe to overwrite it. - subrule_.rule <- Rule(bound_nonterminal = (nonterm, handle)) - return - } + // Moving values that contain smart pointers is generally unsafe + // But here we know that the contained variant is nonterminal (string) and cannot + // possibly contain valid smart pointer. Therefore it should be safe to overwrite it. + subrule_.rule <- Rule(bound_nonterminal = (nonterm, handle)) + return } if (Rule(terminal = $v(term))) { diff --git a/modules/dasTerminal/daslib/terminal.das b/modules/dasTerminal/daslib/terminal.das index a10b077735..907fe0afe7 100644 --- a/modules/dasTerminal/daslib/terminal.das +++ b/modules/dasTerminal/daslib/terminal.das @@ -1158,9 +1158,7 @@ def private resize_buffer(var buffer : TerminalBuffer; old_columns, old_rows, for (logical in range(length(buffer.history))) { let index = history_index(buffer, logical) let old_count = length(buffer.history[index].cells) - unsafe { - buffer.history[index].cells |> resize(columns) - } + buffer.history[index].cells |> resize(columns) for (column in range(old_count, columns)) { buffer.history[index].cells[column] = blank_cell(logical, column) } diff --git a/modules/dasTerminal/tests/app_compat.das b/modules/dasTerminal/tests/app_compat.das index 91d9b6d891..85f0455d36 100644 --- a/modules/dasTerminal/tests/app_compat.das +++ b/modules/dasTerminal/tests/app_compat.das @@ -189,24 +189,18 @@ def main { for (step in scenario.steps) { if (!empty(step.feed)) terminal_feed_bytes(terminal, step.feed) if (step.resize != null) { - unsafe { - terminal_resize(terminal, step.resize.columns, step.resize.rows) - } + terminal_resize(terminal, step.resize.columns, step.resize.rows) } if (!empty(step.checkpoint)) { - unsafe { - check(checkpoint_index < length(expected.checkpoints), - "extra checkpoint {scenario.id}/{step.checkpoint}") - check(expected.checkpoints[checkpoint_index].checkpoint == step.checkpoint, - "checkpoint order {scenario.id}/{step.checkpoint}") - assert_checkpoint(terminal, expected.checkpoints[checkpoint_index], scenario.id) - checkpoint_index++ - } + check(checkpoint_index < length(expected.checkpoints), + "extra checkpoint {scenario.id}/{step.checkpoint}") + check(expected.checkpoints[checkpoint_index].checkpoint == step.checkpoint, + "checkpoint order {scenario.id}/{step.checkpoint}") + assert_checkpoint(terminal, expected.checkpoints[checkpoint_index], scenario.id) + checkpoint_index++ } } - unsafe { - check(checkpoint_index == length(expected.checkpoints), - "missing checkpoint {scenario.id}") - } + check(checkpoint_index == length(expected.checkpoints), + "missing checkpoint {scenario.id}") } } diff --git a/modules/dasTerminal/tests/ownership_semantics.das b/modules/dasTerminal/tests/ownership_semantics.das index f0efb33659..86f12bd286 100644 --- a/modules/dasTerminal/tests/ownership_semantics.das +++ b/modules/dasTerminal/tests/ownership_semantics.das @@ -7,7 +7,7 @@ require strings [export] def main { - unsafe { heap_collect(true, true) } + unsafe(heap_collect(true, true)) var inscope terminal <- terminal_create(240, 100) let live_grid_bytes = heap_bytes_allocated() diff --git a/modules/dasVulkan/daslib/vulkan_assets.das b/modules/dasVulkan/daslib/vulkan_assets.das index 06e92d0c4d..49eed7a552 100644 --- a/modules/dasVulkan/daslib/vulkan_assets.das +++ b/modules/dasVulkan/daslib/vulkan_assets.das @@ -48,11 +48,9 @@ struct public Texture { } def public finalize(var t : Texture) { - unsafe { - delete t.view - delete t.image - delete t.memory - } + delete t.view + delete t.image + delete t.memory } // Isolate the dasStbImage `Image` (clashes with vulkan's `Image` name) to this one helper: load a @@ -174,10 +172,8 @@ def public upload_texture(device : Device; phys : VkPhysicalDevice; queue : VkQu blit.dstOffsets[1].x = nw blit.dstOffsets[1].y = nh blit.dstOffsets[1].z = 1 - unsafe { - vkCmdBlitImage(boost_value_to_vk(cmd), boost_value_to_vk(image), VkImageLayout.TRANSFER_SRC_OPTIMAL, - boost_value_to_vk(image), VkImageLayout.TRANSFER_DST_OPTIMAL, 1u, addr(blit), VkFilter.LINEAR) - } + vkCmdBlitImage(boost_value_to_vk(cmd), boost_value_to_vk(image), VkImageLayout.TRANSFER_SRC_OPTIMAL, + boost_value_to_vk(image), VkImageLayout.TRANSFER_DST_OPTIMAL, 1u, unsafe(addr(blit)), VkFilter.LINEAR) mip_barrier(cmd, image, uint(i - 1), 1u, VkImageLayout.TRANSFER_SRC_OPTIMAL, VkImageLayout.SHADER_READ_ONLY_OPTIMAL, to_tread, to_read, xfer, frag_stage) mw = nw @@ -231,10 +227,8 @@ struct public Mesh { } def public finalize(var m : Mesh) { - unsafe { - delete m.ibuf - delete m.vbuf - } + delete m.ibuf + delete m.vbuf } //! Load an OBJ model into vertex + index buffers via the daslang glsl/geom_gen parser (positions + diff --git a/modules/dasVulkan/daslib/vulkan_boost.das b/modules/dasVulkan/daslib/vulkan_boost.das index 71ed10ac4c..ea1cf69e70 100644 --- a/modules/dasVulkan/daslib/vulkan_boost.das +++ b/modules/dasVulkan/daslib/vulkan_boost.das @@ -29,9 +29,7 @@ def public select_physical_device(instance : Instance) : VkPhysicalDevice { } var devices : array devices |> resize(int(count)) - unsafe { - vkEnumeratePhysicalDevices(boost_value_to_vk(instance), count, addr(devices[0])) - } + vkEnumeratePhysicalDevices(boost_value_to_vk(instance), count, unsafe(addr(devices[0]))) // prefer a discrete GPU var best = devices[0] for (d in devices) { @@ -50,9 +48,7 @@ def public select_graphics_queue_family(phys : VkPhysicalDevice) : uint { vkGetPhysicalDeviceQueueFamilyProperties(phys, count, null) var props : array props |> resize(int(count)) - unsafe { - vkGetPhysicalDeviceQueueFamilyProperties(phys, count, addr(props[0])) - } + vkGetPhysicalDeviceQueueFamilyProperties(phys, count, unsafe(addr(props[0]))) for (i in range(int(count))) { if (props[i].queueFlags.graphics) { return uint(i) @@ -137,9 +133,7 @@ def public mesh_shader_supported(phys : VkPhysicalDevice) : bool { } var mf = VkPhysicalDeviceMeshShaderFeaturesEXT() // sType pre-filled by the ctor var f2 = VkPhysicalDeviceFeatures2() - unsafe { - f2.pNext = addr(mf) - } + f2.pNext = unsafe(addr(mf)) vkGetPhysicalDeviceFeatures2(phys, f2) return mf.meshShader != 0u && mf.taskShader != 0u } @@ -152,9 +146,7 @@ def public create_instance(application_name : string; api_version : uint; extens ai.pApplicationName = application_name } var ci = VkInstanceCreateInfo() - unsafe { - ci.pApplicationInfo = addr(ai) - } + ci.pApplicationInfo = unsafe(addr(ai)) var exts <- [for (e in extensions); e] if (instance_extension_available("VK_KHR_portability_enumeration")) { if (find_index(exts, "VK_KHR_portability_enumeration") < 0) { @@ -166,9 +158,7 @@ def public create_instance(application_name : string; api_version : uint; extens // Vulkan wants); ppEnabledExtensionNames is bound as void? so reinterpret to it. if (!empty(exts)) { ci.enabledExtensionCount = uint(length(exts)) - unsafe { - ci.ppEnabledExtensionNames = addr(exts[0]) - } + ci.ppEnabledExtensionNames = unsafe(addr(exts[0])) } var h : VkInstance vk_check(vkCreateInstance(ci, null, h), null) @@ -209,9 +199,7 @@ def public create_device(phys : VkPhysicalDevice; queue_family : uint; extension var qci = VkDeviceQueueCreateInfo() qci.queueFamilyIndex = queue_family qci.queueCount = 1u - unsafe { - qci.pQueuePriorities = addr(prio) - } + qci.pQueuePriorities = unsafe(addr(prio)) var ci = VkDeviceCreateInfo() ci.queueCreateInfoCount = 1u unsafe { @@ -222,9 +210,7 @@ def public create_device(phys : VkPhysicalDevice; queue_family : uint; extension append_portability_subset(phys, exts) if (!empty(exts)) { ci.enabledExtensionCount = uint(length(exts)) - unsafe { - ci.ppEnabledExtensionNames = addr(exts[0]) - } + ci.ppEnabledExtensionNames = unsafe(addr(exts[0])) } var h : VkDevice vk_check(vkCreateDevice(phys, ci, null, h), null) @@ -242,9 +228,7 @@ def public create_device(phys : VkPhysicalDevice; queue_family : uint; extension var qci = VkDeviceQueueCreateInfo() qci.queueFamilyIndex = queue_family qci.queueCount = 1u - unsafe { - qci.pQueuePriorities = addr(prio) - } + qci.pQueuePriorities = unsafe(addr(prio)) features13.sType = VkStructureType.PHYSICAL_DEVICE_VULKAN_1_3_FEATURES var ci = VkDeviceCreateInfo() ci.queueCreateInfoCount = 1u @@ -256,9 +240,7 @@ def public create_device(phys : VkPhysicalDevice; queue_family : uint; extension append_portability_subset(phys, exts) if (!empty(exts)) { ci.enabledExtensionCount = uint(length(exts)) - unsafe { - ci.ppEnabledExtensionNames = addr(exts[0]) - } + ci.ppEnabledExtensionNames = unsafe(addr(exts[0])) } var h : VkDevice vk_check(vkCreateDevice(phys, ci, null, h), null) @@ -276,9 +258,7 @@ def public create_device(phys : VkPhysicalDevice; queue_family : uint; extension var qci = VkDeviceQueueCreateInfo() qci.queueFamilyIndex = queue_family qci.queueCount = 1u - unsafe { - qci.pQueuePriorities = addr(prio) - } + qci.pQueuePriorities = unsafe(addr(prio)) features12.sType = VkStructureType.PHYSICAL_DEVICE_VULKAN_1_2_FEATURES var ci = VkDeviceCreateInfo() ci.queueCreateInfoCount = 1u @@ -290,9 +270,7 @@ def public create_device(phys : VkPhysicalDevice; queue_family : uint; extension append_portability_subset(phys, exts) if (!empty(exts)) { ci.enabledExtensionCount = uint(length(exts)) - unsafe { - ci.ppEnabledExtensionNames = addr(exts[0]) - } + ci.ppEnabledExtensionNames = unsafe(addr(exts[0])) } var h : VkDevice vk_check(vkCreateDevice(phys, ci, null, h), null) @@ -310,9 +288,7 @@ def public create_device(phys : VkPhysicalDevice; queue_family : uint; extension var qci = VkDeviceQueueCreateInfo() qci.queueFamilyIndex = queue_family qci.queueCount = 1u - unsafe { - qci.pQueuePriorities = addr(prio) - } + qci.pQueuePriorities = unsafe(addr(prio)) features2.sType = VkStructureType.PHYSICAL_DEVICE_FEATURES_2 var ci = VkDeviceCreateInfo() ci.queueCreateInfoCount = 1u @@ -324,9 +300,7 @@ def public create_device(phys : VkPhysicalDevice; queue_family : uint; extension append_portability_subset(phys, exts) if (!empty(exts)) { ci.enabledExtensionCount = uint(length(exts)) - unsafe { - ci.ppEnabledExtensionNames = addr(exts[0]) - } + ci.ppEnabledExtensionNames = unsafe(addr(exts[0])) } var h : VkDevice vk_check(vkCreateDevice(phys, ci, null, h), null) @@ -354,9 +328,7 @@ def public create_device(phys : VkPhysicalDevice; queue_families : array; qc = VkDeviceQueueCreateInfo() qc.queueFamilyIndex = qf qc.queueCount = 1u - unsafe { - qc.pQueuePriorities = addr(prio) - } + qc.pQueuePriorities = unsafe(addr(prio)) } features2.sType = VkStructureType.PHYSICAL_DEVICE_FEATURES_2 var ci = VkDeviceCreateInfo() @@ -369,9 +341,7 @@ def public create_device(phys : VkPhysicalDevice; queue_families : array; append_portability_subset(phys, exts) if (!empty(exts)) { ci.enabledExtensionCount = uint(length(exts)) - unsafe { - ci.ppEnabledExtensionNames = addr(exts[0]) - } + ci.ppEnabledExtensionNames = unsafe(addr(exts[0])) } var h : VkDevice vk_check(vkCreateDevice(phys, ci, null, h), null) @@ -426,9 +396,7 @@ def public create_device_storage_8_16(phys : VkPhysicalDevice; queue_family : ui def public cooperative_matrix_supported(phys : VkPhysicalDevice) : bool { var fcm = VkPhysicalDeviceCooperativeMatrixFeaturesKHR() var f2 = VkPhysicalDeviceFeatures2() - unsafe { - f2.pNext = addr(fcm) - } + f2.pNext = unsafe(addr(fcm)) vkGetPhysicalDeviceFeatures2(phys, f2) return fcm.cooperativeMatrix != 0u } @@ -462,9 +430,7 @@ def public pipeline_exec_props_supported(phys : VkPhysicalDevice) : bool { if (!device_extension_available(phys, "VK_KHR_pipeline_executable_properties")) return false var fpe = VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR() var f2 = VkPhysicalDeviceFeatures2() - unsafe { - f2.pNext = addr(fpe) - } + f2.pNext = unsafe(addr(fpe)) vkGetPhysicalDeviceFeatures2(phys, f2) return fpe.pipelineExecutableInfo != 0u } @@ -481,9 +447,7 @@ let private OSVM_ADAPTER_SHARED = 3 def public os_video_memory(phys : VkPhysicalDevice) : tuple { var idp = VkPhysicalDeviceIDProperties() var p2 = VkPhysicalDeviceProperties2() - unsafe { - p2.pNext = addr(idp) - } + p2.pNext = unsafe(addr(idp)) vkGetPhysicalDeviceProperties2(phys, p2) if (idp.deviceLUIDValid == 0u) { return (budget = 0ul, usage = 0ul, adapter_dedicated = 0ul, adapter_shared = 0ul) @@ -505,9 +469,7 @@ def public os_video_memory(phys : VkPhysicalDevice) : tuple(q13) - } + q2.pNext = unsafe(addr(q13)) vkGetPhysicalDeviceFeatures2(phys, q2) var f11 = VkPhysicalDeviceVulkan11Features() var f12 = VkPhysicalDeviceVulkan12Features() @@ -546,9 +508,7 @@ def public create_device_coopmat_full_subgroups(phys : VkPhysicalDevice; queue_f def public subgroup_properties(phys : VkPhysicalDevice) : VkPhysicalDeviceSubgroupProperties { var sp = VkPhysicalDeviceSubgroupProperties() var p2 = VkPhysicalDeviceProperties2() - unsafe { - p2.pNext = addr(sp) - } + p2.pNext = unsafe(addr(sp)) vkGetPhysicalDeviceProperties2(phys, p2) return sp } @@ -568,9 +528,7 @@ def public subgroup_compute_ops_supported(phys : VkPhysicalDevice) : bool { def public integer_dot_product_supported(phys : VkPhysicalDevice) : bool { var fdot = VkPhysicalDeviceShaderIntegerDotProductFeatures() var f2 = VkPhysicalDeviceFeatures2() - unsafe { - f2.pNext = addr(fdot) - } + f2.pNext = unsafe(addr(fdot)) vkGetPhysicalDeviceFeatures2(phys, f2) return fdot.shaderIntegerDotProduct != 0u } @@ -716,9 +674,7 @@ def public memory_priority_supported(phys : VkPhysicalDevice) : bool { } var qmp = VkPhysicalDeviceMemoryPriorityFeaturesEXT() var q2 = VkPhysicalDeviceFeatures2() - unsafe { - q2.pNext = addr(qmp) - } + q2.pNext = unsafe(addr(qmp)) vkGetPhysicalDeviceFeatures2(phys, q2) return qmp.memoryPriority != 0u } @@ -754,9 +710,7 @@ def public cooperative_matrix2_fa_supported(phys : VkPhysicalDevice) : bool { if (!cooperative_matrix2_supported(phys)) return false var fcm2 = VkPhysicalDeviceCooperativeMatrix2FeaturesNV() var f2 = VkPhysicalDeviceFeatures2() - unsafe { - f2.pNext = addr(fcm2) - } + f2.pNext = unsafe(addr(fcm2)) vkGetPhysicalDeviceFeatures2(phys, f2) return (fcm2.cooperativeMatrixReductions != 0u && fcm2.cooperativeMatrixConversions != 0u && fcm2.cooperativeMatrixPerElementOperations != 0u) @@ -770,9 +724,7 @@ def public cooperative_matrix2_decode_vector_supported(phys : VkPhysicalDevice) if (!cooperative_matrix2_supported(phys) || !device_extension_available(phys, "VK_NV_cooperative_matrix_decode_vector")) return false var fdv = VkPhysicalDeviceCooperativeMatrixDecodeVectorFeaturesNV() var f2 = VkPhysicalDeviceFeatures2() - unsafe { - f2.pNext = addr(fdv) - } + f2.pNext = unsafe(addr(fdv)) vkGetPhysicalDeviceFeatures2(phys, f2) return fdv.cooperativeMatrixDecodeVector != 0u } @@ -782,9 +734,7 @@ def public cooperative_matrix2_decode_vector_supported(phys : VkPhysicalDevice) def public cooperative_matrix2_properties(phys : VkPhysicalDevice) : VkPhysicalDeviceCooperativeMatrix2PropertiesNV { var cp = VkPhysicalDeviceCooperativeMatrix2PropertiesNV() var p2 = VkPhysicalDeviceProperties2() - unsafe { - p2.pNext = addr(cp) - } + p2.pNext = unsafe(addr(cp)) vkGetPhysicalDeviceProperties2(phys, p2) return cp } @@ -796,9 +746,7 @@ def public cooperative_vector_supported(phys : VkPhysicalDevice) : bool { if (!device_extension_available(phys, "VK_NV_cooperative_vector")) return false var fcv = VkPhysicalDeviceCooperativeVectorFeaturesNV() var f2 = VkPhysicalDeviceFeatures2() - unsafe { - f2.pNext = addr(fcv) - } + f2.pNext = unsafe(addr(fcv)) vkGetPhysicalDeviceFeatures2(phys, f2) return fcv.cooperativeVector != 0u } @@ -812,9 +760,7 @@ def public select_transfer_queue_family(phys : VkPhysicalDevice) : int { if (qcount == 0u) return -1 var qprops : array qprops |> resize(int(qcount)) - unsafe { - vkGetPhysicalDeviceQueueFamilyProperties(phys, qcount, addr(qprops[0])) - } + vkGetPhysicalDeviceQueueFamilyProperties(phys, qcount, unsafe(addr(qprops[0]))) var found = -1 for (q, qi in qprops, count()) { if (found < 0 && q.queueFlags.transfer && !q.queueFlags.graphics && !q.queueFlags.compute) { @@ -966,9 +912,7 @@ def public create_device_storage_8_16_int_dot_coopmat2(phys : VkPhysicalDevice; def public timeline_semaphore_supported(phys : VkPhysicalDevice) : bool { var q12 = VkPhysicalDeviceVulkan12Features() var q2 = VkPhysicalDeviceFeatures2() - unsafe { - q2.pNext = addr(q12) - } + q2.pNext = unsafe(addr(q12)) vkGetPhysicalDeviceFeatures2(phys, q2) return q12.timelineSemaphore != 0u } @@ -985,9 +929,7 @@ def public external_memory_host_min_alignment(phys : VkPhysicalDevice) : uint64 } var emh = VkPhysicalDeviceExternalMemoryHostPropertiesEXT() var p2 = VkPhysicalDeviceProperties2() - unsafe { - p2.pNext = addr(emh) - } + p2.pNext = unsafe(addr(emh)) vkGetPhysicalDeviceProperties2(phys, p2) return emh.minImportedHostPointerAlignment } @@ -1016,9 +958,7 @@ def public create_device_draw_parameters(phys : VkPhysicalDevice; queue_family : var qci = VkDeviceQueueCreateInfo() qci.queueFamilyIndex = queue_family qci.queueCount = 1u - unsafe { - qci.pQueuePriorities = addr(prio) - } + qci.pQueuePriorities = unsafe(addr(prio)) var base : VkPhysicalDeviceFeatures base.multiDrawIndirect = 1u var f11 : VkPhysicalDeviceVulkan11Features @@ -1035,9 +975,7 @@ def public create_device_draw_parameters(phys : VkPhysicalDevice; queue_family : append_portability_subset(phys, exts) if (!empty(exts)) { ci.enabledExtensionCount = uint(length(exts)) - unsafe { - ci.ppEnabledExtensionNames = addr(exts[0]) - } + ci.ppEnabledExtensionNames = unsafe(addr(exts[0])) } var h : VkDevice vk_check(vkCreateDevice(phys, ci, null, h), null) @@ -1055,9 +993,7 @@ def public create_device(phys : VkPhysicalDevice; queue_family : uint; extension var qci = VkDeviceQueueCreateInfo() qci.queueFamilyIndex = queue_family qci.queueCount = 1u - unsafe { - qci.pQueuePriorities = addr(prio) - } + qci.pQueuePriorities = unsafe(addr(prio)) meshFeatures.sType = VkStructureType.PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT var ci = VkDeviceCreateInfo() ci.queueCreateInfoCount = 1u @@ -1069,9 +1005,7 @@ def public create_device(phys : VkPhysicalDevice; queue_family : uint; extension append_portability_subset(phys, exts) if (!empty(exts)) { ci.enabledExtensionCount = uint(length(exts)) - unsafe { - ci.ppEnabledExtensionNames = addr(exts[0]) - } + ci.ppEnabledExtensionNames = unsafe(addr(exts[0])) } var h : VkDevice vk_check(vkCreateDevice(phys, ci, null, h), null) @@ -1172,9 +1106,7 @@ def public get_device_queue(device : Device; queue_family, index : uint) : VkQue def public create_shader_module(device : Device; var code : array) : ShaderModule { var ci = VkShaderModuleCreateInfo() ci.codeSize = uint64(long_length(code)) - unsafe { - ci.pCode = addr(code[0]) - } + ci.pCode = unsafe(addr(code[0])) var h : VkShaderModule vk_check(vkCreateShaderModule(boost_value_to_vk(device), ci, null, h), null) var b = vk_value_to_boost(h) @@ -1188,9 +1120,7 @@ def public create_shader_module(device : Device; var code : array) : Shad def public create_shader_module(device : Device; var code : array) : ShaderModule { var ci = VkShaderModuleCreateInfo() ci.codeSize = uint64(long_length(code) * 4l) - unsafe { - ci.pCode = addr(code[0]) - } + ci.pCode = unsafe(addr(code[0])) var h : VkShaderModule vk_check(vkCreateShaderModule(boost_value_to_vk(device), ci, null, h), null) var b = vk_value_to_boost(h) @@ -1822,9 +1752,7 @@ def public compute_full_subgroups_supported(phys : VkPhysicalDevice) : bool { } var q13 = VkPhysicalDeviceVulkan13Features() var q2 = VkPhysicalDeviceFeatures2() - unsafe { - q2.pNext = addr(q13) - } + q2.pNext = unsafe(addr(q13)) vkGetPhysicalDeviceFeatures2(phys, q2) return q13.subgroupSizeControl != 0u && q13.computeFullSubgroups != 0u } @@ -2060,12 +1988,10 @@ def public compute_to_storage_image(var words : array; w, h : int; srgb_en region.dstOffsets[1].x = w region.dstOffsets[1].y = h region.dstOffsets[1].z = 1 - unsafe { - vkCmdBlitImage(boost_value_to_vk(cmd), - boost_value_to_vk(image), VkImageLayout.TRANSFER_SRC_OPTIMAL, - boost_value_to_vk(srgb_image), VkImageLayout.TRANSFER_DST_OPTIMAL, - 1u, addr(region), VkFilter.NEAREST) - } + vkCmdBlitImage(boost_value_to_vk(cmd), + boost_value_to_vk(image), VkImageLayout.TRANSFER_SRC_OPTIMAL, + boost_value_to_vk(srgb_image), VkImageLayout.TRANSFER_DST_OPTIMAL, + 1u, unsafe(addr(region)), VkFilter.NEAREST) transition_image(cmd, srgb_image, VkImageLayout.TRANSFER_DST_OPTIMAL, VkImageLayout.TRANSFER_SRC_OPTIMAL, transfer_write, to_read, xfer, xfer) copy_image_to_buffer(cmd, srgb_image, readback, w, h) @@ -2295,9 +2221,7 @@ def public run_cmd_sync(device : Device; pool : CommandPool; queue : VkQueue; bl ai.level = VkCommandBufferLevel.PRIMARY ai.commandBufferCount = 1u var raw_cmd : VkCommandBuffer - unsafe { - vk_check(vkAllocateCommandBuffers(boost_value_to_vk(device), ai, addr(raw_cmd)), null) - } + vk_check(vkAllocateCommandBuffers(boost_value_to_vk(device), ai, unsafe(addr(raw_cmd))), null) let cmd = vk_value_to_boost(raw_cmd) // non-owning wrapper (pool-freed below) let begin = VkCommandBufferBeginInfo() vk_check(vkBeginCommandBuffer(raw_cmd, begin), null) @@ -2310,9 +2234,7 @@ def public run_cmd_sync(device : Device; pool : CommandPool; queue : VkQueue; bl vk_check(vkQueueSubmit(queue, 1u, addr(submit), null), null) } vk_check(vkQueueWaitIdle(queue), null) - unsafe { - vkFreeCommandBuffers(boost_value_to_vk(device), boost_value_to_vk(pool), 1u, addr(raw_cmd)) - } + vkFreeCommandBuffers(boost_value_to_vk(device), boost_value_to_vk(pool), 1u, unsafe(addr(raw_cmd))) } //! begin/end a render pass around the block, clearing to `clear` @@ -2325,10 +2247,8 @@ def public record_render_pass(cmd : CommandBuffer; render_pass : RenderPass; fra rp.clearValueCount = 1u var c = clear let raw_cmd = boost_value_to_vk(cmd) - unsafe { - rp.pClearValues = addr(c) - vkCmdBeginRenderPass(raw_cmd, rp, VkSubpassContents.INLINE) - } + rp.pClearValues = unsafe(addr(c)) + vkCmdBeginRenderPass(raw_cmd, rp, VkSubpassContents.INLINE) invoke(blk) vkCmdEndRenderPass(raw_cmd) } @@ -2345,10 +2265,8 @@ def public record_render_pass(cmd : CommandBuffer; render_pass : RenderPass; fra rp.renderArea = area rp.clearValueCount = uint(length(clears)) let raw_cmd = boost_value_to_vk(cmd) - unsafe { - rp.pClearValues = addr(clears[0]) - vkCmdBeginRenderPass(raw_cmd, rp, VkSubpassContents.INLINE) - } + rp.pClearValues = unsafe(addr(clears[0])) + vkCmdBeginRenderPass(raw_cmd, rp, VkSubpassContents.INLINE) invoke(blk) vkCmdEndRenderPass(raw_cmd) } @@ -2362,9 +2280,7 @@ def public record_rendering(cmd : CommandBuffer; area : VkRect2D; layer_count : blk : block<() : void>) { var info = RenderingInfo(renderArea = area, layerCount = layer_count, viewMask = 0u, pColorAttachments <- color_attachments) - unsafe { - info.pDepthAttachment = addr(depth_attachment) - } + info.pDepthAttachment = unsafe(addr(depth_attachment)) cmd_begin_rendering(cmd, info) invoke(blk) cmd_end_rendering(cmd) @@ -2388,9 +2304,7 @@ def public record_rendering(cmd : CommandBuffer; area : VkRect2D; layer_count : def public with_mapped_memory(device : Device; memory : DeviceMemory; blk : block<(ptr : void?) : void>) { var mapped : void? = null let flags : VkMemoryMapFlags - unsafe { - vk_check(vkMapMemory(boost_value_to_vk(device), boost_value_to_vk(memory), 0ul, VK_WHOLE_SIZE, flags, addr(mapped)), null) - } + vk_check(vkMapMemory(boost_value_to_vk(device), boost_value_to_vk(memory), 0ul, VK_WHOLE_SIZE, flags, unsafe(addr(mapped))), null) invoke(blk, mapped) vkUnmapMemory(boost_value_to_vk(device), boost_value_to_vk(memory)) } @@ -2408,9 +2322,7 @@ def public with_push_staging(size : uint; blk : block<(ptr : void?) : void>) { if (int(size) > length(g_push_staging)) { g_push_staging |> resize(int(size)) } - unsafe { - invoke(blk, addr(g_push_staging[0])) - } + invoke(blk, unsafe(addr(g_push_staging[0]))) } //! Write a single typed value at a byte offset into mapped device memory (one memcpy of sizeof), for @@ -2427,9 +2339,7 @@ def public write_field(ptr : void?; offset : uint; var value : auto(TT) const) { def public map_memory_to_array(device : Device; memory : DeviceMemory; size : uint64; blk : block<(data : array) : void>) { var mapped : void? = null let flags : VkMemoryMapFlags - unsafe { - vk_check(vkMapMemory(boost_value_to_vk(device), boost_value_to_vk(memory), 0ul, size, flags, addr(mapped)), null) - } + vk_check(vkMapMemory(boost_value_to_vk(device), boost_value_to_vk(memory), 0ul, size, flags, unsafe(addr(mapped))), null) // array is int-indexed, so a >2GB mapping cannot be represented here at all — assert rather // than resize truncated and then memcpy the full width, which would run past the allocation assert(size <= uint64(0x7FFFFFFF), "map_memory_to_array: mapping exceeds the int-indexed array cap") @@ -2544,10 +2454,8 @@ def public copy_image_to_buffer(cmd : CommandBuffer; image : Image; buffer : Hos region.imageExtent.width = uint(width) region.imageExtent.height = uint(height) region.imageExtent.depth = 1u - unsafe { - vkCmdCopyImageToBuffer(boost_value_to_vk(cmd), boost_value_to_vk(image), VkImageLayout.TRANSFER_SRC_OPTIMAL, - boost_value_to_vk(buffer.buffer), 1u, addr(region)) - } + vkCmdCopyImageToBuffer(boost_value_to_vk(cmd), boost_value_to_vk(image), VkImageLayout.TRANSFER_SRC_OPTIMAL, + boost_value_to_vk(buffer.buffer), 1u, unsafe(addr(region))) } // ===== pipeline executable introspection (VK_KHR_pipeline_executable_properties) ===== @@ -2688,9 +2596,7 @@ def public create_address_buffer(device : Device; phys : VkPhysicalDevice; size flags_info.flags.device_address = true var mai = MemoryAllocateInfo(allocationSize = req.size, memoryTypeIndex = find_memory_type(phys, req.memoryTypeBits, want)) - unsafe { - mai.next = addr(flags_info) - } + mai.next = unsafe(addr(flags_info)) var inscope memory <- allocate_memory(device, mai) vk_check(vkBindBufferMemory(boost_value_to_vk(device), boost_value_to_vk(buffer), boost_value_to_vk(memory), 0ul), null) let bdai = BufferDeviceAddressInfo(buffer = weak_copy(buffer)) @@ -2721,9 +2627,7 @@ def public upload_bytes(buf : AddressBuffer; device : Device; var data : array(rtp) - } + p2.pNext = unsafe(addr(rtp)) vkGetPhysicalDeviceProperties2(phys, p2) rtp.pNext = null // don't leak the dangling chain pointer to the caller return rtp @@ -2736,10 +2640,8 @@ def public get_ray_tracing_shader_group_handles(device : Device; pipeline : Pipe first_group : uint; group_count : uint; handle_size : uint) : array { var data : array data |> resize(int(group_count * handle_size)) - unsafe { - vk_check(vkGetRayTracingShaderGroupHandlesKHR(boost_value_to_vk(device), boost_value_to_vk(pipeline), - first_group, group_count, uint64(long_length(data)), addr(data[0])), null) - } + vk_check(vkGetRayTracingShaderGroupHandlesKHR(boost_value_to_vk(device), boost_value_to_vk(pipeline), + first_group, group_count, uint64(long_length(data)), unsafe(addr(data[0]))), null) return <- data } @@ -2783,9 +2685,7 @@ def public create_ray_tracing_pipeline(device : Device; layout : PipelineLayout; var no_op : DeferredOperationKHR var no_cache : PipelineCache var pipes <- create_ray_tracing_pipelines_k_h_r(device, no_op, no_cache, infos) - unsafe { - delete infos - } + delete infos var p <- pipes[0] delete pipes return <- p @@ -2942,9 +2842,7 @@ def private build_accel_structure(device : Device; phys : VkPhysicalDevice; pool run_cmd_sync(device, pool, queue) $(cmd) { cmd_build_acceleration_structures_k_h_r(cmd, infos, ranges) } - unsafe { - delete infos - } + delete infos delete ranges let dai = AccelerationStructureDeviceAddressInfoKHR(accelerationStructure = weak_copy(handle)) let address = get_acceleration_structure_device_address_k_h_r(device, dai) diff --git a/modules/dasVulkan/daslib/vulkan_gltf.das b/modules/dasVulkan/daslib/vulkan_gltf.das index daa6e431ea..8e0d7d8ca3 100644 --- a/modules/dasVulkan/daslib/vulkan_gltf.das +++ b/modules/dasVulkan/daslib/vulkan_gltf.das @@ -239,29 +239,27 @@ struct public GltfVkModel { } def public finalize(var m : GltfVkModel) { - unsafe { - delete m.pipeline_index - delete m.pipelines - delete m.desc_sets - delete m.desc_pool - delete m.pipe_layout_skinned - delete m.pipe_layout_rigid - delete m.set_layouts_skinned - delete m.set_layouts_rigid - delete m.frag - delete m.vert_skinned - delete m.vert_rigid - delete m.skin_ubos - delete m.mat_ubos - delete m.cam_ubo - delete m.env_tex - delete m.default_sampler - delete m.flat_normal_tex - delete m.white_tex - delete m.samplers - delete m.textures - delete m.meshes - } + delete m.pipeline_index + delete m.pipelines + delete m.desc_sets + delete m.desc_pool + delete m.pipe_layout_skinned + delete m.pipe_layout_rigid + delete m.set_layouts_skinned + delete m.set_layouts_rigid + delete m.frag + delete m.vert_skinned + delete m.vert_rigid + delete m.skin_ubos + delete m.mat_ubos + delete m.cam_ubo + delete m.env_tex + delete m.default_sampler + delete m.flat_normal_tex + delete m.white_tex + delete m.samplers + delete m.textures + delete m.meshes } // ===== private helpers ===== @@ -660,9 +658,7 @@ def private emplace_env_write(var writes : array; model : Gl //! the mip chain the roughness lookup needs. Takes ownership of `env`; call between frames (device idle). //! `GltfPbrLight.environment` scales it per frame; without an environment the flat ambient is used. def public gltf_vk_set_environment(var model : GltfVkModel; device : Device; var env : Texture) { - unsafe { - delete model.env_tex - } + delete model.env_tex model.env_tex <- env model.env_max_lod = (model.env_tex.width > 0 ? floor(log2(float(max(model.env_tex.width, model.env_tex.height)))) : 0.0) diff --git a/modules/dasVulkan/daslib/vulkan_live.das b/modules/dasVulkan/daslib/vulkan_live.das index e233b1d99b..589d1cfdba 100644 --- a/modules/dasVulkan/daslib/vulkan_live.das +++ b/modules/dasVulkan/daslib/vulkan_live.das @@ -78,7 +78,7 @@ def public vk_live_set_target(device : Device; phys : VkPhysicalDevice; queue : g_last_index = -1 // a freshly registered target has no presented frame yet g_frames_rendered = 0 if (g_readback_cap > 0ul) { // drop a readback buffer from a previous target (possibly a different device) - unsafe { delete g_readback } + delete g_readback g_readback_cap = 0ul } } @@ -98,7 +98,7 @@ def private ensure_readback(nbytes : uint64) { return } if (g_readback_cap > 0ul) { - unsafe { delete g_readback } + delete g_readback } g_readback <- create_host_buffer(g.device, g.phys, nbytes) // 3-arg overload = transfer_dst usage g_readback_cap = nbytes @@ -170,7 +170,7 @@ def private set_live_viewport(cmd : CommandBuffer; width, height : int) { delete scis } -def public vk_live_draw_frame(render_pass : RenderPass; sync : FrameSync; clear : VkClearValue; // nolint:STYLE038 - flat frame-record scaffold +def public vk_live_draw_frame(render_pass : RenderPass; sync : FrameSync; clear : VkClearValue; dynamic_viewport : bool; blk : block<(cmd : CommandBuffer) : void>) : bool { //! acquire -> record (render pass + `blk`) -> submit -> present on the `vk_live_set_target` target; //! drop-in for vulkan_window's `draw_frame` that also tracks the presented image and feeds the APNG @@ -195,9 +195,7 @@ def public vk_live_draw_frame(render_pass : RenderPass; sync : FrameSync; clear ai.level = VkCommandBufferLevel.PRIMARY ai.commandBufferCount = 1u var raw_cmd : VkCommandBuffer - unsafe { - vk_check(vkAllocateCommandBuffers(dev, ai, addr(raw_cmd)), null) - } + vk_check(vkAllocateCommandBuffers(dev, ai, unsafe(addr(raw_cmd))), null) let cmd = vk_value_to_boost(raw_cmd) let begin = VkCommandBufferBeginInfo() vk_check(vkBeginCommandBuffer(raw_cmd, begin), null) @@ -238,9 +236,7 @@ def public vk_live_draw_frame(render_pass : RenderPass; sync : FrameSync; clear presented = vkQueuePresentKHR(g.queue, present) } vk_check(vkQueueWaitIdle(g.queue), null) - unsafe { - vkFreeCommandBuffers(dev, boost_value_to_vk(g.pool), 1u, addr(raw_cmd)) - } + vkFreeCommandBuffers(dev, boost_value_to_vk(g.pool), 1u, unsafe(addr(raw_cmd))) // SUBOPTIMAL is still a usable present; out-of-date or any other error -> false so the caller recreates. // Only count the frame as presented (track last-index + capture) when present actually succeeded. @@ -511,9 +507,7 @@ struct RecordStatusResult { def record_status(_input : JsonValue?) : JsonValue? { var dropped = 0 if (recorder_active) { - unsafe { - dropped = stbi_apng_dropped(recorder.writer) - } + dropped = stbi_apng_dropped(recorder.writer) } return JV(RecordStatusResult( active = recorder_active, diff --git a/modules/dasVulkan/daslib/vulkan_reflect.das b/modules/dasVulkan/daslib/vulkan_reflect.das index 36f5802f43..4bbd7a84f3 100644 --- a/modules/dasVulkan/daslib/vulkan_reflect.das +++ b/modules/dasVulkan/daslib/vulkan_reflect.das @@ -179,7 +179,7 @@ def build_pipeline_layout(device : Device; set_layouts : array write the result through the pointer; the caller decides. def public vk_check(r : VkResult; var out : VkResult?) { if (out != null) { - unsafe { - *out = r - } + *out = r } elif (r != VkResult.SUCCESS) { panic("Vulkan call failed: {r}") } diff --git a/modules/dasVulkan/daslib/vulkan_window.das b/modules/dasVulkan/daslib/vulkan_window.das index aaf6c686b1..44c31c741f 100644 --- a/modules/dasVulkan/daslib/vulkan_window.das +++ b/modules/dasVulkan/daslib/vulkan_window.das @@ -76,9 +76,7 @@ def private choose_surface_format(phys : VkPhysicalDevice; surface : SurfaceKHR; vk_check(vkGetPhysicalDeviceSurfaceFormatsKHR(phys, boost_value_to_vk(surface), count, null), null) var formats : array formats |> resize(int(count)) - unsafe { - vk_check(vkGetPhysicalDeviceSurfaceFormatsKHR(phys, boost_value_to_vk(surface), count, addr(formats[0])), null) - } + vk_check(vkGetPhysicalDeviceSurfaceFormatsKHR(phys, boost_value_to_vk(surface), count, unsafe(addr(formats[0]))), null) // 1. explicit preference: UNORM presents pass-through (UI/2D, no double sRGB encode), sRGB suits linear-lit 3D. if (preferred != VkFormat.UNDEFINED) { // sRGB-nonlinear colorspace first (predictable presentation), then the format with any colorspace. @@ -154,9 +152,7 @@ def public create_swapchain(device : Device; phys : VkPhysicalDevice; surface : var got = 0u vk_check(vkGetSwapchainImagesKHR(dev, boost_value_to_vk(sc.handle), got, null), null) sc.images |> resize(int(got)) - unsafe { - vk_check(vkGetSwapchainImagesKHR(dev, boost_value_to_vk(sc.handle), got, addr(sc.images[0])), null) - } + vk_check(vkGetSwapchainImagesKHR(dev, boost_value_to_vk(sc.handle), got, unsafe(addr(sc.images[0]))), null) // one image view per image sc.views |> reserve(length(sc.images)) @@ -250,9 +246,7 @@ def public draw_frame(device : Device; queue : VkQueue; sc : Swapchain; render_p ai.level = VkCommandBufferLevel.PRIMARY ai.commandBufferCount = 1u var raw_cmd : VkCommandBuffer - unsafe { - vk_check(vkAllocateCommandBuffers(dev, ai, addr(raw_cmd)), null) - } + vk_check(vkAllocateCommandBuffers(dev, ai, unsafe(addr(raw_cmd))), null) let cmd = vk_value_to_boost(raw_cmd) let begin = VkCommandBufferBeginInfo() vk_check(vkBeginCommandBuffer(raw_cmd, begin), null) @@ -293,9 +287,7 @@ def public draw_frame(device : Device; queue : VkQueue; sc : Swapchain; render_p presented = vkQueuePresentKHR(queue, present) } vk_check(vkQueueWaitIdle(queue), null) - unsafe { - vkFreeCommandBuffers(dev, boost_value_to_vk(pool), 1u, addr(raw_cmd)) - } + vkFreeCommandBuffers(dev, boost_value_to_vk(pool), 1u, unsafe(addr(raw_cmd))) return presented != VkResult.ERROR_OUT_OF_DATE_KHR } @@ -318,9 +310,7 @@ def public present_frame(device : Device; queue : VkQueue; sc : Swapchain; pool ai.level = VkCommandBufferLevel.PRIMARY ai.commandBufferCount = 1u var raw_cmd : VkCommandBuffer - unsafe { - vk_check(vkAllocateCommandBuffers(dev, ai, addr(raw_cmd)), null) - } + vk_check(vkAllocateCommandBuffers(dev, ai, unsafe(addr(raw_cmd))), null) let cmd = vk_value_to_boost(raw_cmd) let begin = VkCommandBufferBeginInfo() vk_check(vkBeginCommandBuffer(raw_cmd, begin), null) @@ -355,8 +345,6 @@ def public present_frame(device : Device; queue : VkQueue; sc : Swapchain; pool presented = vkQueuePresentKHR(queue, present) } vk_check(vkQueueWaitIdle(queue), null) - unsafe { - vkFreeCommandBuffers(dev, boost_value_to_vk(pool), 1u, addr(raw_cmd)) - } + vkFreeCommandBuffers(dev, boost_value_to_vk(pool), 1u, unsafe(addr(raw_cmd))) return presented != VkResult.ERROR_OUT_OF_DATE_KHR } diff --git a/modules/dasVulkan/examples/compute.das b/modules/dasVulkan/examples/compute.das index 184d1a2d21..9d1b1cbc51 100644 --- a/modules/dasVulkan/examples/compute.das +++ b/modules/dasVulkan/examples/compute.das @@ -38,9 +38,7 @@ def main() : int { // nolint:STYLE038 - flat example scaffold vkGetPhysicalDeviceQueueFamilyProperties(phys, qcount, null) var qprops : array qprops |> resize(int(qcount)) - unsafe { - vkGetPhysicalDeviceQueueFamilyProperties(phys, qcount, addr(qprops[0])) - } + vkGetPhysicalDeviceQueueFamilyProperties(phys, qcount, unsafe(addr(qprops[0]))) var fam = -1 for (i in range(int(qcount))) { if (qprops[i].queueFlags.compute) { @@ -85,10 +83,8 @@ def main() : int { // nolint:STYLE038 - flat example scaffold var dslci = VkDescriptorSetLayoutCreateInfo() dslci.bindingCount = 1u var set_layout : VkDescriptorSetLayout - unsafe { - dslci.pBindings = addr(binding) - vk_check(vkCreateDescriptorSetLayout(dev, dslci, null, set_layout), null) - } + dslci.pBindings = unsafe(addr(binding)) + vk_check(vkCreateDescriptorSetLayout(dev, dslci, null, set_layout), null) // ---- descriptor pool + set ---- var pool_size : VkDescriptorPoolSize @@ -98,10 +94,8 @@ def main() : int { // nolint:STYLE038 - flat example scaffold dpci.maxSets = 1u dpci.poolSizeCount = 1u var desc_pool : VkDescriptorPool - unsafe { - dpci.pPoolSizes = addr(pool_size) - vk_check(vkCreateDescriptorPool(dev, dpci, null, desc_pool), null) - } + dpci.pPoolSizes = unsafe(addr(pool_size)) + vk_check(vkCreateDescriptorPool(dev, dpci, null, desc_pool), null) var dsai = VkDescriptorSetAllocateInfo() dsai.descriptorPool = desc_pool dsai.descriptorSetCount = 1u @@ -128,10 +122,8 @@ def main() : int { // nolint:STYLE038 - flat example scaffold var plci = VkPipelineLayoutCreateInfo() plci.setLayoutCount = 1u var pipe_layout : VkPipelineLayout - unsafe { - plci.pSetLayouts = addr(set_layout) - vk_check(vkCreatePipelineLayout(dev, plci, null, pipe_layout), null) - } + plci.pSetLayouts = unsafe(addr(set_layout)) + vk_check(vkCreatePipelineLayout(dev, plci, null, pipe_layout), null) var stage = VkPipelineShaderStageCreateInfo() stage.stage.compute = true stage.module_ = boost_value_to_vk(shader) @@ -150,18 +142,14 @@ def main() : int { // nolint:STYLE038 - flat example scaffold // pipeline/layout/desc_set are raw here (raw descriptor setup), so unwrap the // command buffer; cmd_dispatch is a generated boost wrapper taking CommandBuffer. vkCmdBindPipeline(boost_value_to_vk(cmd), VkPipelineBindPoint.COMPUTE, pipeline) - unsafe { - vkCmdBindDescriptorSets(boost_value_to_vk(cmd), VkPipelineBindPoint.COMPUTE, pipe_layout, 0u, 1u, addr(desc_set), 0u, null) - } + vkCmdBindDescriptorSets(boost_value_to_vk(cmd), VkPipelineBindPoint.COMPUTE, pipe_layout, 0u, 1u, unsafe(addr(desc_set)), 0u, null) cmd_dispatch(cmd, uint(N / GROUP), 1u, 1u) } // ---- read back + verify ---- var mapped : void? = null let mf : VkMemoryMapFlags - unsafe { - vk_check(vkMapMemory(dev, memory, 0ul, buf_size, mf, addr(mapped)), null) - } + vk_check(vkMapMemory(dev, memory, 0ul, buf_size, mf, unsafe(addr(mapped))), null) var values : array values |> resize(N) unsafe { diff --git a/modules/dasVulkan/examples/device_probe.das b/modules/dasVulkan/examples/device_probe.das index 6391af4e65..9f9f09b7e7 100644 --- a/modules/dasVulkan/examples/device_probe.das +++ b/modules/dasVulkan/examples/device_probe.das @@ -4,7 +4,7 @@ options _comment_hygiene = true require vulkan [export] -def main() { // nolint:STYLE038 - flat example scaffold +def main() { if (volkInitialize() != 0) { print("no Vulkan\n") return @@ -14,9 +14,7 @@ def main() { // nolint:STYLE038 - flat example scaffold ai.apiVersion = (1u << 22u) | (3u << 12u) var ici : VkInstanceCreateInfo ici.sType = VkStructureType.INSTANCE_CREATE_INFO - unsafe { - ici.pApplicationInfo = addr(ai) - } + ici.pApplicationInfo = unsafe(addr(ai)) var instance : VkInstance if (vkCreateInstance(ici, null, instance) != VkResult.SUCCESS) { print("instance failed\n") @@ -33,9 +31,7 @@ def main() { // nolint:STYLE038 - flat example scaffold } var devices : array devices |> resize(int(count)) - unsafe { - vkEnumeratePhysicalDevices(instance, count, addr(devices[0])) - } + vkEnumeratePhysicalDevices(instance, count, unsafe(addr(devices[0]))) let phys = devices[0] // find a graphics queue family -- exercises bitfield field access @@ -43,9 +39,7 @@ def main() { // nolint:STYLE038 - flat example scaffold vkGetPhysicalDeviceQueueFamilyProperties(phys, qcount, null) var qprops : array qprops |> resize(int(qcount)) - unsafe { - vkGetPhysicalDeviceQueueFamilyProperties(phys, qcount, addr(qprops[0])) - } + vkGetPhysicalDeviceQueueFamilyProperties(phys, qcount, unsafe(addr(qprops[0]))) var gfx_family = -1 for (i in range(int(qcount))) { if (qprops[i].queueFlags.graphics) { @@ -64,15 +58,11 @@ def main() { // nolint:STYLE038 - flat example scaffold qci.sType = VkStructureType.DEVICE_QUEUE_CREATE_INFO qci.queueFamilyIndex = uint(gfx_family) qci.queueCount = 1u - unsafe { - qci.pQueuePriorities = addr(priority) - } + qci.pQueuePriorities = unsafe(addr(priority)) var dci : VkDeviceCreateInfo dci.sType = VkStructureType.DEVICE_CREATE_INFO dci.queueCreateInfoCount = 1u - unsafe { - dci.pQueueCreateInfos = addr(qci) - } + dci.pQueueCreateInfos = unsafe(addr(qci)) var device : VkDevice if (vkCreateDevice(phys, dci, null, device) != VkResult.SUCCESS) { print("device failed\n") diff --git a/modules/dasVulkan/examples/enumerate.das b/modules/dasVulkan/examples/enumerate.das index 6c4a906bf0..bcc9f0f930 100644 --- a/modules/dasVulkan/examples/enumerate.das +++ b/modules/dasVulkan/examples/enumerate.das @@ -31,9 +31,7 @@ def main() : int { } var devices : array devices |> resize(int(count)) - unsafe { - vkEnumeratePhysicalDevices(boost_value_to_vk(instance), count, addr(devices[0])) - } + vkEnumeratePhysicalDevices(boost_value_to_vk(instance), count, unsafe(addr(devices[0]))) for (d in devices) { var props : VkPhysicalDeviceProperties @@ -47,9 +45,7 @@ def main() : int { vkGetPhysicalDeviceQueueFamilyProperties(d, qcount, null) var qprops : array qprops |> resize(int(qcount)) - unsafe { - vkGetPhysicalDeviceQueueFamilyProperties(d, qcount, addr(qprops[0])) - } + vkGetPhysicalDeviceQueueFamilyProperties(d, qcount, unsafe(addr(qprops[0]))) print(" queue families: {int(qcount)}\n") for (i in range(int(qcount))) { let f = qprops[i].queueFlags diff --git a/modules/dasVulkan/examples/offscreen_triangle.das b/modules/dasVulkan/examples/offscreen_triangle.das index 8ed611489e..2cfc3afa19 100644 --- a/modules/dasVulkan/examples/offscreen_triangle.das +++ b/modules/dasVulkan/examples/offscreen_triangle.das @@ -57,9 +57,7 @@ def create_shader_module(device : VkDevice; var code : array) : VkShaderMo var sci : VkShaderModuleCreateInfo sci.sType = VkStructureType.SHADER_MODULE_CREATE_INFO sci.codeSize = uint64(long_length(code) * 4l) - unsafe { - sci.pCode = addr(code[0]) - } + sci.pCode = unsafe(addr(code[0])) var sm : VkShaderModule check(vkCreateShaderModule(device, sci, null, sm), "create shader module") return sm @@ -78,9 +76,7 @@ def main() : int { // nolint:STYLE038 - flat example scaffold ai.apiVersion = (1u << 22u) | (3u << 12u) var ici : VkInstanceCreateInfo ici.sType = VkStructureType.INSTANCE_CREATE_INFO - unsafe { - ici.pApplicationInfo = addr(ai) - } + ici.pApplicationInfo = unsafe(addr(ai)) var instance : VkInstance check(vkCreateInstance(ici, null, instance), "create instance") volkLoadInstance(instance) @@ -93,18 +89,14 @@ def main() : int { // nolint:STYLE038 - flat example scaffold } var devices : array devices |> resize(int(count)) - unsafe { - vkEnumeratePhysicalDevices(instance, count, addr(devices[0])) - } + vkEnumeratePhysicalDevices(instance, count, unsafe(addr(devices[0]))) let phys = devices[0] var qcount = 0u vkGetPhysicalDeviceQueueFamilyProperties(phys, qcount, null) var qprops : array qprops |> resize(int(qcount)) - unsafe { - vkGetPhysicalDeviceQueueFamilyProperties(phys, qcount, addr(qprops[0])) - } + vkGetPhysicalDeviceQueueFamilyProperties(phys, qcount, unsafe(addr(qprops[0]))) var gfx = -1 for (i in range(int(qcount))) { if (qprops[i].queueFlags.graphics) { @@ -122,15 +114,11 @@ def main() : int { // nolint:STYLE038 - flat example scaffold qci.sType = VkStructureType.DEVICE_QUEUE_CREATE_INFO qci.queueFamilyIndex = uint(gfx) qci.queueCount = 1u - unsafe { - qci.pQueuePriorities = addr(priority) - } + qci.pQueuePriorities = unsafe(addr(priority)) var dci : VkDeviceCreateInfo dci.sType = VkStructureType.DEVICE_CREATE_INFO dci.queueCreateInfoCount = 1u - unsafe { - dci.pQueueCreateInfos = addr(qci) - } + dci.pQueueCreateInfos = unsafe(addr(qci)) var device : VkDevice check(vkCreateDevice(phys, dci, null, device), "create device") volkLoadDevice(device) @@ -197,20 +185,14 @@ def main() : int { // nolint:STYLE038 - flat example scaffold var subpass : VkSubpassDescription subpass.pipelineBindPoint = VkPipelineBindPoint.GRAPHICS subpass.colorAttachmentCount = 1u - unsafe { - subpass.pColorAttachments = addr(color_ref) - } + subpass.pColorAttachments = unsafe(addr(color_ref)) var rp_ci : VkRenderPassCreateInfo rp_ci.sType = VkStructureType.RENDER_PASS_CREATE_INFO rp_ci.attachmentCount = 1u - unsafe { - rp_ci.pAttachments = addr(attach) - } + rp_ci.pAttachments = unsafe(addr(attach)) rp_ci.subpassCount = 1u - unsafe { - rp_ci.pSubpasses = addr(subpass) - } + rp_ci.pSubpasses = unsafe(addr(subpass)) var render_pass : VkRenderPass check(vkCreateRenderPass(device, rp_ci, null, render_pass), "create render pass") @@ -219,9 +201,7 @@ def main() : int { // nolint:STYLE038 - flat example scaffold fb_ci.sType = VkStructureType.FRAMEBUFFER_CREATE_INFO fb_ci.renderPass = render_pass fb_ci.attachmentCount = 1u - unsafe { - fb_ci.pAttachments = addr(color_view) - } + fb_ci.pAttachments = unsafe(addr(color_view)) fb_ci.width = uint(WIDTH) fb_ci.height = uint(HEIGHT) fb_ci.layers = 1u @@ -261,13 +241,9 @@ def main() : int { // nolint:STYLE038 - flat example scaffold var vpstate : VkPipelineViewportStateCreateInfo vpstate.sType = VkStructureType.PIPELINE_VIEWPORT_STATE_CREATE_INFO vpstate.viewportCount = 1u - unsafe { - vpstate.pViewports = addr(viewport) - } + vpstate.pViewports = unsafe(addr(viewport)) vpstate.scissorCount = 1u - unsafe { - vpstate.pScissors = addr(scissor) - } + vpstate.pScissors = unsafe(addr(scissor)) var raster : VkPipelineRasterizationStateCreateInfo raster.sType = VkStructureType.PIPELINE_RASTERIZATION_STATE_CREATE_INFO @@ -288,9 +264,7 @@ def main() : int { // nolint:STYLE038 - flat example scaffold var blend : VkPipelineColorBlendStateCreateInfo blend.sType = VkStructureType.PIPELINE_COLOR_BLEND_STATE_CREATE_INFO blend.attachmentCount = 1u - unsafe { - blend.pAttachments = addr(blend_att) - } + blend.pAttachments = unsafe(addr(blend_att)) var pl_ci : VkPipelineLayoutCreateInfo pl_ci.sType = VkStructureType.PIPELINE_LAYOUT_CREATE_INFO @@ -351,9 +325,7 @@ def main() : int { // nolint:STYLE038 - flat example scaffold cb_ai.level = VkCommandBufferLevel.PRIMARY cb_ai.commandBufferCount = 1u var cmd : VkCommandBuffer - unsafe { - check(vkAllocateCommandBuffers(device, cb_ai, addr(cmd)), "alloc command buffer") - } + check(vkAllocateCommandBuffers(device, cb_ai, unsafe(addr(cmd))), "alloc command buffer") var begin : VkCommandBufferBeginInfo begin.sType = VkStructureType.COMMAND_BUFFER_BEGIN_INFO @@ -371,9 +343,7 @@ def main() : int { // nolint:STYLE038 - flat example scaffold rp_begin.renderArea.extent.width = uint(WIDTH) rp_begin.renderArea.extent.height = uint(HEIGHT) rp_begin.clearValueCount = 1u - unsafe { - rp_begin.pClearValues = addr(clear) - } + rp_begin.pClearValues = unsafe(addr(clear)) vkCmdBeginRenderPass(cmd, rp_begin, VkSubpassContents.INLINE) vkCmdBindPipeline(cmd, VkPipelineBindPoint.GRAPHICS, pipeline) vkCmdDraw(cmd, 3u, 1u, 0u, 0u) @@ -386,29 +356,21 @@ def main() : int { // nolint:STYLE038 - flat example scaffold region.imageExtent.width = uint(WIDTH) region.imageExtent.height = uint(HEIGHT) region.imageExtent.depth = 1u - unsafe { - vkCmdCopyImageToBuffer(cmd, color_image, VkImageLayout.TRANSFER_SRC_OPTIMAL, readback, 1u, addr(region)) - } + vkCmdCopyImageToBuffer(cmd, color_image, VkImageLayout.TRANSFER_SRC_OPTIMAL, readback, 1u, unsafe(addr(region))) check(vkEndCommandBuffer(cmd), "end command buffer") // ----- submit + wait ----- var submit : VkSubmitInfo submit.sType = VkStructureType.SUBMIT_INFO submit.commandBufferCount = 1u - unsafe { - submit.pCommandBuffers = addr(cmd) - } - unsafe { - check(vkQueueSubmit(queue, 1u, addr(submit), null), "queue submit") - } + submit.pCommandBuffers = unsafe(addr(cmd)) + check(vkQueueSubmit(queue, 1u, unsafe(addr(submit)), null), "queue submit") check(vkQueueWaitIdle(queue), "wait idle") // ----- read back pixels ----- var mapped : void? = null let map_flags : VkMemoryMapFlags - unsafe { - check(vkMapMemory(device, buf_mem, 0ul, buf_size, map_flags, addr(mapped)), "map memory") - } + check(vkMapMemory(device, buf_mem, 0ul, buf_size, map_flags, unsafe(addr(mapped))), "map memory") var pixels : array pixels |> resize(WIDTH * HEIGHT * 4) unsafe { diff --git a/modules/dasVulkan/examples/smoke.das b/modules/dasVulkan/examples/smoke.das index 509d5bfebb..130b2369d1 100644 --- a/modules/dasVulkan/examples/smoke.das +++ b/modules/dasVulkan/examples/smoke.das @@ -20,9 +20,7 @@ def main() { var ci : VkInstanceCreateInfo ci.sType = VkStructureType.INSTANCE_CREATE_INFO - unsafe { - ci.pApplicationInfo = addr(app_info) - } + ci.pApplicationInfo = unsafe(addr(app_info)) var instance : VkInstance let crc = vkCreateInstance(ci, null, instance) @@ -40,9 +38,7 @@ def main() { if (count > 0u) { var devices : array devices |> resize(int(count)) - unsafe { - vkEnumeratePhysicalDevices(instance, count, addr(devices[0])) - } + vkEnumeratePhysicalDevices(instance, count, unsafe(addr(devices[0]))) for (d in devices) { var props : VkPhysicalDeviceProperties vkGetPhysicalDeviceProperties(d, props) diff --git a/modules/dasVulkan/tests/integration/scene_helpers.das b/modules/dasVulkan/tests/integration/scene_helpers.das index 64792c695d..e4cd20e159 100644 --- a/modules/dasVulkan/tests/integration/scene_helpers.das +++ b/modules/dasVulkan/tests/integration/scene_helpers.das @@ -109,10 +109,8 @@ def public run_compute(n : int) : array { // nolint:STYLE038 - flat comm var dslci = VkDescriptorSetLayoutCreateInfo() dslci.bindingCount = 1u var set_layout : VkDescriptorSetLayout - unsafe { - dslci.pBindings = addr(binding) - vk_check(vkCreateDescriptorSetLayout(dev, dslci, null, set_layout), null) - } + dslci.pBindings = unsafe(addr(binding)) + vk_check(vkCreateDescriptorSetLayout(dev, dslci, null, set_layout), null) var pool_size : VkDescriptorPoolSize pool_size.type_ = VkDescriptorType.STORAGE_BUFFER pool_size.descriptorCount = 1u @@ -120,10 +118,8 @@ def public run_compute(n : int) : array { // nolint:STYLE038 - flat comm dpci.maxSets = 1u dpci.poolSizeCount = 1u var desc_pool : VkDescriptorPool - unsafe { - dpci.pPoolSizes = addr(pool_size) - vk_check(vkCreateDescriptorPool(dev, dpci, null, desc_pool), null) - } + dpci.pPoolSizes = unsafe(addr(pool_size)) + vk_check(vkCreateDescriptorPool(dev, dpci, null, desc_pool), null) var dsai = VkDescriptorSetAllocateInfo() dsai.descriptorPool = desc_pool dsai.descriptorSetCount = 1u @@ -147,10 +143,8 @@ def public run_compute(n : int) : array { // nolint:STYLE038 - flat comm var plci = VkPipelineLayoutCreateInfo() plci.setLayoutCount = 1u var pipe_layout : VkPipelineLayout - unsafe { - plci.pSetLayouts = addr(set_layout) - vk_check(vkCreatePipelineLayout(dev, plci, null, pipe_layout), null) - } + plci.pSetLayouts = unsafe(addr(set_layout)) + vk_check(vkCreatePipelineLayout(dev, plci, null, pipe_layout), null) var stage = VkPipelineShaderStageCreateInfo() stage.stage.compute = true stage.module_ = boost_value_to_vk(shader) @@ -167,9 +161,7 @@ def public run_compute(n : int) : array { // nolint:STYLE038 - flat comm var inscope pool <- create_command_pool(device, poolci) run_cmd_sync(device, pool, queue) $(cmd) { vkCmdBindPipeline(boost_value_to_vk(cmd), VkPipelineBindPoint.COMPUTE, pipeline) - unsafe { - vkCmdBindDescriptorSets(boost_value_to_vk(cmd), VkPipelineBindPoint.COMPUTE, pipe_layout, 0u, 1u, addr(desc_set), 0u, null) - } + vkCmdBindDescriptorSets(boost_value_to_vk(cmd), VkPipelineBindPoint.COMPUTE, pipe_layout, 0u, 1u, unsafe(addr(desc_set)), 0u, null) cmd_dispatch(cmd, uint(n / 64), 1u, 1u) } var mapped : void? = null @@ -308,9 +300,7 @@ def public run_compute_spirv(var words : array; n : int) : array { var inscope pool <- create_command_pool(device, pool_info(gfx)) run_cmd_sync(device, pool, queue) $(cmd) { vkCmdBindPipeline(boost_value_to_vk(cmd), VkPipelineBindPoint.COMPUTE, pipeline) - unsafe { - vkCmdBindDescriptorSets(boost_value_to_vk(cmd), VkPipelineBindPoint.COMPUTE, boost_value_to_vk(pipe_layout), 0u, 1u, addr(raw_set), 0u, null) - } + vkCmdBindDescriptorSets(boost_value_to_vk(cmd), VkPipelineBindPoint.COMPUTE, boost_value_to_vk(pipe_layout), 0u, 1u, unsafe(addr(raw_set)), 0u, null) cmd_dispatch(cmd, uint(n / 64), 1u, 1u) } @@ -1074,9 +1064,7 @@ def public render_textured_quad() : array { // nolint:STYLE038 - flat c cmd_bind_descriptor_sets(cmd, VkPipelineBindPoint.GRAPHICS, pipe_layout, 0u, sets, no_dyn) var pcf : VkShaderStageFlags pcf.fragment = true - unsafe { - vkCmdPushConstants(raw_cmd, boost_value_to_vk(pipe_layout), pcf, 0u, push_size, addr(tint[0])) - } + vkCmdPushConstants(raw_cmd, boost_value_to_vk(pipe_layout), pcf, 0u, push_size, unsafe(addr(tint[0]))) cmd_draw(cmd, 6u) } copy_image_to_buffer(cmd, target.image, readback, TRI_W, TRI_H) diff --git a/modules/dasVulkan/tests/integration/test_bindless_descriptor_array.das b/modules/dasVulkan/tests/integration/test_bindless_descriptor_array.das index c3e5faddad..32218727ae 100644 --- a/modules/dasVulkan/tests/integration/test_bindless_descriptor_array.das +++ b/modules/dasVulkan/tests/integration/test_bindless_descriptor_array.das @@ -243,9 +243,7 @@ def private render_one_id(id : int) : array { // nolint:STYLE038 - flat cmd_bind_descriptor_sets(cmd, VkPipelineBindPoint.GRAPHICS, pipe_layout, 0u, sets, no_dyn) var pcf : VkShaderStageFlags pcf.fragment = true - unsafe { - vkCmdPushConstants(raw_cmd, boost_value_to_vk(pipe_layout), pcf, 0u, 4u, addr(pushed[0])) - } + vkCmdPushConstants(raw_cmd, boost_value_to_vk(pipe_layout), pcf, 0u, 4u, unsafe(addr(pushed[0]))) cmd_draw(cmd, 3u) } copy_image_to_buffer(cmd, target.image, readback, TEX_W, TEX_H) diff --git a/modules/dasVulkan/tests/integration/test_compute_features.das b/modules/dasVulkan/tests/integration/test_compute_features.das index c77512fa1d..dd51bfef0b 100644 --- a/modules/dasVulkan/tests/integration/test_compute_features.das +++ b/modules/dasVulkan/tests/integration/test_compute_features.das @@ -212,9 +212,7 @@ def run_multi(var words : array; var bufs : array>; groups : var inscope pool <- create_command_pool(device, cpci) run_cmd_sync(device, pool, queue) $(cmd) { cmd_bind_pipeline(cmd, pipeline, VkPipelineBindPoint.COMPUTE) - unsafe { - vkCmdBindDescriptorSets(boost_value_to_vk(cmd), VkPipelineBindPoint.COMPUTE, boost_value_to_vk(pipe_layout), 0u, 1u, addr(raw_set), 0u, null) - } + vkCmdBindDescriptorSets(boost_value_to_vk(cmd), VkPipelineBindPoint.COMPUTE, boost_value_to_vk(pipe_layout), 0u, 1u, unsafe(addr(raw_set)), 0u, null) cmd_dispatch(cmd, groups, 1u, 1u) } diff --git a/modules/dasVulkan/tests/integration/test_compute_shared.das b/modules/dasVulkan/tests/integration/test_compute_shared.das index 235a123bf4..926c0ed224 100644 --- a/modules/dasVulkan/tests/integration/test_compute_shared.das +++ b/modules/dasVulkan/tests/integration/test_compute_shared.das @@ -90,10 +90,8 @@ def private run_compute_shared() : array { // nolint:STYLE038 - flat com var dslci = VkDescriptorSetLayoutCreateInfo() dslci.bindingCount = 1u var set_layout : VkDescriptorSetLayout - unsafe { - dslci.pBindings = addr(binding) - vk_check(vkCreateDescriptorSetLayout(dev, dslci, null, set_layout), null) - } + dslci.pBindings = unsafe(addr(binding)) + vk_check(vkCreateDescriptorSetLayout(dev, dslci, null, set_layout), null) var pool_size : VkDescriptorPoolSize pool_size.type_ = VkDescriptorType.STORAGE_BUFFER pool_size.descriptorCount = 1u @@ -101,10 +99,8 @@ def private run_compute_shared() : array { // nolint:STYLE038 - flat com dpci.maxSets = 1u dpci.poolSizeCount = 1u var desc_pool : VkDescriptorPool - unsafe { - dpci.pPoolSizes = addr(pool_size) - vk_check(vkCreateDescriptorPool(dev, dpci, null, desc_pool), null) - } + dpci.pPoolSizes = unsafe(addr(pool_size)) + vk_check(vkCreateDescriptorPool(dev, dpci, null, desc_pool), null) var dsai = VkDescriptorSetAllocateInfo() dsai.descriptorPool = desc_pool dsai.descriptorSetCount = 1u @@ -129,10 +125,8 @@ def private run_compute_shared() : array { // nolint:STYLE038 - flat com var plci = VkPipelineLayoutCreateInfo() plci.setLayoutCount = 1u var pipe_layout : VkPipelineLayout - unsafe { - plci.pSetLayouts = addr(set_layout) - vk_check(vkCreatePipelineLayout(dev, plci, null, pipe_layout), null) - } + plci.pSetLayouts = unsafe(addr(set_layout)) + vk_check(vkCreatePipelineLayout(dev, plci, null, pipe_layout), null) var stage = VkPipelineShaderStageCreateInfo() stage.stage.compute = true stage.module_ = boost_value_to_vk(shader) @@ -150,10 +144,8 @@ def private run_compute_shared() : array { // nolint:STYLE038 - flat com var inscope pool <- create_command_pool(device, poolci) run_cmd_sync(device, pool, queue) $(cmd) { vkCmdBindPipeline(boost_value_to_vk(cmd), VkPipelineBindPoint.COMPUTE, pipeline) - unsafe { - vkCmdBindDescriptorSets(boost_value_to_vk(cmd), VkPipelineBindPoint.COMPUTE, pipe_layout, - 0u, 1u, addr(desc_set), 0u, null) - } + vkCmdBindDescriptorSets(boost_value_to_vk(cmd), VkPipelineBindPoint.COMPUTE, pipe_layout, + 0u, 1u, unsafe(addr(desc_set)), 0u, null) vkCmdDispatch(boost_value_to_vk(cmd), 1u, 1u, 1u) } diff --git a/modules/dasVulkan/tests/integration/test_nonuniform_ext.das b/modules/dasVulkan/tests/integration/test_nonuniform_ext.das index 4e53f6a2e1..26c5d824b3 100644 --- a/modules/dasVulkan/tests/integration/test_nonuniform_ext.das +++ b/modules/dasVulkan/tests/integration/test_nonuniform_ext.das @@ -239,9 +239,7 @@ def private render_one_id(id : int) : array { // nolint:STYLE038 - flat cmd_bind_descriptor_sets(cmd, VkPipelineBindPoint.GRAPHICS, pipe_layout, 0u, sets, no_dyn) var pcf : VkShaderStageFlags pcf.fragment = true - unsafe { - vkCmdPushConstants(raw_cmd, boost_value_to_vk(pipe_layout), pcf, 0u, 4u, addr(pushed[0])) - } + vkCmdPushConstants(raw_cmd, boost_value_to_vk(pipe_layout), pcf, 0u, 4u, unsafe(addr(pushed[0]))) cmd_draw(cmd, 3u) } copy_image_to_buffer(cmd, target.image, readback, TEX_W, TEX_H) diff --git a/modules/dasVulkan/tests/integration/test_opt_ptr_view_semantics.das b/modules/dasVulkan/tests/integration/test_opt_ptr_view_semantics.das index 74d2c24216..4f2d2007aa 100644 --- a/modules/dasVulkan/tests/integration/test_opt_ptr_view_semantics.das +++ b/modules/dasVulkan/tests/integration/test_opt_ptr_view_semantics.das @@ -22,9 +22,7 @@ def test_opt_ptr_view_semantics(t : T?) { var st : PipelineShaderStageCreateInfo // null module -- never handed to a driver st.stage.vertex = true gp.pStages <- [st] - unsafe { - gp.pViewportState = addr(vp) - } + gp.pViewportState = unsafe(addr(vp)) t |> success(gp.pViewportState != null, "opt-ptr field set before viewing") let vk1 = vk_view_create_unsafe(gp) diff --git a/modules/dasVulkan/tests/integration/test_os_video_memory.das b/modules/dasVulkan/tests/integration/test_os_video_memory.das index eef0ca9b35..1192fa9464 100644 --- a/modules/dasVulkan/tests/integration/test_os_video_memory.das +++ b/modules/dasVulkan/tests/integration/test_os_video_memory.das @@ -17,9 +17,7 @@ def test_os_video_memory(t : T?) { let phys = select_physical_device(instance) var idp = VkPhysicalDeviceIDProperties() var p2 = VkPhysicalDeviceProperties2() - unsafe { - p2.pNext = addr(idp) - } + p2.pNext = unsafe(addr(idp)) vkGetPhysicalDeviceProperties2(phys, p2) let os = os_video_memory(phys) let answered = os.budget > 0ul diff --git a/modules/dasVulkan/tests/integration/test_ubo_nested.das b/modules/dasVulkan/tests/integration/test_ubo_nested.das index 5da2b9955a..65032a4ba4 100644 --- a/modules/dasVulkan/tests/integration/test_ubo_nested.das +++ b/modules/dasVulkan/tests/integration/test_ubo_nested.das @@ -213,9 +213,7 @@ def private render_one_id(id : int) : array { // nolint:STYLE038 - flat cmd_bind_descriptor_sets(cmd, VkPipelineBindPoint.GRAPHICS, pipe_layout, 0u, sets, no_dyn) var pcf : VkShaderStageFlags pcf.fragment = true - unsafe { - vkCmdPushConstants(raw_cmd, boost_value_to_vk(pipe_layout), pcf, 0u, 4u, addr(pushed[0])) - } + vkCmdPushConstants(raw_cmd, boost_value_to_vk(pipe_layout), pcf, 0u, 4u, unsafe(addr(pushed[0]))) cmd_draw(cmd, 3u) } copy_image_to_buffer(cmd, target.image, readback, TEX_W, TEX_H) diff --git a/modules/dasVulkan/tutorials/02_mandelbrot/window/mandelbrot_compute.das b/modules/dasVulkan/tutorials/02_mandelbrot/window/mandelbrot_compute.das index 75a4eb206d..6f1a39b166 100644 --- a/modules/dasVulkan/tutorials/02_mandelbrot/window/mandelbrot_compute.das +++ b/modules/dasVulkan/tutorials/02_mandelbrot/window/mandelbrot_compute.das @@ -117,7 +117,7 @@ def public build_mandel_compute(device : Device; phys : VkPhysicalDevice; var wo plci.pPushConstantRanges |> emplace(pcr) var inscope pipe_layout <- create_pipeline_layout(device, plci) delete plci.pPushConstantRanges // owned input freed once the layout has copied the range - unsafe { delete plci.pSetLayouts } // the [weak_copy(set_layout)] literal we built above (handles non-owning) + delete plci.pSetLayouts // the [weak_copy(set_layout)] literal we built above (handles non-owning) var inscope pipeline <- create_compute_pipeline(device, pipe_layout, shader) return <- MandelCompute(image <- image, memory <- imem, view <- view, set_layout <- set_layout, diff --git a/modules/dasVulkan/tutorials/03_sdf/sdf_tut.das b/modules/dasVulkan/tutorials/03_sdf/sdf_tut.das index ecedbf4ee3..188ff20e35 100644 --- a/modules/dasVulkan/tutorials/03_sdf/sdf_tut.das +++ b/modules/dasVulkan/tutorials/03_sdf/sdf_tut.das @@ -36,21 +36,19 @@ struct public SdfRenderer { } def public finalize(var r : SdfRenderer) { - unsafe { - delete r.readback - delete r.pipeline - delete r.pipe_layout - delete r.desc_pool // frees the descriptor set allocated from it - delete r.set_layout - delete r.srgb_image - delete r.srgb_memory - delete r.view - delete r.image - delete r.memory - delete r.pool - delete r.device - delete r.instance - } + delete r.readback + delete r.pipeline + delete r.pipe_layout + delete r.desc_pool // frees the descriptor set allocated from it + delete r.set_layout + delete r.srgb_image + delete r.srgb_memory + delete r.view + delete r.image + delete r.memory + delete r.pool + delete r.device + delete r.instance } //! Initialize Vulkan, build the storage image + compute pipeline for sdf_spv, and allocate a host @@ -177,7 +175,7 @@ def public build_sdf_renderer() : SdfRenderer { // nolint:STYLE038 - flat one- plci.pPushConstantRanges |> emplace(pcr) var inscope pipe_layout <- create_pipeline_layout(device, plci) delete plci.pPushConstantRanges - unsafe { delete plci.pSetLayouts } // the [weak_copy(set_layout)] literal we built above (handles are non-owning) + delete plci.pSetLayouts // the [weak_copy(set_layout)] literal we built above (handles are non-owning) var inscope pipeline <- create_compute_pipeline(device, pipe_layout, shader) let buf_size = uint64(SDF_DIM * SDF_DIM * 4) @@ -235,12 +233,10 @@ def public render_sdf_frame(var r : SdfRenderer; time : float) : array { region.dstOffsets[1].x = SDF_DIM region.dstOffsets[1].y = SDF_DIM region.dstOffsets[1].z = 1 - unsafe { - vkCmdBlitImage(boost_value_to_vk(cmd), - boost_value_to_vk(r.image), VkImageLayout.TRANSFER_SRC_OPTIMAL, - boost_value_to_vk(r.srgb_image), VkImageLayout.TRANSFER_DST_OPTIMAL, - 1u, addr(region), VkFilter.NEAREST) - } + vkCmdBlitImage(boost_value_to_vk(cmd), + boost_value_to_vk(r.image), VkImageLayout.TRANSFER_SRC_OPTIMAL, + boost_value_to_vk(r.srgb_image), VkImageLayout.TRANSFER_DST_OPTIMAL, + 1u, unsafe(addr(region)), VkFilter.NEAREST) // srgb_image -> TRANSFER_SRC so copy_image_to_buffer can read it transition_image(cmd, r.srgb_image, VkImageLayout.TRANSFER_DST_OPTIMAL, VkImageLayout.TRANSFER_SRC_OPTIMAL, transfer_write, transfer_read, xfer, xfer) diff --git a/modules/dasVulkan/tutorials/03_sdf/window/resident_compute.das b/modules/dasVulkan/tutorials/03_sdf/window/resident_compute.das index 7b9d36a58d..bff28f71cb 100644 --- a/modules/dasVulkan/tutorials/03_sdf/window/resident_compute.das +++ b/modules/dasVulkan/tutorials/03_sdf/window/resident_compute.das @@ -117,7 +117,7 @@ def public build_compute_image(device : Device; phys : VkPhysicalDevice; var wor plci.pPushConstantRanges |> emplace(pcr) var inscope pipe_layout <- create_pipeline_layout(device, plci) delete plci.pPushConstantRanges // owned input freed once the layout has copied the range - unsafe { delete plci.pSetLayouts } // the [weak_copy(set_layout)] literal we built above (handles non-owning) + delete plci.pSetLayouts // the [weak_copy(set_layout)] literal we built above (handles non-owning) var inscope pipeline <- create_compute_pipeline(device, pipe_layout, shader) return <- ComputeImage(image <- image, memory <- imem, view <- view, set_layout <- set_layout, diff --git a/modules/dasVulkan/tutorials/04_cube/cube_tut.das b/modules/dasVulkan/tutorials/04_cube/cube_tut.das index e6cd98542a..b623b4c75e 100644 --- a/modules/dasVulkan/tutorials/04_cube/cube_tut.das +++ b/modules/dasVulkan/tutorials/04_cube/cube_tut.das @@ -226,24 +226,22 @@ struct public CubeResources { //! Reverse-of-creation cleanup (the desc_set is owned by desc_pool so its raw handle just goes //! away when the pool destroys; nothing to delete for it explicitly). def public finalize(var r : CubeResources) { - unsafe { - delete r.readback - delete r.pipeline - delete r.pipe_layout - delete r.desc_pool - delete r.set_layouts - delete r.sampler - delete r.tex_view - delete r.tex_image - delete r.tex_memory - delete r.ubo - delete r.ib - delete r.vb - delete r.framebuffer - delete r.render_pass - delete r.depth - delete r.color - } + delete r.readback + delete r.pipeline + delete r.pipe_layout + delete r.desc_pool + delete r.set_layouts + delete r.sampler + delete r.tex_view + delete r.tex_image + delete r.tex_memory + delete r.ubo + delete r.ib + delete r.vb + delete r.framebuffer + delete r.render_pass + delete r.depth + delete r.color } //! Self-contained one-shot context for the offscreen oracle + recording driver: owns its own @@ -258,12 +256,10 @@ struct public CubeContext { } def public finalize(var ctx : CubeContext) { - unsafe { - delete ctx.res - delete ctx.pool - delete ctx.device - delete ctx.instance - } + delete ctx.res + delete ctx.pool + delete ctx.device + delete ctx.instance } //! Build the cube's render resources against a caller-owned (device, phys, queue, pool). Used by both diff --git a/modules/dasVulkan/tutorials/05_instancing/instancing_tut.das b/modules/dasVulkan/tutorials/05_instancing/instancing_tut.das index 60b77238bb..f866305bd1 100644 --- a/modules/dasVulkan/tutorials/05_instancing/instancing_tut.das +++ b/modules/dasVulkan/tutorials/05_instancing/instancing_tut.das @@ -167,21 +167,19 @@ struct public InstancingResources { } def public finalize(var r : InstancingResources) { - unsafe { - delete r.readback - delete r.pipeline - delete r.pipe_layout - delete r.desc_pool - delete r.set_layouts - delete r.ubo - delete r.inst_buf - delete r.ib - delete r.vb - delete r.framebuffer - delete r.render_pass - delete r.depth - delete r.color - } + delete r.readback + delete r.pipeline + delete r.pipe_layout + delete r.desc_pool + delete r.set_layouts + delete r.ubo + delete r.inst_buf + delete r.ib + delete r.vb + delete r.framebuffer + delete r.render_pass + delete r.depth + delete r.color } struct public InstancingContext { @@ -193,12 +191,10 @@ struct public InstancingContext { } def public finalize(var ctx : InstancingContext) { - unsafe { - delete ctx.res - delete ctx.pool - delete ctx.device - delete ctx.instance - } + delete ctx.res + delete ctx.pool + delete ctx.device + delete ctx.instance } //! Build the offscreen render targets, the 2-binding vertex input pipeline, descriptors and the diff --git a/modules/dasVulkan/tutorials/06_skybox/skybox_tut.das b/modules/dasVulkan/tutorials/06_skybox/skybox_tut.das index d8cdda3768..0f275fd1a2 100644 --- a/modules/dasVulkan/tutorials/06_skybox/skybox_tut.das +++ b/modules/dasVulkan/tutorials/06_skybox/skybox_tut.das @@ -254,30 +254,28 @@ struct public SkyboxResources { } def public finalize(var r : SkyboxResources) { - unsafe { - delete r.readback - delete r.floor_pipeline - delete r.sphere_pipeline - delete r.pipeline - delete r.pipe_layout - delete r.desc_pool - delete r.set_layouts - delete r.sky_sampler - delete r.sky_view - delete r.sky_image - delete r.sky_memory - delete r.ubo - delete r.floor_ib - delete r.floor_vb - delete r.sphere_ib - delete r.sphere_vb - delete r.ib - delete r.vb - delete r.framebuffer - delete r.render_pass - delete r.depth - delete r.color - } + delete r.readback + delete r.floor_pipeline + delete r.sphere_pipeline + delete r.pipeline + delete r.pipe_layout + delete r.desc_pool + delete r.set_layouts + delete r.sky_sampler + delete r.sky_view + delete r.sky_image + delete r.sky_memory + delete r.ubo + delete r.floor_ib + delete r.floor_vb + delete r.sphere_ib + delete r.sphere_vb + delete r.ib + delete r.vb + delete r.framebuffer + delete r.render_pass + delete r.depth + delete r.color } struct public SkyboxContext { @@ -289,12 +287,10 @@ struct public SkyboxContext { } def public finalize(var ctx : SkyboxContext) { - unsafe { - delete ctx.res - delete ctx.pool - delete ctx.device - delete ctx.instance - } + delete ctx.res + delete ctx.pool + delete ctx.device + delete ctx.instance } //! Foreground (sphere/floor) pipeline: vertex + fragment, pos+normal vertex input (stride 24), depth diff --git a/modules/dasVulkan/tutorials/07_particles/particles_tut.das b/modules/dasVulkan/tutorials/07_particles/particles_tut.das index 344f9a0719..de1c3742da 100644 --- a/modules/dasVulkan/tutorials/07_particles/particles_tut.das +++ b/modules/dasVulkan/tutorials/07_particles/particles_tut.das @@ -226,23 +226,21 @@ struct public ParticlesResources { } def public finalize(var r : ParticlesResources) { - unsafe { - delete r.readback - delete r.gpipeline - delete r.gpipe_layout - delete r.gdesc_pool - delete r.gset_layouts - delete r.cpipeline - delete r.cpipe_layout - delete r.cdesc_pool - delete r.cset_layouts - delete r.ubo - delete r.particle_buf - delete r.framebuffer - delete r.render_pass - delete r.depth - delete r.color - } + delete r.readback + delete r.gpipeline + delete r.gpipe_layout + delete r.gdesc_pool + delete r.gset_layouts + delete r.cpipeline + delete r.cpipe_layout + delete r.cdesc_pool + delete r.cset_layouts + delete r.ubo + delete r.particle_buf + delete r.framebuffer + delete r.render_pass + delete r.depth + delete r.color } struct public ParticlesContext { @@ -254,12 +252,10 @@ struct public ParticlesContext { } def public finalize(var ctx : ParticlesContext) { - unsafe { - delete ctx.res - delete ctx.pool - delete ctx.device - delete ctx.instance - } + delete ctx.res + delete ctx.pool + delete ctx.device + delete ctx.instance } //! Build the offscreen targets, the two pipelines (compute + graphics), and the once-seeded particle @@ -488,13 +484,11 @@ def public record_particles_render_pass(res : ParticlesResources; cmd : CommandB var bmbs : array bmbs |> push(bmb) let no_dep : VkDependencyFlags - unsafe { - vkCmdPipelineBarrier(raw_cmd, src_stage, dst_stage, - no_dep, - 0u, null, - 1u, addr(bmbs[0]), - 0u, null) - } + vkCmdPipelineBarrier(raw_cmd, src_stage, dst_stage, + no_dep, + 0u, null, + 1u, unsafe(addr(bmbs[0])), + 0u, null) delete bmbs // 3) Graphics pass: bind the SAME particle buffer (the bytes the compute just wrote) at diff --git a/modules/dasVulkan/tutorials/08_shadow/shadow_tut.das b/modules/dasVulkan/tutorials/08_shadow/shadow_tut.das index bd9270ac76..3f9595ea7a 100644 --- a/modules/dasVulkan/tutorials/08_shadow/shadow_tut.das +++ b/modules/dasVulkan/tutorials/08_shadow/shadow_tut.das @@ -225,32 +225,30 @@ struct public ShadowResources { } def public finalize(var r : ShadowResources) { - unsafe { - delete r.readback - delete r.pipeline_main - delete r.pipeline_shadow - delete r.pipe_layout - delete r.desc_pool - delete r.set_layouts - delete r.brick_roughness - delete r.brick_ao - delete r.brick_normal - delete r.brick_albedo - delete r.tex_sampler - delete r.shadow_sampler - delete r.ubo - delete r.floor_ib - delete r.floor_vb - delete r.cube_ib - delete r.cube_vb - delete r.fb_shadow - delete r.fb_color - delete r.rp_shadow - delete r.rp_color - delete r.shadow_map - delete r.depth - delete r.color - } + delete r.readback + delete r.pipeline_main + delete r.pipeline_shadow + delete r.pipe_layout + delete r.desc_pool + delete r.set_layouts + delete r.brick_roughness + delete r.brick_ao + delete r.brick_normal + delete r.brick_albedo + delete r.tex_sampler + delete r.shadow_sampler + delete r.ubo + delete r.floor_ib + delete r.floor_vb + delete r.cube_ib + delete r.cube_vb + delete r.fb_shadow + delete r.fb_color + delete r.rp_shadow + delete r.rp_color + delete r.shadow_map + delete r.depth + delete r.color } //! Self-contained one-shot context for the offscreen oracle + recording driver. Windowed drivers @@ -265,12 +263,10 @@ struct public ShadowContext { } def public finalize(var ctx : ShadowContext) { - unsafe { - delete ctx.res - delete ctx.pool - delete ctx.device - delete ctx.instance - } + delete ctx.res + delete ctx.pool + delete ctx.device + delete ctx.instance } // ===== pipeline builders ===== diff --git a/modules/dasVulkan/tutorials/09_msaa/msaa_tut.das b/modules/dasVulkan/tutorials/09_msaa/msaa_tut.das index d8b57b2615..da3003f0e9 100644 --- a/modules/dasVulkan/tutorials/09_msaa/msaa_tut.das +++ b/modules/dasVulkan/tutorials/09_msaa/msaa_tut.das @@ -263,26 +263,24 @@ struct public MsaaResources { } def public finalize(var r : MsaaResources) { - unsafe { - delete r.readback - delete r.pipeline_1x - delete r.pipeline_msaa - delete r.pipe_layout - delete r.desc_pool - delete r.set_layouts - delete r.sampler - delete r.tex_view - delete r.tex_image - delete r.tex_memory - delete r.ubo - delete r.ib - delete r.vb - delete r.depth_1x - delete r.color_1x - delete r.depth_msaa - delete r.color_resolve - delete r.color_msaa - } + delete r.readback + delete r.pipeline_1x + delete r.pipeline_msaa + delete r.pipe_layout + delete r.desc_pool + delete r.set_layouts + delete r.sampler + delete r.tex_view + delete r.tex_image + delete r.tex_memory + delete r.ubo + delete r.ib + delete r.vb + delete r.depth_1x + delete r.color_1x + delete r.depth_msaa + delete r.color_resolve + delete r.color_msaa } struct public MsaaContext { @@ -294,12 +292,10 @@ struct public MsaaContext { } def public finalize(var ctx : MsaaContext) { - unsafe { - delete ctx.res - delete ctx.pool - delete ctx.device - delete ctx.instance - } + delete ctx.res + delete ctx.pool + delete ctx.device + delete ctx.instance } //! Build the MSAA cube's render resources. The pool's queue family must equal `queue`'s family -- diff --git a/modules/dasVulkan/tutorials/10_deferred/deferred_tut.das b/modules/dasVulkan/tutorials/10_deferred/deferred_tut.das index 747d2bf4ef..bf08c51151 100644 --- a/modules/dasVulkan/tutorials/10_deferred/deferred_tut.das +++ b/modules/dasVulkan/tutorials/10_deferred/deferred_tut.das @@ -258,55 +258,53 @@ struct public DeferredResources { } def public finalize(var r : DeferredResources) { - unsafe { - delete r.readback - delete r.desc_pool - delete r.lighting_pipeline - delete r.lighting_pipe_layout - delete r.lighting_set_layouts - delete r.ssao_pipeline - delete r.ssao_pipe_layout - delete r.ssao_set_layouts - delete r.gbuffer_pipeline - delete r.gbuffer_pipe_layout - delete r.gbuffer_set_layouts - delete r.shadow_pipeline - delete r.shadow_pipe_layout - delete r.shadow_set_layouts - delete r.fb_lighting - delete r.fb_ssao - delete r.fb_gbuffer - delete r.fb_shadow - delete r.rp_lighting - delete r.rp_ssao - delete r.rp_gbuffer - delete r.rp_shadow - delete r.gbuffer_sampler - delete r.floor_roughness - delete r.floor_ao - delete r.floor_normal - delete r.floor_albedo - delete r.cat_sampler - delete r.cat_arm - delete r.cat_normal - delete r.cat_albedo - delete r.env_sampler - delete r.env_tex - delete r.shadow_sampler - delete r.scene_ubo - delete r.xform_ubo - delete r.floor_ib - delete r.floor_vb - delete r.cube_ib - delete r.cube_vb - delete r.shadow_map - delete r.depth - delete r.final_color - delete r.ssao_img - delete r.g_worldpos - delete r.g_normal - delete r.g_albedo - } + delete r.readback + delete r.desc_pool + delete r.lighting_pipeline + delete r.lighting_pipe_layout + delete r.lighting_set_layouts + delete r.ssao_pipeline + delete r.ssao_pipe_layout + delete r.ssao_set_layouts + delete r.gbuffer_pipeline + delete r.gbuffer_pipe_layout + delete r.gbuffer_set_layouts + delete r.shadow_pipeline + delete r.shadow_pipe_layout + delete r.shadow_set_layouts + delete r.fb_lighting + delete r.fb_ssao + delete r.fb_gbuffer + delete r.fb_shadow + delete r.rp_lighting + delete r.rp_ssao + delete r.rp_gbuffer + delete r.rp_shadow + delete r.gbuffer_sampler + delete r.floor_roughness + delete r.floor_ao + delete r.floor_normal + delete r.floor_albedo + delete r.cat_sampler + delete r.cat_arm + delete r.cat_normal + delete r.cat_albedo + delete r.env_sampler + delete r.env_tex + delete r.shadow_sampler + delete r.scene_ubo + delete r.xform_ubo + delete r.floor_ib + delete r.floor_vb + delete r.cube_ib + delete r.cube_vb + delete r.shadow_map + delete r.depth + delete r.final_color + delete r.ssao_img + delete r.g_worldpos + delete r.g_normal + delete r.g_albedo } struct public DeferredContext { @@ -318,12 +316,10 @@ struct public DeferredContext { } def public finalize(var ctx : DeferredContext) { - unsafe { - delete ctx.res - delete ctx.pool - delete ctx.device - delete ctx.instance - } + delete ctx.res + delete ctx.pool + delete ctx.device + delete ctx.instance } // ===== build ===== diff --git a/modules/dasVulkan/tutorials/11_hdr/hdr_tut.das b/modules/dasVulkan/tutorials/11_hdr/hdr_tut.das index b2c69fc545..1b1783d4c2 100644 --- a/modules/dasVulkan/tutorials/11_hdr/hdr_tut.das +++ b/modules/dasVulkan/tutorials/11_hdr/hdr_tut.das @@ -215,39 +215,37 @@ struct public HdrResources { } def public finalize(var r : HdrResources) { - unsafe { - delete r.readback - delete r.desc_pool - delete r.composite_pipeline - delete r.composite_pipe_layout - delete r.composite_set_layouts - delete r.up_pipeline - delete r.down_pipeline - delete r.bright_pipeline - delete r.post_pipe_layout - delete r.post_set_layouts - delete r.scene_pipeline - delete r.scene_pipe_layout - delete r.scene_set_layouts - delete r.ubo - delete r.inst_buf - delete r.cube_ib - delete r.cube_vb - delete r.sampler_linear_clamp - delete r.fb_composite - delete r.fb_post_load - delete r.fb_post_clear - delete r.fb_scene - delete r.rp_composite - delete r.rp_post_load - delete r.rp_post_clear - delete r.rp_scene - delete r.readback_8bit - delete r.ldr_color - delete r.bloom - delete r.hdr_depth - delete r.hdr_color - } + delete r.readback + delete r.desc_pool + delete r.composite_pipeline + delete r.composite_pipe_layout + delete r.composite_set_layouts + delete r.up_pipeline + delete r.down_pipeline + delete r.bright_pipeline + delete r.post_pipe_layout + delete r.post_set_layouts + delete r.scene_pipeline + delete r.scene_pipe_layout + delete r.scene_set_layouts + delete r.ubo + delete r.inst_buf + delete r.cube_ib + delete r.cube_vb + delete r.sampler_linear_clamp + delete r.fb_composite + delete r.fb_post_load + delete r.fb_post_clear + delete r.fb_scene + delete r.rp_composite + delete r.rp_post_load + delete r.rp_post_clear + delete r.rp_scene + delete r.readback_8bit + delete r.ldr_color + delete r.bloom + delete r.hdr_depth + delete r.hdr_color } struct public HdrContext { @@ -259,12 +257,10 @@ struct public HdrContext { } def public finalize(var ctx : HdrContext) { - unsafe { - delete ctx.res - delete ctx.pool - delete ctx.device - delete ctx.instance - } + delete ctx.res + delete ctx.pool + delete ctx.device + delete ctx.instance } // ===== build ===== @@ -1069,12 +1065,10 @@ def public render_hdr_frame(var ctx : HdrContext; time, camera_t : float) : arra region.dstOffsets[1].x = HDR_W region.dstOffsets[1].y = HDR_H region.dstOffsets[1].z = 1 - unsafe { - vkCmdBlitImage(boost_value_to_vk(cmd), - boost_value_to_vk(ctx.res.ldr_color.image), VkImageLayout.TRANSFER_SRC_OPTIMAL, - boost_value_to_vk(ctx.res.readback_8bit.image), VkImageLayout.TRANSFER_DST_OPTIMAL, - 1u, addr(region), VkFilter.NEAREST) - } + vkCmdBlitImage(boost_value_to_vk(cmd), + boost_value_to_vk(ctx.res.ldr_color.image), VkImageLayout.TRANSFER_SRC_OPTIMAL, + boost_value_to_vk(ctx.res.readback_8bit.image), VkImageLayout.TRANSFER_DST_OPTIMAL, + 1u, unsafe(addr(region)), VkFilter.NEAREST) // readback_8bit -> TRANSFER_SRC_OPTIMAL so copy_image_to_buffer can read it. transition_image(cmd, ctx.res.readback_8bit.image, VkImageLayout.TRANSFER_DST_OPTIMAL, VkImageLayout.TRANSFER_SRC_OPTIMAL, transfer_write, transfer_read, transfer_stage, transfer_stage) diff --git a/modules/dasVulkan/tutorials/12_gpu_driven/gpu_driven_tut.das b/modules/dasVulkan/tutorials/12_gpu_driven/gpu_driven_tut.das index f421adf04e..b2a0914629 100644 --- a/modules/dasVulkan/tutorials/12_gpu_driven/gpu_driven_tut.das +++ b/modules/dasVulkan/tutorials/12_gpu_driven/gpu_driven_tut.das @@ -222,9 +222,7 @@ def public draw_indirect_count_available() : bool { var f12 = VkPhysicalDeviceVulkan12Features() f12.sType = VkStructureType.PHYSICAL_DEVICE_VULKAN_1_2_FEATURES var f2 = VkPhysicalDeviceFeatures2() - unsafe { - f2.pNext = addr(f12) - } + f2.pNext = unsafe(addr(f12)) vkGetPhysicalDeviceFeatures2(phys, f2) return f12.drawIndirectCount != 0u } @@ -722,47 +720,45 @@ struct public GpuDrivenResources { } def public finalize(var r : GpuDrivenResources) { - unsafe { - delete r.readback - delete r.desc_pool - delete r.god_pipe - delete r.god_pl - delete r.god_layouts - delete r.main_pipe - delete r.main_pl - delete r.main_layouts - delete r.occ_ghost_pipe - delete r.occ_solid_pipe - delete r.depth_pipe - delete r.occ_pl - delete r.occ_layouts - delete r.down_pipe - delete r.mip0_pipe - delete r.hzb_pl - delete r.hzb_layouts - delete r.cull_pipe - delete r.cull_pl - delete r.cull_layouts - delete r.cull_reason - delete r.draw_inst - delete r.draw_count - delete r.draw_cmds - delete r.instances - delete r.ubo - delete r.cube_ib - delete r.cube_vb - delete r.materials - delete r.mat_sampler - delete r.depth_sampler - delete r.fb_color - delete r.fb_depth - delete r.rp_color - delete r.rp_depth - delete r.hzb - delete r.occ_depth - delete r.out_depth - delete r.out_color - } + delete r.readback + delete r.desc_pool + delete r.god_pipe + delete r.god_pl + delete r.god_layouts + delete r.main_pipe + delete r.main_pl + delete r.main_layouts + delete r.occ_ghost_pipe + delete r.occ_solid_pipe + delete r.depth_pipe + delete r.occ_pl + delete r.occ_layouts + delete r.down_pipe + delete r.mip0_pipe + delete r.hzb_pl + delete r.hzb_layouts + delete r.cull_pipe + delete r.cull_pl + delete r.cull_layouts + delete r.cull_reason + delete r.draw_inst + delete r.draw_count + delete r.draw_cmds + delete r.instances + delete r.ubo + delete r.cube_ib + delete r.cube_vb + delete r.materials + delete r.mat_sampler + delete r.depth_sampler + delete r.fb_color + delete r.fb_depth + delete r.rp_color + delete r.rp_depth + delete r.hzb + delete r.occ_depth + delete r.out_depth + delete r.out_color } struct public GpuDrivenContext { @@ -774,12 +770,10 @@ struct public GpuDrivenContext { } def public finalize(var ctx : GpuDrivenContext) { - unsafe { - delete ctx.res - delete ctx.pool - delete ctx.device - delete ctx.instance - } + delete ctx.res + delete ctx.pool + delete ctx.device + delete ctx.instance } // ===== build ===== @@ -1143,9 +1137,7 @@ def public record_frame(res : GpuDrivenResources; cmd : CommandBuffer; wall_x : // ===== pass 3: cull ===== // zero the draw count, then make it visible to the cull shader - unsafe { - vkCmdFillBuffer(raw, boost_value_to_vk(res.draw_count.buffer), 0ul, 4ul, 0u) - } + vkCmdFillBuffer(raw, boost_value_to_vk(res.draw_count.buffer), 0ul, 4ul, 0u) { var bb : BufferMemoryBarrier bb.srcAccessMask.transfer_write = true diff --git a/modules/dasVulkan/tutorials/14_teapot/teapot_tut.das b/modules/dasVulkan/tutorials/14_teapot/teapot_tut.das index 7229c66cb5..b10c3403e5 100644 --- a/modules/dasVulkan/tutorials/14_teapot/teapot_tut.das +++ b/modules/dasVulkan/tutorials/14_teapot/teapot_tut.das @@ -187,27 +187,25 @@ struct public TeapotResources { } def public finalize(var r : TeapotResources) { - unsafe { - delete r.readback - delete r.pipeline_shadow - delete r.pipeline_sky - delete r.pipeline_floor - delete r.pipeline - delete r.pipe_layout - delete r.desc_pool - delete r.set_layouts - delete r.shadow_sampler - delete r.sky_vb - delete r.floor_vb - delete r.ubo - delete r.fb_shadow - delete r.framebuffer - delete r.rp_shadow - delete r.render_pass - delete r.shadow_map - delete r.depth - delete r.color - } + delete r.readback + delete r.pipeline_shadow + delete r.pipeline_sky + delete r.pipeline_floor + delete r.pipeline + delete r.pipe_layout + delete r.desc_pool + delete r.set_layouts + delete r.shadow_sampler + delete r.sky_vb + delete r.floor_vb + delete r.ubo + delete r.fb_shadow + delete r.framebuffer + delete r.rp_shadow + delete r.render_pass + delete r.shadow_map + delete r.depth + delete r.color } struct public TeapotContext { @@ -219,12 +217,10 @@ struct public TeapotContext { } def public finalize(var ctx : TeapotContext) { - unsafe { - delete ctx.res - delete ctx.pool - delete ctx.device - delete ctx.instance - } + delete ctx.res + delete ctx.pool + delete ctx.device + delete ctx.instance } //! Depth-only mesh-shader pipeline for the shadow pass: task + mesh stages, NO fragment, NO color diff --git a/modules/dasVulkan/tutorials/recording/tutorial_record.das b/modules/dasVulkan/tutorials/recording/tutorial_record.das index 89c80560a2..800b7d7350 100644 --- a/modules/dasVulkan/tutorials/recording/tutorial_record.das +++ b/modules/dasVulkan/tutorials/recording/tutorial_record.das @@ -56,9 +56,7 @@ def public capture_apng(apng_path : string; w, h, n_frames, frame_ms : int; } flip_rows_inplace(pixels, w, h) var rc = 0 - unsafe { - rc = stbi_apng_frame(writer, addr(pixels[0]), w * 4, frame_ms) - } + rc = stbi_apng_frame(writer, unsafe(addr(pixels[0])), w * 4, frame_ms) delete pixels if (rc != 1) { to_log(LOG_ERROR, "[record] stbi_apng_frame {f} failed\n") diff --git a/skills/daslang/references/everything.md b/skills/daslang/references/everything.md index f529c73c00..6358b9bf67 100644 --- a/skills/daslang/references/everything.md +++ b/skills/daslang/references/everything.md @@ -3848,6 +3848,7 @@ The AST module provides access to the abstract syntax tree representation of das - `TypeDecl.isBitfield` - Returns whether the given type is a bitfield type. - `TypeDecl.isLocal` - Returns whether the given type is a local type that can be allocated on the stack. - `TypeDecl.hasClasses` - Returns whether the type definition contains any class types. +- `TypeDecl.isSafeToDelete` - Returns whether a value of the given type is safe to delete, meaning that deleting it does not require an unsafe block. - `TypeDecl.hasNonTrivialCtor` - Returns whether the type definition contains any non-trivial constructors. - `TypeDecl.hasNonTrivialDtor` - Returns whether the type definition contains any non-trivial destructors. - `TypeDecl.hasNonTrivialCopy` - Returns whether the type definition contains any non-trivial copy operations. diff --git a/src/builtin/module_builtin_ast_annotations_1.cpp b/src/builtin/module_builtin_ast_annotations_1.cpp index 5c7aeeea1d..81cedf10dd 100644 --- a/src/builtin/module_builtin_ast_annotations_1.cpp +++ b/src/builtin/module_builtin_ast_annotations_1.cpp @@ -121,6 +121,7 @@ namespace das { addProperty("isBitfield","isBitfield"); addProperty("isLocal", "isLocal"); addProperty("hasClasses", "hasClasses"); + addProperty("isSafeToDelete", "isSafeToDelete"); addProperty("hasNonTrivialCtor", "hasNonTrivialCtor"); addProperty("hasNonTrivialDtor", "hasNonTrivialDtor"); addProperty("hasNonTrivialCopy", "hasNonTrivialCopy"); diff --git a/tests/aot/test_int64_ptr_index.das b/tests/aot/test_int64_ptr_index.das index 609cbb2f76..c2b0bcdf26 100644 --- a/tests/aot/test_int64_ptr_index.das +++ b/tests/aot/test_int64_ptr_index.das @@ -23,9 +23,7 @@ def safe_read_u64(p : float?; i : uint64) : float { } def write_i64(var p : float?; i : int64; v : float) { - unsafe { - p[i] = v - } + unsafe(p[i]) = v } def read_const_pointee_i64(p : float const?; i : int64) : float { diff --git a/tests/ast/test_any_long_size.das b/tests/ast/test_any_long_size.das index 728bba2efb..0326e84dde 100644 --- a/tests/ast/test_any_long_size.das +++ b/tests/ast/test_any_long_size.das @@ -10,17 +10,13 @@ require dastest/testing_boost public [test] def test_any_array_long_size(t : T?) { var arr <- [10, 20, 30, 40, 50] - unsafe { - let p = addr(arr) - t |> equal(any_array_long_size(p), int64(5)) - } + let p = unsafe(addr(arr)) + t |> equal(any_array_long_size(p), int64(5)) } [test] def test_any_table_long_size(t : T?) { var tab <- {1 => 100, 2 => 200, 3 => 300} - unsafe { - let p = addr(tab) - t |> equal(any_table_long_size(p), int64(3)) - } + let p = unsafe(addr(tab)) + t |> equal(any_table_long_size(p), int64(3)) } diff --git a/tests/bool_array/test_bool_array_iterator_crash.das b/tests/bool_array/test_bool_array_iterator_crash.das index e32bd9a944..dc2578d6bf 100644 --- a/tests/bool_array/test_bool_array_iterator_crash.das +++ b/tests/bool_array/test_bool_array_iterator_crash.das @@ -11,9 +11,7 @@ require daslib/rtti // Benchmark that prints context name and tries to iterate BoolArray [benchmark] def benchmark_context_check(b : B?) { - unsafe { - to_log(LOG_INFO, "benchmark_context_check: context name = '{this_context().name}'\n") - } + to_log(LOG_INFO, "benchmark_context_check: context name = '{this_context().name}'\n") var a : BoolArray for (i in 0 .. 10) { a.push(i % 2 == 0) diff --git a/tests/dasPUGIXML/test_serial_table.das b/tests/dasPUGIXML/test_serial_table.das index 6064e4e353..aeedd040cb 100644 --- a/tests/dasPUGIXML/test_serial_table.das +++ b/tests/dasPUGIXML/test_serial_table.das @@ -72,9 +72,7 @@ def test_from_xml_table_string_string(t : T?) { t |> success(ok) var tab <- from_XML(doc.document_element, type>) t |> equal(length(tab), 1) - unsafe { - t |> equal(tab["name"], "Alice") - } + unsafe(t |> equal(tab["name"], "Alice")) } } } diff --git a/tests/dasPUGIXML/test_serial_variant.das b/tests/dasPUGIXML/test_serial_variant.das index 8f935bee90..f819a9fadb 100644 --- a/tests/dasPUGIXML/test_serial_variant.das +++ b/tests/dasPUGIXML/test_serial_variant.das @@ -20,7 +20,7 @@ struct WithVariant { def test_xml_serialize_variant_int(t : T?) { t |> run("serialize variant (int case) to XML") <| @(t : T?) { var v : IntOrString - unsafe { v.i_val = 42; } + unsafe(v.i_val) = 42 with_doc() $(doc) { var dnode = doc as xml_node var root = append_child(dnode, "val") @@ -101,7 +101,7 @@ def test_from_xml_variant_string(t : T?) { def test_roundtrip_variant_int(t : T?) { t |> run("roundtrip variant (int case)") <| @(t : T?) { var original : IntOrString - unsafe { original.i_val = 123; } + unsafe(original.i_val) = 123 let xml_str = to_XML(original, "val") parse_xml(xml_str) $(doc, ok) { t |> success(ok) diff --git a/tests/daslib/eval_single_expression_test.das b/tests/daslib/eval_single_expression_test.das index 2119c8cced..8a1573eed9 100644 --- a/tests/daslib/eval_single_expression_test.das +++ b/tests/daslib/eval_single_expression_test.das @@ -56,11 +56,9 @@ def test_eval_literal_no_context(t : T?) { let init = find_foo_field(program, "bar") t2 |> success(init != null, "found Foo.bar init expression") var ok = true - unsafe { - let v = eval_single_expression(init, ok) - t2 |> success(ok, "eval ok") - t2 |> equal(v.x, 3.14, "literal value matches") - } + let v = unsafe(eval_single_expression(init, ok)) + t2 |> success(ok, "eval ok") + t2 |> equal(v.x, 3.14, "literal value matches") } } } @@ -71,11 +69,9 @@ def test_eval_literal_with_context(t : T?) { compile_fixture(t2) $(program; ctx) { let init = find_foo_field(program, "bar") var ok = true - unsafe { - let v = eval_single_expression(init, ctx, ok) - t2 |> success(ok, "eval ok") - t2 |> equal(v.x, 3.14, "literal value matches") - } + let v = unsafe(eval_single_expression(init, ctx, ok)) + t2 |> success(ok, "eval ok") + t2 |> equal(v.x, 3.14, "literal value matches") } } } @@ -90,11 +86,9 @@ def test_eval_folded_away_constexpr_var_no_context(t : T?) { t2 |> success(init != null, "found Foo.qux init expression") t2 |> success(init.__rtti == "ExprVar", "qux init stays as ExprVar (got {init.__rtti})") var ok = true - unsafe { - let v = eval_single_expression(init, ok) - t2 |> success(ok, "eval ok (regression: would crash before fix)") - t2 |> equal(v.x, PI, "PI value matches math::PI") - } + let v = unsafe(eval_single_expression(init, ok)) + t2 |> success(ok, "eval ok (regression: would crash before fix)") + t2 |> equal(v.x, PI, "PI value matches math::PI") } } } @@ -105,11 +99,9 @@ def test_eval_folded_away_constexpr_var_with_context(t : T?) { compile_fixture(t2) $(program; ctx) { let init = find_foo_field(program, "qux") var ok = true - unsafe { - let v = eval_single_expression(init, ctx, ok) - t2 |> success(ok, "eval ok (regression: would crash before fix)") - t2 |> equal(v.x, PI, "PI value matches math::PI") - } + let v = unsafe(eval_single_expression(init, ctx, ok)) + t2 |> success(ok, "eval ok (regression: would crash before fix)") + t2 |> equal(v.x, PI, "PI value matches math::PI") } } } @@ -119,11 +111,9 @@ def test_eval_null_expr_with_context(t : T?) { t |> run("null expression sets ok=false safely") <| @(t2 : T?) { compile_fixture(t2) $(program; ctx) { var ok = true - unsafe { - let nullExpr : ExpressionPtr = null - eval_single_expression(nullExpr, ctx, ok) - t2 |> success(!ok, "ok set to false for null expression") - } + let nullExpr : ExpressionPtr = null + unsafe(eval_single_expression(nullExpr, ctx, ok)) + t2 |> success(!ok, "ok set to false for null expression") } } } diff --git a/tests/data_walker/test_walk_containers.das b/tests/data_walker/test_walk_containers.das index 891fa1cb30..e4177f803d 100644 --- a/tests/data_walker/test_walk_containers.das +++ b/tests/data_walker/test_walk_containers.das @@ -21,9 +21,7 @@ def test_walk_array(t : T?) { // nolint:STYLE038 - flat list of independent walk var walker = new LogWalker() var arr = [10, 20, 30] make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(arr), typeinfo rtti_typeinfo(arr)) - } + adapter |> walk_data(unsafe(addr(arr)), typeinfo rtti_typeinfo(arr)) } var expected = "beforeArray\n" expected += "beforeArrayData:3\n" @@ -45,9 +43,7 @@ def test_walk_array(t : T?) { // nolint:STYLE038 - flat list of independent walk var walker = new LogWalker() var arr : array make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(arr), typeinfo rtti_typeinfo(arr)) - } + adapter |> walk_data(unsafe(addr(arr)), typeinfo rtti_typeinfo(arr)) } var expected = "beforeArray\n" expected += "beforeArrayData:0\n" @@ -60,9 +56,7 @@ def test_walk_array(t : T?) { // nolint:STYLE038 - flat list of independent walk var walker = new LogWalker() var arr = [42] make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(arr), typeinfo rtti_typeinfo(arr)) - } + adapter |> walk_data(unsafe(addr(arr)), typeinfo rtti_typeinfo(arr)) } // Single element: index=0, last=true t |> equal(find(walker.log, "beforeElem:0:true") != -1, true) @@ -73,9 +67,7 @@ def test_walk_array(t : T?) { // nolint:STYLE038 - flat list of independent walk var walker = new LogWalker() var arr <- [SimpleStruct(x = 1, y = 1.0), SimpleStruct(x = 2, y = 2.0)] make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(arr), typeinfo rtti_typeinfo(arr)) - } + adapter |> walk_data(unsafe(addr(arr)), typeinfo rtti_typeinfo(arr)) } t |> equal(find(walker.log, "beforeArray") != -1, true) t |> equal(find(walker.log, "beforeStruct:SimpleStruct") != -1, true) @@ -87,9 +79,7 @@ def test_walk_array(t : T?) { // nolint:STYLE038 - flat list of independent walk var walker = new LogWalker() var arr = ["foo", "bar", "baz"] make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(arr), typeinfo rtti_typeinfo(arr)) - } + adapter |> walk_data(unsafe(addr(arr)), typeinfo rtti_typeinfo(arr)) } t |> equal(find(walker.log, "String:foo") != -1, true) t |> equal(find(walker.log, "String:bar") != -1, true) @@ -100,9 +90,7 @@ def test_walk_array(t : T?) { // nolint:STYLE038 - flat list of independent walk var walker = new LogWalker() var arr <- [(1, "one"), (2, "two")] make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(arr), typeinfo rtti_typeinfo(arr)) - } + adapter |> walk_data(unsafe(addr(arr)), typeinfo rtti_typeinfo(arr)) } t |> equal(find(walker.log, "beforeArray") != -1, true) t |> equal(find(walker.log, "beforeTuple") != -1, true) @@ -128,9 +116,7 @@ def test_walk_dim(t : T?) { arr[1] = 200 arr[2] = 300 make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(arr), typeinfo rtti_typeinfo(arr)) - } + adapter |> walk_data(unsafe(addr(arr)), typeinfo rtti_typeinfo(arr)) } t |> equal(find(walker.log, "beforeDim") != -1, true) t |> equal(find(walker.log, "Int:100") != -1, true) @@ -153,9 +139,7 @@ def test_walk_table(t : T?) { var tab : table tab |> insert("alpha", 1) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(tab), typeinfo rtti_typeinfo(tab)) - } + adapter |> walk_data(unsafe(addr(tab)), typeinfo rtti_typeinfo(tab)) } t |> equal(find(walker.log, "beforeTable") != -1, true) t |> equal(find(walker.log, "String:alpha") != -1, true) @@ -167,9 +151,7 @@ def test_walk_table(t : T?) { var walker = new LogWalker() var tab : table make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(tab), typeinfo rtti_typeinfo(tab)) - } + adapter |> walk_data(unsafe(addr(tab)), typeinfo rtti_typeinfo(tab)) } var expected = "beforeTable\n" expected += "afterTable\n" @@ -182,9 +164,7 @@ def test_walk_table(t : T?) { var tab : table tab |> insert("x", 42) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(tab), typeinfo rtti_typeinfo(tab)) - } + adapter |> walk_data(unsafe(addr(tab)), typeinfo rtti_typeinfo(tab)) } let key_pos = find(walker.log, "beforeKey") let key_after_pos = find(walker.log, "afterKey") @@ -201,9 +181,7 @@ def test_walk_table(t : T?) { var tab : table tab |> insert(42, "answer") make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(tab), typeinfo rtti_typeinfo(tab)) - } + adapter |> walk_data(unsafe(addr(tab)), typeinfo rtti_typeinfo(tab)) } t |> equal(find(walker.log, "Int:42") != -1, true) t |> equal(find(walker.log, "String:answer") != -1, true) @@ -213,9 +191,7 @@ def test_walk_table(t : T?) { var walker = new LogWalker() var tab <- {"a" => 1, "b" => 2, "c" => 3} make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(tab), typeinfo rtti_typeinfo(tab)) - } + adapter |> walk_data(unsafe(addr(tab)), typeinfo rtti_typeinfo(tab)) } // All 3 keys and values should appear (order may vary due to hash table) t |> equal(find(walker.log, "String:a") != -1, true) diff --git a/tests/data_walker/test_walk_edge_cases.das b/tests/data_walker/test_walk_edge_cases.das index 138dd61895..29d90ed14d 100644 --- a/tests/data_walker/test_walk_edge_cases.das +++ b/tests/data_walker/test_walk_edge_cases.das @@ -42,9 +42,7 @@ def test_walk_null_pointer(t : T?) { var walker = new LogWalker() var p : SimpleStruct? make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(p), typeinfo rtti_typeinfo(p)) - } + adapter |> walk_data(unsafe(addr(p)), typeinfo rtti_typeinfo(p)) } // Null pointer: beforePtr → Null → afterPtr (walker still brackets with ptr callbacks) var expected = "beforePtr\n" @@ -58,9 +56,7 @@ def test_walk_null_pointer(t : T?) { var s = SimpleStruct(x = 7, y = 1.5) var p : SimpleStruct? = unsafe(addr(s)) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(p), typeinfo rtti_typeinfo(p)) - } + adapter |> walk_data(unsafe(addr(p)), typeinfo rtti_typeinfo(p)) } t |> equal(find(walker.log, "beforePtr") != -1, true) t |> equal(find(walker.log, "beforeStruct:SimpleStruct") != -1, true) @@ -84,9 +80,7 @@ def test_walk_lambda(t : T?) { return captured_value } make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(lam), typeinfo rtti_typeinfo(lam)) - } + adapter |> walk_data(unsafe(addr(lam)), typeinfo rtti_typeinfo(lam)) } t |> equal(find(walker.log, "beforeLambda") != -1, true) t |> equal(find(walker.log, "afterLambda") != -1, true) @@ -105,9 +99,7 @@ def test_walk_edge_values(t : T?) { var walker = new LogWalker() var x = 0 make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "Int:0\n") unsafe { delete walker; } @@ -116,9 +108,7 @@ def test_walk_edge_values(t : T?) { var walker = new LogWalker() var x = -42 make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "Int:-42\n") unsafe { delete walker; } @@ -127,9 +117,7 @@ def test_walk_edge_values(t : T?) { var walker = new LogWalker() var x = -1.5 make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "Float:-1.5\n") unsafe { delete walker; } @@ -138,9 +126,7 @@ def test_walk_edge_values(t : T?) { var walker = new LogWalker() var x = 2147483647 make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "Int:2147483647\n") unsafe { delete walker; } @@ -149,9 +135,7 @@ def test_walk_edge_values(t : T?) { var walker = new LogWalker() var x = -2147483647 - 1 make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "Int:-2147483648\n") unsafe { delete walker; } @@ -170,9 +154,7 @@ def test_deeply_nested(t : T?) { var root <- TreeNode(value = 1, children <- [TreeNode(value = 2), TreeNode(value = 3)]) root.children[0].children |> emplace(TreeNode(value = 4)) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(root), typeinfo rtti_typeinfo(root)) - } + adapter |> walk_data(unsafe(addr(root)), typeinfo rtti_typeinfo(root)) } // All 4 values should be visited t |> equal(find(walker.log, "Int:1") != -1, true) @@ -194,16 +176,12 @@ def test_reuse_adapter(t : T?) { var walker = new LogWalker() make_data_walker(walker) $(adapter) { var x = 10 - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) t |> equal(walker.log, "Int:10\n") // Reset log and walk again walker.log = "" var y = 20 - unsafe { - adapter |> walk_data(addr(y), typeinfo rtti_typeinfo(y)) - } + adapter |> walk_data(unsafe(addr(y)), typeinfo rtti_typeinfo(y)) t |> equal(walker.log, "Int:20\n") } unsafe { delete walker; } @@ -221,9 +199,7 @@ def test_count_scalars(t : T?) { var walker = new CountWalker() var s = SimpleStruct(x = 1, y = 2.0) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(s), typeinfo rtti_typeinfo(s)) - } + adapter |> walk_data(unsafe(addr(s)), typeinfo rtti_typeinfo(s)) } t |> equal(walker.count, 2) // x(int) + y(float) unsafe { delete walker; } @@ -232,9 +208,7 @@ def test_count_scalars(t : T?) { var walker = new CountWalker() var s = NestedStruct(inner = SimpleStruct(x = 1, y = 2.0), tag = "test") make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(s), typeinfo rtti_typeinfo(s)) - } + adapter |> walk_data(unsafe(addr(s)), typeinfo rtti_typeinfo(s)) } t |> equal(walker.count, 3) // inner.x(int) + inner.y(float) + tag(string) unsafe { delete walker; } @@ -243,9 +217,7 @@ def test_count_scalars(t : T?) { var walker = new CountWalker() var arr = [1, 2, 3, 4, 5] make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(arr), typeinfo rtti_typeinfo(arr)) - } + adapter |> walk_data(unsafe(addr(arr)), typeinfo rtti_typeinfo(arr)) } t |> equal(walker.count, 5) unsafe { delete walker; } diff --git a/tests/data_walker/test_walk_filtering.das b/tests/data_walker/test_walk_filtering.das index d58d06b104..bf9af661d9 100644 --- a/tests/data_walker/test_walk_filtering.das +++ b/tests/data_walker/test_walk_filtering.das @@ -136,9 +136,7 @@ def test_can_visit_filtering(t : T?) { var walker = new SkipStructWalker() var s = SimpleStruct(x = 10, y = 2.5) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(s), typeinfo rtti_typeinfo(s)) - } + adapter |> walk_data(unsafe(addr(s)), typeinfo rtti_typeinfo(s)) } // Should see canVisitStructure but NOT beforeStruct/afterStruct or field values t |> equal(find(walker.log, "canVisitStructure:false") != -1, true) @@ -151,9 +149,7 @@ def test_can_visit_filtering(t : T?) { var walker = new SkipArrayWalker() var arr = [1, 2, 3] make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(arr), typeinfo rtti_typeinfo(arr)) - } + adapter |> walk_data(unsafe(addr(arr)), typeinfo rtti_typeinfo(arr)) } // Should NOT see any Int callbacks or beforeArray t |> equal(walker.log, "") @@ -168,9 +164,7 @@ def test_can_visit_array_data(t : T?) { var walker = new SkipArrayDataWalker() var arr = [1, 2, 3] make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(arr), typeinfo rtti_typeinfo(arr)) - } + adapter |> walk_data(unsafe(addr(arr)), typeinfo rtti_typeinfo(arr)) } // Should see beforeArray/afterArray but no element callbacks t |> equal(find(walker.log, "beforeArray") != -1, true) @@ -188,9 +182,7 @@ def test_can_visit_table_data(t : T?) { var walker = new SkipTableDataWalker() var tab <- {"a" => 1, "b" => 2} make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(tab), typeinfo rtti_typeinfo(tab)) - } + adapter |> walk_data(unsafe(addr(tab)), typeinfo rtti_typeinfo(tab)) } t |> equal(find(walker.log, "beforeTable") != -1, true) t |> equal(find(walker.log, "afterTable") != -1, true) @@ -209,9 +201,7 @@ def test_can_visit_pointer(t : T?) { var s = SimpleStruct(x = 99, y = 1.0) var p : SimpleStruct? = unsafe(addr(s)) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(p), typeinfo rtti_typeinfo(p)) - } + adapter |> walk_data(unsafe(addr(p)), typeinfo rtti_typeinfo(p)) } // Should NOT walk through the pointer t |> equal(walker.log, "") @@ -227,9 +217,7 @@ def test_selective_struct_visit(t : T?) { walker.skip_name = "SimpleStruct" var s = NestedStruct(inner = SimpleStruct(x = 1, y = 2.0), tag = "outer") make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(s), typeinfo rtti_typeinfo(s)) - } + adapter |> walk_data(unsafe(addr(s)), typeinfo rtti_typeinfo(s)) } // Should visit NestedStruct but skip SimpleStruct t |> equal(find(walker.log, "visit:NestedStruct") != -1, true) diff --git a/tests/data_walker/test_walk_lattice.das b/tests/data_walker/test_walk_lattice.das index 5d08e2f655..29fcb1db27 100644 --- a/tests/data_walker/test_walk_lattice.das +++ b/tests/data_walker/test_walk_lattice.das @@ -163,9 +163,7 @@ def test_walk_lattice_struct(t : T?) { bv = byte4(-1, 2, -3, 4), ubv = ubyte16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(s), typeinfo rtti_typeinfo(s)) - } + adapter |> walk_data(unsafe(addr(s)), typeinfo rtti_typeinfo(s)) } t |> equal(find(walker.log, "beforeStruct:LatticeStruct") != -1, true) t |> equal(find(walker.log, "Float16:{s.h}") != -1, true) @@ -191,9 +189,7 @@ def test_walk_lattice_arrays(t : T?) { a[0] = half4(1., 2., 3., 4.) a[1] = half4(5., 6., 7., 8.) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(a), typeinfo rtti_typeinfo(a)) - } + adapter |> walk_data(unsafe(addr(a)), typeinfo rtti_typeinfo(a)) } t |> equal(find(walker.log, "beforeDim") != -1, true) t |> equal(find(walker.log, "Half4:{a[0]}") != -1, true) @@ -205,9 +201,7 @@ def test_walk_lattice_arrays(t : T?) { var walker = new LogWalker() var arr = [byte4(1, 2, 3, 4), byte4(5, 6, 7, 8)] make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(arr), typeinfo rtti_typeinfo(arr)) - } + adapter |> walk_data(unsafe(addr(arr)), typeinfo rtti_typeinfo(arr)) } t |> equal(find(walker.log, "beforeArray") != -1, true) t |> equal(find(walker.log, "Byte4:{arr[0]}") != -1, true) diff --git a/tests/data_walker/test_walk_mutation.das b/tests/data_walker/test_walk_mutation.das index 29bc65822a..08fdc1d356 100644 --- a/tests/data_walker/test_walk_mutation.das +++ b/tests/data_walker/test_walk_mutation.das @@ -42,9 +42,7 @@ def test_mutation(t : T?) { var walker = new Doubler() var x = 21 make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(x, 42) unsafe { delete walker; } @@ -53,9 +51,7 @@ def test_mutation(t : T?) { var walker = new Doubler() var s = SimpleStruct(x = 5, y = 1.5) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(s), typeinfo rtti_typeinfo(s)) - } + adapter |> walk_data(unsafe(addr(s)), typeinfo rtti_typeinfo(s)) } t |> equal(s.x, 10) t |> equal(s.y, 3.0) @@ -65,9 +61,7 @@ def test_mutation(t : T?) { var walker = new Doubler() var arr = [1, 2, 3] make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(arr), typeinfo rtti_typeinfo(arr)) - } + adapter |> walk_data(unsafe(addr(arr)), typeinfo rtti_typeinfo(arr)) } t |> equal(arr[0], 2) t |> equal(arr[1], 4) @@ -83,9 +77,7 @@ def test_mutate_nested(t : T?) { var walker = new StringUpperWalker() var s = NestedStruct(inner = SimpleStruct(x = 1, y = 2.0), tag = "hello") make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(s), typeinfo rtti_typeinfo(s)) - } + adapter |> walk_data(unsafe(addr(s)), typeinfo rtti_typeinfo(s)) } t |> equal(s.tag, "HELLO") unsafe { delete walker; } @@ -94,9 +86,7 @@ def test_mutate_nested(t : T?) { var walker = new StringUpperWalker() var arr = ["abc", "def"] make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(arr), typeinfo rtti_typeinfo(arr)) - } + adapter |> walk_data(unsafe(addr(arr)), typeinfo rtti_typeinfo(arr)) } t |> equal(arr[0], "ABC") t |> equal(arr[1], "DEF") diff --git a/tests/data_walker/test_walk_scalars.das b/tests/data_walker/test_walk_scalars.das index 1eeb8a7c72..ce0aefb0c4 100644 --- a/tests/data_walker/test_walk_scalars.das +++ b/tests/data_walker/test_walk_scalars.das @@ -11,14 +11,12 @@ require dw_common [test] -def test_walk_int(t : T?) { // nolint:STYLE038 - flat list of independent walker arms +def test_walk_int(t : T?) { t |> run("int") @(t : T?) { var walker = new LogWalker() var x = 42 make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "Int:42\n") unsafe { delete walker; } @@ -27,9 +25,7 @@ def test_walk_int(t : T?) { // nolint:STYLE038 - flat list of independent walker var walker = new LogWalker() var x = 0xFF_u make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "UInt:0xff\n") unsafe { delete walker; } @@ -38,9 +34,7 @@ def test_walk_int(t : T?) { // nolint:STYLE038 - flat list of independent walker var walker = new LogWalker() var x = 100_000_000_000l make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "Int64:100000000000\n") unsafe { delete walker; } @@ -49,9 +43,7 @@ def test_walk_int(t : T?) { // nolint:STYLE038 - flat list of independent walker var walker = new LogWalker() var x = 99ul make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "UInt64:0x63\n") unsafe { delete walker; } @@ -60,9 +52,7 @@ def test_walk_int(t : T?) { // nolint:STYLE038 - flat list of independent walker var walker = new LogWalker() var x = int8(127) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "Int8:127\n") unsafe { delete walker; } @@ -71,9 +61,7 @@ def test_walk_int(t : T?) { // nolint:STYLE038 - flat list of independent walker var walker = new LogWalker() var x = uint8(200) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "UInt8:200\n") unsafe { delete walker; } @@ -82,9 +70,7 @@ def test_walk_int(t : T?) { // nolint:STYLE038 - flat list of independent walker var walker = new LogWalker() var x = int16(-1000) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "Int16:-1000\n") unsafe { delete walker; } @@ -93,9 +79,7 @@ def test_walk_int(t : T?) { // nolint:STYLE038 - flat list of independent walker var walker = new LogWalker() var x = uint16(60000) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "UInt16:60000\n") unsafe { delete walker; } @@ -109,9 +93,7 @@ def test_walk_float_double(t : T?) { var walker = new LogWalker() var x = 3.14 make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "Float:3.14\n") unsafe { delete walker; } @@ -120,9 +102,7 @@ def test_walk_float_double(t : T?) { var walker = new LogWalker() var x = 2.718281828lf make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "Double:2.718281828\n") unsafe { delete walker; } @@ -136,9 +116,7 @@ def test_walk_bool_string(t : T?) { var walker = new LogWalker() var x = true make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "Bool:true\n") unsafe { delete walker; } @@ -147,9 +125,7 @@ def test_walk_bool_string(t : T?) { var walker = new LogWalker() var x = false make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "Bool:false\n") unsafe { delete walker; } @@ -158,9 +134,7 @@ def test_walk_bool_string(t : T?) { var walker = new LogWalker() var x = "hello world" make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "String:hello world\n") unsafe { delete walker; } @@ -169,9 +143,7 @@ def test_walk_bool_string(t : T?) { var walker = new LogWalker() var x = "" make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) } t |> equal(walker.log, "String:\n") unsafe { delete walker; } @@ -185,9 +157,7 @@ def test_walk_enum(t : T?) { var walker = new LogWalker() var c : Color = Color.Green make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(c), typeinfo rtti_typeinfo(c)) - } + adapter |> walk_data(unsafe(addr(c)), typeinfo rtti_typeinfo(c)) } t |> equal(walker.log, "Enum:Color:1\n") unsafe { delete walker; } @@ -196,9 +166,7 @@ def test_walk_enum(t : T?) { var walker = new LogWalker() var c : Color = Color.Red make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(c), typeinfo rtti_typeinfo(c)) - } + adapter |> walk_data(unsafe(addr(c)), typeinfo rtti_typeinfo(c)) } t |> equal(walker.log, "Enum:Color:0\n") unsafe { delete walker; } @@ -212,9 +180,7 @@ def test_walk_bitfield(t : T?) { var walker = new LogWalker() var p : Permissions = Permissions.read | Permissions.execute make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(p), typeinfo rtti_typeinfo(p)) - } + adapter |> walk_data(unsafe(addr(p)), typeinfo rtti_typeinfo(p)) } // read=bit0 (1), execute=bit2 (4) → 5 = 0x5 t |> equal(walker.log, "Bitfield:0x5\n") @@ -224,9 +190,7 @@ def test_walk_bitfield(t : T?) { var walker = new LogWalker() var p : Permissions make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(p), typeinfo rtti_typeinfo(p)) - } + adapter |> walk_data(unsafe(addr(p)), typeinfo rtti_typeinfo(p)) } t |> equal(walker.log, "Bitfield:0x0\n") unsafe { delete walker; } diff --git a/tests/data_walker/test_walk_structs.das b/tests/data_walker/test_walk_structs.das index c95b65d5d3..b1e8dcc380 100644 --- a/tests/data_walker/test_walk_structs.das +++ b/tests/data_walker/test_walk_structs.das @@ -16,9 +16,7 @@ def test_walk_struct(t : T?) { var walker = new LogWalker() var s = SimpleStruct(x = 10, y = 2.5) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(s), typeinfo rtti_typeinfo(s)) - } + adapter |> walk_data(unsafe(addr(s)), typeinfo rtti_typeinfo(s)) } var expected = "beforeStruct:SimpleStruct\n" expected += "beforeField:x:false\n" @@ -35,9 +33,7 @@ def test_walk_struct(t : T?) { var walker = new LogWalker() var s = NestedStruct(inner = SimpleStruct(x = 1, y = 2.0), tag = "test") make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(s), typeinfo rtti_typeinfo(s)) - } + adapter |> walk_data(unsafe(addr(s)), typeinfo rtti_typeinfo(s)) } // Should see: NestedStruct → inner(SimpleStruct → x, y) → tag t |> equal(find(walker.log, "beforeStruct:NestedStruct") != -1, true) @@ -52,9 +48,7 @@ def test_walk_struct(t : T?) { var walker = new LogWalker() var s = ManyFields(a = 1, b = 2, c = 3, d = 4) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(s), typeinfo rtti_typeinfo(s)) - } + adapter |> walk_data(unsafe(addr(s)), typeinfo rtti_typeinfo(s)) } t |> equal(find(walker.log, "beforeField:a:false") != -1, true) t |> equal(find(walker.log, "beforeField:b:false") != -1, true) @@ -71,9 +65,7 @@ def test_walk_class(t : T?) { var walker = new LogWalker() var a = new Animal(name = "cat") make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(a), typeinfo rtti_typeinfo(a)) - } + adapter |> walk_data(unsafe(addr(a)), typeinfo rtti_typeinfo(a)) } // Walking a class pointer: beforePtr → beforeStruct:Animal → field:name → afterStruct → afterPtr t |> equal(find(walker.log, "beforeStruct:Animal") != -1, true) @@ -84,9 +76,7 @@ def test_walk_class(t : T?) { var walker = new LogWalker() var d = new Dog(name = "Rex", breed = "Shepherd") make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(d), typeinfo rtti_typeinfo(d)) - } + adapter |> walk_data(unsafe(addr(d)), typeinfo rtti_typeinfo(d)) } // Derived class should walk Dog fields including breed t |> equal(find(walker.log, "beforeStruct:Dog") != -1, true) @@ -116,9 +106,7 @@ def test_walk_all_scalars_in_struct(t : T?) { u64 = 200ul ) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(s), typeinfo rtti_typeinfo(s)) - } + adapter |> walk_data(unsafe(addr(s)), typeinfo rtti_typeinfo(s)) } // Verify all scalar callbacks fired t |> equal(find(walker.log, "Bool:true") != -1, true) @@ -149,9 +137,7 @@ def test_walk_vectors_in_struct(t : T?) { r = range(10, 20) ) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(s), typeinfo rtti_typeinfo(s)) - } + adapter |> walk_data(unsafe(addr(s)), typeinfo rtti_typeinfo(s)) } t |> equal(find(walker.log, "Float2:") != -1, true) t |> equal(find(walker.log, "Float3:") != -1, true) diff --git a/tests/data_walker/test_walk_tuples_variants.das b/tests/data_walker/test_walk_tuples_variants.das index 4027dc0826..df14b35193 100644 --- a/tests/data_walker/test_walk_tuples_variants.das +++ b/tests/data_walker/test_walk_tuples_variants.das @@ -15,9 +15,7 @@ def test_walk_tuple(t : T?) { var walker = new LogWalker() var tup : tuple = (42, "hello") make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(tup), typeinfo rtti_typeinfo(tup)) - } + adapter |> walk_data(unsafe(addr(tup)), typeinfo rtti_typeinfo(tup)) } var expected = "beforeTuple\n" expected += "beforeTupleEntry:0:false\n" @@ -34,9 +32,7 @@ def test_walk_tuple(t : T?) { var walker = new LogWalker() var tup : tuple = (1, 2.0, true) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(tup), typeinfo rtti_typeinfo(tup)) - } + adapter |> walk_data(unsafe(addr(tup)), typeinfo rtti_typeinfo(tup)) } // Middle element should not be last t |> equal(find(walker.log, "beforeTupleEntry:1:false") != -1, true) @@ -53,9 +49,7 @@ def test_walk_variant(t : T?) { var walker = new LogWalker() var v : MyVariant = MyVariant(i = 42) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(v), typeinfo rtti_typeinfo(v)) - } + adapter |> walk_data(unsafe(addr(v)), typeinfo rtti_typeinfo(v)) } t |> equal(find(walker.log, "beforeVariant") != -1, true) t |> equal(find(walker.log, "Int:42") != -1, true) @@ -69,9 +63,7 @@ def test_walk_variant(t : T?) { var walker = new LogWalker() var v : MyVariant = MyVariant(s = "hello") make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(v), typeinfo rtti_typeinfo(v)) - } + adapter |> walk_data(unsafe(addr(v)), typeinfo rtti_typeinfo(v)) } t |> equal(find(walker.log, "beforeVariant") != -1, true) t |> equal(find(walker.log, "String:hello") != -1, true) @@ -83,9 +75,7 @@ def test_walk_variant(t : T?) { var walker = new LogWalker() var v : MyVariant = MyVariant(f = 9.5) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(v), typeinfo rtti_typeinfo(v)) - } + adapter |> walk_data(unsafe(addr(v)), typeinfo rtti_typeinfo(v)) } t |> equal(find(walker.log, "Float:9.5") != -1, true) unsafe { delete walker; } diff --git a/tests/data_walker/test_walk_vectors_ranges.das b/tests/data_walker/test_walk_vectors_ranges.das index cb3bb61f09..78039fc721 100644 --- a/tests/data_walker/test_walk_vectors_ranges.das +++ b/tests/data_walker/test_walk_vectors_ranges.das @@ -15,9 +15,7 @@ def test_walk_vectors(t : T?) { // nolint:STYLE038 - flat list of independent wa var walker = new LogWalker() var v = int2(10, 20) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(v), typeinfo rtti_typeinfo(v)) - } + adapter |> walk_data(unsafe(addr(v)), typeinfo rtti_typeinfo(v)) } t |> equal(walker.log, "Int2:{v}\n") unsafe { delete walker; } @@ -26,9 +24,7 @@ def test_walk_vectors(t : T?) { // nolint:STYLE038 - flat list of independent wa var walker = new LogWalker() var v = int3(1, 2, 3) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(v), typeinfo rtti_typeinfo(v)) - } + adapter |> walk_data(unsafe(addr(v)), typeinfo rtti_typeinfo(v)) } t |> equal(walker.log, "Int3:{v}\n") unsafe { delete walker; } @@ -37,9 +33,7 @@ def test_walk_vectors(t : T?) { // nolint:STYLE038 - flat list of independent wa var walker = new LogWalker() var v = int4(1, 2, 3, 4) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(v), typeinfo rtti_typeinfo(v)) - } + adapter |> walk_data(unsafe(addr(v)), typeinfo rtti_typeinfo(v)) } t |> equal(walker.log, "Int4:{v}\n") unsafe { delete walker; } @@ -48,9 +42,7 @@ def test_walk_vectors(t : T?) { // nolint:STYLE038 - flat list of independent wa var walker = new LogWalker() var v = float2(1.5, 2.5) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(v), typeinfo rtti_typeinfo(v)) - } + adapter |> walk_data(unsafe(addr(v)), typeinfo rtti_typeinfo(v)) } t |> equal(walker.log, "Float2:{v}\n") unsafe { delete walker; } @@ -59,9 +51,7 @@ def test_walk_vectors(t : T?) { // nolint:STYLE038 - flat list of independent wa var walker = new LogWalker() var v = float3(1.0, 2.0, 3.0) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(v), typeinfo rtti_typeinfo(v)) - } + adapter |> walk_data(unsafe(addr(v)), typeinfo rtti_typeinfo(v)) } t |> equal(walker.log, "Float3:{v}\n") unsafe { delete walker; } @@ -70,9 +60,7 @@ def test_walk_vectors(t : T?) { // nolint:STYLE038 - flat list of independent wa var walker = new LogWalker() var v = float4(1.0, 2.0, 3.0, 4.0) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(v), typeinfo rtti_typeinfo(v)) - } + adapter |> walk_data(unsafe(addr(v)), typeinfo rtti_typeinfo(v)) } t |> equal(walker.log, "Float4:{v}\n") unsafe { delete walker; } @@ -81,9 +69,7 @@ def test_walk_vectors(t : T?) { // nolint:STYLE038 - flat list of independent wa var walker = new LogWalker() var v = uint2(1u, 2u) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(v), typeinfo rtti_typeinfo(v)) - } + adapter |> walk_data(unsafe(addr(v)), typeinfo rtti_typeinfo(v)) } t |> equal(walker.log, "UInt2:{v}\n") unsafe { delete walker; } @@ -92,9 +78,7 @@ def test_walk_vectors(t : T?) { // nolint:STYLE038 - flat list of independent wa var walker = new LogWalker() var v = uint3(1u, 2u, 3u) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(v), typeinfo rtti_typeinfo(v)) - } + adapter |> walk_data(unsafe(addr(v)), typeinfo rtti_typeinfo(v)) } t |> equal(walker.log, "UInt3:{v}\n") unsafe { delete walker; } @@ -103,9 +87,7 @@ def test_walk_vectors(t : T?) { // nolint:STYLE038 - flat list of independent wa var walker = new LogWalker() var v = uint4(1u, 2u, 3u, 4u) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(v), typeinfo rtti_typeinfo(v)) - } + adapter |> walk_data(unsafe(addr(v)), typeinfo rtti_typeinfo(v)) } t |> equal(walker.log, "UInt4:{v}\n") unsafe { delete walker; } @@ -119,9 +101,7 @@ def test_walk_ranges(t : T?) { var walker = new LogWalker() var r = range(0, 10) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(r), typeinfo rtti_typeinfo(r)) - } + adapter |> walk_data(unsafe(addr(r)), typeinfo rtti_typeinfo(r)) } t |> equal(walker.log, "Range:{r}\n") unsafe { delete walker; } @@ -130,9 +110,7 @@ def test_walk_ranges(t : T?) { var walker = new LogWalker() var r = urange(5u, 15u) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(r), typeinfo rtti_typeinfo(r)) - } + adapter |> walk_data(unsafe(addr(r)), typeinfo rtti_typeinfo(r)) } t |> equal(walker.log, "URange:{r}\n") unsafe { delete walker; } @@ -141,9 +119,7 @@ def test_walk_ranges(t : T?) { var walker = new LogWalker() var r = range64(0l, 100l) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(r), typeinfo rtti_typeinfo(r)) - } + adapter |> walk_data(unsafe(addr(r)), typeinfo rtti_typeinfo(r)) } t |> equal(walker.log, "Range64:{r}\n") unsafe { delete walker; } @@ -152,9 +128,7 @@ def test_walk_ranges(t : T?) { var walker = new LogWalker() var r = urange64(10ul, 20ul) make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(r), typeinfo rtti_typeinfo(r)) - } + adapter |> walk_data(unsafe(addr(r)), typeinfo rtti_typeinfo(r)) } t |> equal(walker.log, "URange64:{r}\n") unsafe { delete walker; } diff --git a/tests/debug_agent/test_callback_threadlock.das b/tests/debug_agent/test_callback_threadlock.das index 47c2172dfa..0c1599308d 100644 --- a/tests/debug_agent/test_callback_threadlock.das +++ b/tests/debug_agent/test_callback_threadlock.das @@ -53,15 +53,13 @@ def test_callback_and_pinvoke_are_serialized(t : T?) { var overlap = atomic32_create() var tick_done = atomic32_create() let agent_context = unsafe(addr(get_debug_agent_context("callback_threadlock_test"))) - unsafe { - invoke_in_context( - *agent_context, - "configure_callback", - entered, - release, - active, - overlap) - } + unsafe(invoke_in_context( + *agent_context, + "configure_callback", + entered, + release, + active, + overlap)) with_job_que() { new_thread() @() { tick_debug_agent("callback_threadlock_test") diff --git a/tests/debug_agent/test_invoke_in_context.das b/tests/debug_agent/test_invoke_in_context.das index ce90b7932e..b14255583d 100644 --- a/tests/debug_agent/test_invoke_in_context.das +++ b/tests/debug_agent/test_invoke_in_context.das @@ -32,9 +32,7 @@ def agent_reset() { [export, pinvoke] def agent_read_counter(var result : int?) { - unsafe { - *result = invoke_counter - } + *result = invoke_counter } def setup_invoke_agent(_ctx : Context) { @@ -103,13 +101,9 @@ def test_invoke_two_args(t : T?) { def test_invoke_multiple_calls(t : T?) { t |> run("multiple invoke_in_context calls accumulate") @(t : T?) { ensure_invoke_agent() - unsafe { - invoke_in_context(get_debug_agent_context("invoke_test"), "agent_reset") - } + unsafe(invoke_in_context(get_debug_agent_context("invoke_test"), "agent_reset")) for (_i in range(10)) { - unsafe { - invoke_in_context(get_debug_agent_context("invoke_test"), "agent_inc") - } + unsafe(invoke_in_context(get_debug_agent_context("invoke_test"), "agent_inc")) } var result = 0 unsafe { @@ -124,9 +118,7 @@ def test_local_unchanged(t : T?) { t |> run("local copy of global is unchanged by agent") @(t : T?) { ensure_invoke_agent() invoke_counter = 0 - unsafe { - invoke_in_context(get_debug_agent_context("invoke_test"), "agent_add", 100) - } + unsafe(invoke_in_context(get_debug_agent_context("invoke_test"), "agent_add", 100)) // local copy should still be 0 t |> equal(invoke_counter, 0) } diff --git a/tests/debug_agent/test_invoke_method.das b/tests/debug_agent/test_invoke_method.das index 96d2d81957..00f2cf01b6 100644 --- a/tests/debug_agent/test_invoke_method.das +++ b/tests/debug_agent/test_invoke_method.das @@ -40,9 +40,7 @@ def ensure_method_agent() { [export, pinvoke] def read_method_value(var result : int?) { - unsafe { - *result = method_value - } + *result = method_value } [test] @@ -50,9 +48,7 @@ def test_method_no_extra_args(t : T?) { t |> run("invoke_debug_agent_method with 0 user args") @(t : T?) { ensure_method_agent() // First set a known value via invoke_in_context so we can detect change - unsafe { - invoke_debug_agent_method("method_test", "set_zero") - } + unsafe(invoke_debug_agent_method("method_test", "set_zero")) var result = -1 unsafe { invoke_in_context(get_debug_agent_context("method_test"), "read_method_value", addr(result)) @@ -65,9 +61,7 @@ def test_method_no_extra_args(t : T?) { def test_method_one_arg(t : T?) { t |> run("invoke_debug_agent_method with 1 user arg") @(t : T?) { ensure_method_agent() - unsafe { - invoke_debug_agent_method("method_test", "set_from_arg", 77) - } + unsafe(invoke_debug_agent_method("method_test", "set_from_arg", 77)) var result = 0 unsafe { invoke_in_context(get_debug_agent_context("method_test"), "read_method_value", addr(result)) @@ -80,9 +74,7 @@ def test_method_one_arg(t : T?) { def test_method_two_args(t : T?) { t |> run("invoke_debug_agent_method with 2 user args") @(t : T?) { ensure_method_agent() - unsafe { - invoke_debug_agent_method("method_test", "set_sum", 30, 12) - } + unsafe(invoke_debug_agent_method("method_test", "set_sum", 30, 12)) var result = 0 unsafe { invoke_in_context(get_debug_agent_context("method_test"), "read_method_value", addr(result)) @@ -95,9 +87,7 @@ def test_method_two_args(t : T?) { def test_method_reads_agent_field(t : T?) { t |> run("method can read agent fields via self") @(t : T?) { ensure_method_agent() - unsafe { - invoke_debug_agent_method("method_test", "set_base_value") - } + unsafe(invoke_debug_agent_method("method_test", "set_base_value")) var result = 0 unsafe { invoke_in_context(get_debug_agent_context("method_test"), "read_method_value", addr(result)) diff --git a/tests/debug_agent/test_lifecycle.das b/tests/debug_agent/test_lifecycle.das index 097772857b..d6669eea0a 100644 --- a/tests/debug_agent/test_lifecycle.das +++ b/tests/debug_agent/test_lifecycle.das @@ -48,9 +48,7 @@ def test_get_agent_context_callable(t : T?) { t |> run("get_debug_agent_context returns callable context") @(t : T?) { ensure_lifecycle() // If this doesn't throw, the context is valid - unsafe { - invoke_in_context(get_debug_agent_context("lifecycle"), "lifecycle_noop") - } + unsafe(invoke_in_context(get_debug_agent_context("lifecycle"), "lifecycle_noop")) t |> equal(true, true) } } diff --git a/tests/debug_agent/test_on_log.das b/tests/debug_agent/test_on_log.das index a6eb11b98d..6a84878c16 100644 --- a/tests/debug_agent/test_on_log.das +++ b/tests/debug_agent/test_on_log.das @@ -33,16 +33,12 @@ def ensure_log_agent() { [export, pinvoke] def read_log_count(var result : int?) { - unsafe { - *result = log_count - } + *result = log_count } [export, pinvoke] def read_last_level(var result : int?) { - unsafe { - *result = last_log_level - } + *result = last_log_level } [export, pinvoke] @@ -55,9 +51,7 @@ def reset_log_state() { def test_to_log_triggers_on_log(t : T?) { t |> run("to_log routes through onLog") @(t : T?) { ensure_log_agent() - unsafe { - invoke_in_context(get_debug_agent_context("log_test"), "reset_log_state") - } + unsafe(invoke_in_context(get_debug_agent_context("log_test"), "reset_log_state")) to_log(LOG_INFO, "test message\n") var count = 0 unsafe { @@ -71,9 +65,7 @@ def test_to_log_triggers_on_log(t : T?) { def test_print_triggers_on_log(t : T?) { t |> run("print routes through onLog") @(t : T?) { ensure_log_agent() - unsafe { - invoke_in_context(get_debug_agent_context("log_test"), "reset_log_state") - } + unsafe(invoke_in_context(get_debug_agent_context("log_test"), "reset_log_state")) // this print is intentional. do not feint print("test print message\n") var count = 0 @@ -88,9 +80,7 @@ def test_print_triggers_on_log(t : T?) { def test_on_log_receives_level(t : T?) { t |> run("onLog receives the log level") @(t : T?) { ensure_log_agent() - unsafe { - invoke_in_context(get_debug_agent_context("log_test"), "reset_log_state") - } + unsafe(invoke_in_context(get_debug_agent_context("log_test"), "reset_log_state")) to_log(LOG_WARNING, "warning test\n") var level = -1 unsafe { diff --git a/tests/debug_agent/test_state_collection.das b/tests/debug_agent/test_state_collection.das index 2792068904..5543c06bf8 100644 --- a/tests/debug_agent/test_state_collection.das +++ b/tests/debug_agent/test_state_collection.das @@ -34,16 +34,12 @@ def ensure_collector() { [export, pinvoke] def read_collect_count(var result : int?) { - unsafe { - *result = collect_count - } + *result = collect_count } [export, pinvoke] def read_variable_count(var result : int?) { - unsafe { - *result = variable_count - } + *result = variable_count } [export, pinvoke] @@ -56,9 +52,7 @@ def reset_collector_state() { def test_on_collect_called(t : T?) { t |> run("collect_debug_agent_state triggers onCollect") @(t : T?) { ensure_collector() - unsafe { - invoke_in_context(get_debug_agent_context("collector"), "reset_collector_state") - } + unsafe(invoke_in_context(get_debug_agent_context("collector"), "reset_collector_state")) collect_debug_agent_state(this_context(), get_line_info(1)) var count = 0 unsafe { @@ -72,9 +66,7 @@ def test_on_collect_called(t : T?) { def test_on_collect_increments(t : T?) { t |> run("multiple collect calls increment counter") @(t : T?) { ensure_collector() - unsafe { - invoke_in_context(get_debug_agent_context("collector"), "reset_collector_state") - } + unsafe(invoke_in_context(get_debug_agent_context("collector"), "reset_collector_state")) collect_debug_agent_state(this_context(), get_line_info(1)) collect_debug_agent_state(this_context(), get_line_info(1)) var count = 0 diff --git a/tests/debug_agent/test_threadlock.das b/tests/debug_agent/test_threadlock.das index 3a6d8466ec..b63681c6e6 100644 --- a/tests/debug_agent/test_threadlock.das +++ b/tests/debug_agent/test_threadlock.das @@ -16,9 +16,7 @@ def tl_increment() { [export, pinvoke] def tl_read(var result : int?) { - unsafe { - *result = tl_counter - } + *result = tl_counter } [export, pinvoke] @@ -59,13 +57,9 @@ def test_threadlock_invoke(t : T?) { def test_threadlock_multiple(t : T?) { t |> run("multiple invoke_in_context calls under threadlock") @(t : T?) { ensure_tl_agent() - unsafe { - invoke_in_context(get_debug_agent_context("threadlock_test"), "tl_reset") - } + unsafe(invoke_in_context(get_debug_agent_context("threadlock_test"), "tl_reset")) for (_i in range(5)) { - unsafe { - invoke_in_context(get_debug_agent_context("threadlock_test"), "tl_increment") - } + unsafe(invoke_in_context(get_debug_agent_context("threadlock_test"), "tl_increment")) } var result = 0 unsafe { diff --git a/tests/decs/test_gc.das b/tests/decs/test_gc.das index c2d0b2fc46..036e1adbdf 100644 --- a/tests/decs/test_gc.das +++ b/tests/decs/test_gc.das @@ -92,9 +92,7 @@ def test_gc_arrays(t : T?) { } } before_gc() - unsafe { - heap_collect(true, true) - } + unsafe(heap_collect(true, true)) after_gc() t |> run("after gc") @(t : T?) { query() $(values : array; i : int) { @@ -122,9 +120,7 @@ def test_gc_strings(t : T?) { t |> equal(i, 3) } before_gc() - unsafe { - heap_collect(true, true) - } + unsafe(heap_collect(true, true)) after_gc() t |> run("after string gc") @(t : T?) { var j = 0 @@ -197,9 +193,7 @@ def test_gc_stress(t : T?) { // nolint:STYLE037,STYLE038 - one randomized stre } if ((random_int(seed) % 100) < 50) { before_gc() - unsafe { - heap_collect(true, true) - } + unsafe(heap_collect(true, true)) after_gc() } commit() @@ -238,9 +232,7 @@ def test_gc_stress(t : T?) { // nolint:STYLE037,STYLE038 - one randomized stre data |> mem_archive_load(decsState) } else { before_gc() - unsafe { - heap_collect(true, true) - } + unsafe(heap_collect(true, true)) after_gc() } query() $(values : array; i : int) { diff --git a/tests/fio/fio_dwrite.das b/tests/fio/fio_dwrite.das index 78f4e8de9b..78fddf4143 100644 --- a/tests/fio/fio_dwrite.das +++ b/tests/fio/fio_dwrite.das @@ -95,9 +95,7 @@ def test_dwrite(t : T?) { } var bp = unsafe(reinterpret(band)) for (i in range(take)) { - unsafe { - bp[i] = dwrite_pattern(total + i) - } + unsafe(bp[i]) = dwrite_pattern(total + i) } ok = ok && unsafe(dwrite_commit(w, uint64(take))) total += take @@ -131,9 +129,7 @@ def test_dwrite(t : T?) { } var bp = unsafe(reinterpret(band)) for (i in range(100)) { - unsafe { - bp[i] = dwrite_pattern(total + i) - } + unsafe(bp[i]) = dwrite_pattern(total + i) } ok = ok && unsafe(dwrite_commit(w, 100ul)) total += 100 diff --git a/tests/fio/fio_exit_now.das b/tests/fio/fio_exit_now.das index 7bcb091f93..bc5ee41513 100644 --- a/tests/fio/fio_exit_now.das +++ b/tests/fio/fio_exit_now.das @@ -11,9 +11,7 @@ def test_exit_now_binds_under_aot(t : T?) { t |> run("exit_now compiles into generated C++ against the public header") @(t : T?) { let args <- get_command_line_arguments() if (empty(args)) { - unsafe { - exit_now(3) - } + unsafe(exit_now(3)) } t |> success(!empty(args), "the process is still here: argv carried the interpreter") } diff --git a/tests/fio/fio_fmap_rw.das b/tests/fio/fio_fmap_rw.das index 1ac5c554b1..f8761a53d5 100644 --- a/tests/fio/fio_fmap_rw.das +++ b/tests/fio/fio_fmap_rw.das @@ -48,14 +48,10 @@ def test_fmap_rw(t : T?) { // nolint:STYLE038 - flat list of independent mapping t |> success(intact, "mapped content matches what was written") var at = 0 while (at < n) { - unsafe { - bp[at] = uint8(255 - int(rw_pattern(at))) - } + unsafe(bp[at]) = uint8(255 - int(rw_pattern(at))) at += 4099 } - unsafe { - fmap_close(base, msize) - } + unsafe(fmap_close(base, msize)) // reopen READ-ONLY: the flips must have landed in the file itself var persisted = false fopen(fname, "rb") $(f) { diff --git a/tests/fio/fio_prefetch.das b/tests/fio/fio_prefetch.das index 67d2ca580e..d3dbce47e3 100644 --- a/tests/fio/fio_prefetch.das +++ b/tests/fio/fio_prefetch.das @@ -52,8 +52,6 @@ def test_prefetch_map(t : T?) { remove(fname) } t |> run("degenerate arguments decline instead of crashing") @(t : T?) { - unsafe { - t |> success(!prefetch_map(null, 0ul), "null base + zero bytes declines") - } + t |> success(!unsafe(prefetch_map(null, 0ul)), "null base + zero bytes declines") } } diff --git a/tests/fixed_array/test_layout.das b/tests/fixed_array/test_layout.das index 6f073bc3dd..0e0e9b2361 100644 --- a/tests/fixed_array/test_layout.das +++ b/tests/fixed_array/test_layout.das @@ -112,9 +112,7 @@ def test_composite_layout(t : T?) { t |> run("variant with FA arm") @(t : T?) { var vf : VarFA t |> equal(typeinfo sizeof(vf), 20) // 16 payload + index - unsafe { - vf.ints[1] = 7 - } + unsafe(vf.ints)[1] = 7 t |> success(vf is ints) t |> equal((vf as ints)[1], 7) } diff --git a/tests/gc/gc_typedecl.das b/tests/gc/gc_typedecl.das index db375efd6f..231e268005 100644 --- a/tests/gc/gc_typedecl.das +++ b/tests/gc/gc_typedecl.das @@ -27,9 +27,7 @@ def compile_and_run(file_path : string) : bool { to_log(LOG_ERROR, "simulate failed: {serrors}\n") return } - unsafe { - invoke_in_context(context, "test") - } + unsafe(invoke_in_context(context, "test")) result = true } } @@ -154,9 +152,7 @@ def test_thread_root_decrease_investigation(t : T?) { let c2 = gc_thread_root_count() to_log(LOG_INFO, "after simulate: {c2} (delta from compile: {int64(c2)-int64(c1)})\n") t |> success(sok, "simulation succeeded") - unsafe { - invoke_in_context(context, "test") - } + unsafe(invoke_in_context(context, "test")) let c3 = gc_thread_root_count() to_log(LOG_INFO, "after invoke: {c3} (delta from simulate: {int64(c3)-int64(c2)})\n") } diff --git a/tests/gc/lattice_escape_tests.das b/tests/gc/lattice_escape_tests.das index 9fe3519fae..46d0c57b42 100644 --- a/tests/gc/lattice_escape_tests.das +++ b/tests/gc/lattice_escape_tests.das @@ -326,10 +326,8 @@ def use_ret_param(i : int) : int { def unsafe_addr_local(i : int) : int { var p = new Node(x = i, y = i * 2) var r = p.x + p.y - unsafe { - let pp = addr(p) // taking the address marks the function unsafe -> excluded - if (pp == null) { r = -1 } // never taken; consumes pp without a dead store - } + let pp = unsafe(addr(p)) // taking the address marks the function unsafe -> excluded + if (pp == null) { r = -1 } // never taken; consumes pp without a dead store return r } diff --git a/tests/gc/test_gc_coverage.das b/tests/gc/test_gc_coverage.das index 8f42dcd2db..40ac2bcd0d 100644 --- a/tests/gc/test_gc_coverage.das +++ b/tests/gc/test_gc_coverage.das @@ -28,9 +28,7 @@ var g_big : array var g_garbage_sink : Holder? def collect() { - unsafe { - heap_collect(true, true) - } + unsafe(heap_collect(true, true)) } def make_garbage(n : int) { diff --git a/tests/gc/test_gc_deep_recursion.das b/tests/gc/test_gc_deep_recursion.das index 097abdb60b..54203949f9 100644 --- a/tests/gc/test_gc_deep_recursion.das +++ b/tests/gc/test_gc_deep_recursion.das @@ -37,8 +37,6 @@ def chain_len(head : Node?) : int { def test_gc_deep_chain_no_overflow(t : T?) { let depth = 200000 build_chain(depth) - unsafe { - heap_collect(true, true) // validate=true: no overflow, no dangling pointers - } + unsafe(heap_collect(true, true)) // validate=true: no overflow, no dangling pointers t |> equal(chain_len(g_head), depth) // whole chain survived GC (reachable, not swept) } diff --git a/tests/gc/test_gc_escape_free.das b/tests/gc/test_gc_escape_free.das index ad947df083..78309882e8 100644 --- a/tests/gc/test_gc_escape_free.das +++ b/tests/gc/test_gc_escape_free.das @@ -127,14 +127,14 @@ def move_into_local_box_read(i : int) : int { [test] def test_escape_free_does_not_free_global(t : T?) { leak_into_global(42) - unsafe { heap_collect(true, true) } + unsafe(heap_collect(true, true)) t |> equal(g_kept.x, 42) } [test] def test_escape_free_does_not_free_returned(t : T?) { var n = make_node(7) - unsafe { heap_collect(true, true) } + unsafe(heap_collect(true, true)) t |> equal(n.x, 7) unsafe { delete n } } @@ -144,7 +144,7 @@ def test_escape_free_does_not_free_pushed(t : T?) { g_list |> clear() push_into_global(11) push_into_global(22) - unsafe { heap_collect(true, true) } + unsafe(heap_collect(true, true)) t |> equal(length(g_list), 2) t |> equal(g_list[0].x, 11) t |> equal(g_list[1].x, 22) @@ -153,7 +153,7 @@ def test_escape_free_does_not_free_pushed(t : T?) { [test] def test_escape_free_does_not_free_aliased(t : T?) { alias_then_escape(99) - unsafe { heap_collect(true, true) } + unsafe(heap_collect(true, true)) t |> equal(g_kept.x, 99) // survived: neither p nor its alias q was statically freed } @@ -162,7 +162,7 @@ def test_escape_free_does_not_free_aliased(t : T?) { [test] def test_escape_free_nested_sound(t : T?) { let s = churn_nested() - unsafe { heap_collect(true, true) } + unsafe(heap_collect(true, true)) t |> equal(s, (500 - 1) * 500 / 2 + 500 * 10) } @@ -171,7 +171,7 @@ def test_escape_free_nested_sound(t : T?) { [test] def test_escape_free_does_not_free_captured(t : T?) { capture_into_global(55) - unsafe { heap_collect(true, true) } + unsafe(heap_collect(true, true)) t |> equal(invoke(g_lam), 55) } @@ -203,21 +203,21 @@ def test_escape_free_does_not_run_user_finalizer(t : T?) { [test] def test_escape_free_does_not_free_stored_by_script(t : T?) { escape_via_script(77) - unsafe { heap_collect(true, true) } + unsafe(heap_collect(true, true)) t |> equal(g_kept.x, 77) } [test] def test_escape_free_does_not_free_stored_by_script_transitive(t : T?) { escape_via_script_transitive(88) - unsafe { heap_collect(true, true) } + unsafe(heap_collect(true, true)) t |> equal(g_kept.x, 88) } [test] def test_escape_free_does_not_free_captured_by_script(t : T?) { escape_via_script_capture(66) - unsafe { heap_collect(true, true) } + unsafe(heap_collect(true, true)) t |> equal(invoke(g_lam), 66) } @@ -227,7 +227,7 @@ def test_escape_free_does_not_free_captured_by_script(t : T?) { def test_escape_free_move_into_escaping_struct_not_freed(t : T?) { g_boxes |> clear() move_into_escaping_box(55) - unsafe { heap_collect(true, true) } // throws if the moved-in pointee was wrongly freed + unsafe(heap_collect(true, true)) // throws if the moved-in pointee was wrongly freed t |> equal(length(g_boxes), 1) t |> equal(g_boxes[0].node.x, 55) // survived intact through move + escape } @@ -238,6 +238,6 @@ def test_escape_free_move_into_escaping_struct_not_freed(t : T?) { def test_escape_free_move_into_local_struct_sound(t : T?) { var acc = 0 for (i in range(100)) { acc += move_into_local_box_read(i) } - unsafe { heap_collect(true, true) } + unsafe(heap_collect(true, true)) t |> equal(acc, (100 - 1) * 100 / 2) } diff --git a/tests/jit_tests/aarch64_neon.das b/tests/jit_tests/aarch64_neon.das index 1757a9acca..0273d58eec 100644 --- a/tests/jit_tests/aarch64_neon.das +++ b/tests/jit_tests/aarch64_neon.das @@ -32,14 +32,12 @@ def ref_sdot4(acc : int4; w : int8 const?; x : int8 const?) : int4 { def ref_sdot4_w(acc : int4; w : int4; x : int8 const?) : int4 { var r = acc - unsafe { - for (j in range(4)) { - var s = 0 - for (e in range(4)) { - s += packed_byte_sx(w[j], e) * int(x[4 * j + e]) - } - r[j] += s + for (j in range(4)) { + var s = 0 + for (e in range(4)) { + s += packed_byte_sx(w[j], e) * int(unsafe(x[4 * j + e])) } + r[j] += s } return r } @@ -60,14 +58,12 @@ def ref_sdot4_laneq(acc : int4; w : int8 const?; x : int8 const?; lane : int) : def ref_sdot4_laneq_w(acc : int4; w : int4; x : int8 const?; lane : int) : int4 { var r = acc - unsafe { - for (j in range(4)) { - var s = 0 - for (e in range(4)) { - s += packed_byte_sx(w[j], e) * int(x[4 * lane + e]) - } - r[j] += s + for (j in range(4)) { + var s = 0 + for (e in range(4)) { + s += packed_byte_sx(w[j], e) * int(unsafe(x[4 * lane + e])) } + r[j] += s } return r } diff --git a/tests/jit_tests/const_arg_readonly.das b/tests/jit_tests/const_arg_readonly.das index 74f2285872..e9b465bdb9 100644 --- a/tests/jit_tests/const_arg_readonly.das +++ b/tests/jit_tests/const_arg_readonly.das @@ -18,19 +18,15 @@ struct Cell { // const void? out-parameter, cast to a typed pointer [hint(noinline)] def route_void(dst : void?; v : int) { - unsafe { - var p = reinterpret(dst) - *p = v - } + var p = unsafe(reinterpret(dst)) + *p = v } // const typed pointer, cast to its own type [hint(noinline)] def route_same_type(dst : int?; v : int) { - unsafe { - var p = reinterpret(dst) - *p = v - } + var p = unsafe(reinterpret(dst)) + *p = v } // const void? out-parameter as a memcpy destination @@ -45,19 +41,15 @@ def route_memcpy(dst : void?; v : int) { // const structure reference, address taken and cast back [hint(noinline)] def route_const_ref(c : Cell; v : int) { - unsafe { - var p = addr(c) - p.a = v - } + var p = unsafe(addr(c)) + p.a = v } // const typed pointer under a noalias hint - with no readonly the hint alone keeps the write [hint(noinline, noalias = dst)] def route_noalias(dst : int const?; v : int) { - unsafe { - var p = reinterpret(dst) - *p = v - } + var p = unsafe(reinterpret(dst)) + *p = v } [test] @@ -65,30 +57,22 @@ def test_write_through_const_argument(t : T?) { t |> success(!jit_enabled() || is_jit_function(@@route_void)) t |> run("const typed pointer under noalias") @(t : T?) { var slot = 0 - unsafe { - route_noalias(addr(slot), 40) - } + route_noalias(unsafe(addr(slot)), 40) t |> equal(40, slot) } t |> run("const void? out-parameter") @(t : T?) { var slot = 0 - unsafe { - route_void(addr(slot), 41) - } + route_void(unsafe(addr(slot)), 41) t |> equal(41, slot) } t |> run("const typed pointer") @(t : T?) { var slot = 0 - unsafe { - route_same_type(addr(slot), 42) - } + route_same_type(unsafe(addr(slot)), 42) t |> equal(42, slot) } t |> run("const void? memcpy destination") @(t : T?) { var slot = 0 - unsafe { - route_memcpy(addr(slot), 43) - } + route_memcpy(unsafe(addr(slot)), 43) t |> equal(43, slot) } t |> run("const structure reference") @(t : T?) { @@ -102,26 +86,20 @@ def test_write_through_const_argument(t : T?) { // every mode [hint(noinline)] def route_var_parameter(var dst : void?; v : int) { - unsafe { - var p = reinterpret(dst) - *p = v - } + var p = unsafe(reinterpret(dst)) + *p = v } [test] def test_var_parameter_is_the_control(t : T?) { var slot = 0 - unsafe { - route_var_parameter(addr(slot), 47) - } + route_var_parameter(unsafe(addr(slot)), 47) t |> equal(47, slot, "the same body with a var parameter") } [test] def test_write_through_const_argument_across_modules(t : T?) { var slot = 0 - unsafe { - store_int(addr(slot), 46) - } + store_int(unsafe(addr(slot)), 46) t |> equal(46, slot, "a cross-partition callee needs no inlining hint") } diff --git a/tests/jit_tests/cross_target_folds.das b/tests/jit_tests/cross_target_folds.das index b25a46e5b5..3bc53f288a 100644 --- a/tests/jit_tests/cross_target_folds.das +++ b/tests/jit_tests/cross_target_folds.das @@ -22,19 +22,17 @@ def private spawn_child(cmd : string; var lines : array) : int { if (get_platform_name() == "windows") { full = "\"{full}\"" // cmd.exe strips the first and last quote of a line that opens with one } - unsafe { - rc = popen_timeout(full, 300.0) $(f) { - if (f == null) { - return - } - while (!feof(f)) { - let ln = strip(fgets(f)) - if (!empty(ln)) { - lines |> push("{ln}") - } + rc = unsafe(popen_timeout(full, 300.0) $(f) { + if (f == null) { + return + } + while (!feof(f)) { + let ln = strip(fgets(f)) + if (!empty(ln)) { + lines |> push("{ln}") } } - } + }) return rc } diff --git a/tests/jit_tests/exe_host_cpu.das b/tests/jit_tests/exe_host_cpu.das index 796598263a..ca459af173 100644 --- a/tests/jit_tests/exe_host_cpu.das +++ b/tests/jit_tests/exe_host_cpu.das @@ -52,20 +52,17 @@ def private neutral_env() : string { } def private spawn_child(cmd : string; var lines : array) : int { - var rc : int - unsafe { - rc = popen_timeout("{cmd} 2>&1", 300.0) $(f) { - if (f == null) { - return - } - while (!feof(f)) { - let ln = strip(fgets(f)) - if (!empty(ln)) { - lines |> push("{ln}") - } + let rc = unsafe(popen_timeout("{cmd} 2>&1", 300.0) $(f) { + if (f == null) { + return + } + while (!feof(f)) { + let ln = strip(fgets(f)) + if (!empty(ln)) { + lines |> push("{ln}") } } - } + }) return rc } diff --git a/tests/jit_tests/jit_exe.das b/tests/jit_tests/jit_exe.das index 03a16c6ee1..83a76fdd27 100644 --- a/tests/jit_tests/jit_exe.das +++ b/tests/jit_tests/jit_exe.das @@ -144,13 +144,11 @@ def compile_to_exe(t : T?; src : string; out : string) : bool { def run_exe(exe : string) : string { var output = "" - unsafe { - popen("{exe}.exe") $(f) { - while (!feof(f)) { - output += fgets(f) - } + unsafe(popen("{exe}.exe") $(f) { + while (!feof(f)) { + output += fgets(f) } - } + }) return output } diff --git a/tests/jit_tests/jit_lib.das b/tests/jit_tests/jit_lib.das index c7781b49c7..d56549c378 100644 --- a/tests/jit_tests/jit_lib.das +++ b/tests/jit_tests/jit_lib.das @@ -13,20 +13,17 @@ let SHARED_FIXTURE = "{get_das_root()}/tests-cpp/big/standalone_ctx/standalone_i def private spawn(cmd : string; var lines : array) : int { - var rc : int - unsafe { - rc = popen_timeout("{cmd} 2>&1", 600.0) $(f) { - if (f == null) { - return - } - while (!feof(f)) { - let ln = strip(fgets(f)) - if (!(ln |> empty())) { - lines |> push("{ln}") - } + let rc = unsafe(popen_timeout("{cmd} 2>&1", 600.0) $(f) { + if (f == null) { + return + } + while (!feof(f)) { + let ln = strip(fgets(f)) + if (!(ln |> empty())) { + lines |> push("{ln}") } } - } + }) return rc } diff --git a/tests/jit_tests/llvm_compile_only.das b/tests/jit_tests/llvm_compile_only.das index 0e03faa0b2..dd02aec11b 100644 --- a/tests/jit_tests/llvm_compile_only.das +++ b/tests/jit_tests/llvm_compile_only.das @@ -30,20 +30,17 @@ def test_jit_compile_only(t : T?) { var sawCompileOnly = false var sawResult = false var sawDllCache = false - var rc : int - unsafe { - rc = popen_timeout(cmd, 300.0) $(f) { - if (f == null) { - return - } - while (!feof(f)) { - let ln = fgets(f) - sawCompileOnly ||= find(ln, "LLVM JIT: compile-only") >= 0 - sawResult ||= find(ln, "COMPILE_ONLY_RESULT 402") >= 0 - sawDllCache ||= find(ln, "DLL cache") >= 0 - } + let rc = unsafe(popen_timeout(cmd, 300.0) $(f) { + if (f == null) { + return } - } + while (!feof(f)) { + let ln = fgets(f) + sawCompileOnly ||= find(ln, "LLVM JIT: compile-only") >= 0 + sawResult ||= find(ln, "COMPILE_ONLY_RESULT 402") >= 0 + sawDllCache ||= find(ln, "DLL cache") >= 0 + } + }) t |> equal(rc, 0) t |> success(sawCompileOnly) // the compile-only path ran to the escape t |> success(sawResult) // interpreted execution still produced the right answer diff --git a/tests/jit_tests/llvm_split_modules.das b/tests/jit_tests/llvm_split_modules.das index b9abd5a403..ccd2708407 100644 --- a/tests/jit_tests/llvm_split_modules.das +++ b/tests/jit_tests/llvm_split_modules.das @@ -15,19 +15,16 @@ require strings def private run_split_child(cmd : string; hit_marker : string) : tuple { var sawResult = false var sawMarker = false - var rc : int - unsafe { - rc = popen_timeout(cmd, 300.0) $(f) { - if (f == null) { - return - } - while (!feof(f)) { - let ln = fgets(f) - sawResult ||= find(ln, "SPLIT_RESULT 340 19 36 33 -1") >= 0 - sawMarker ||= find(ln, hit_marker) >= 0 - } + let rc = unsafe(popen_timeout(cmd, 300.0) $(f) { + if (f == null) { + return } - } + while (!feof(f)) { + let ln = fgets(f) + sawResult ||= find(ln, "SPLIT_RESULT 340 19 36 33 -1") >= 0 + sawMarker ||= find(ln, hit_marker) >= 0 + } + }) return (rc = rc, sawResult = sawResult, sawMarker = sawMarker) } diff --git a/tests/jit_tests/memset.das b/tests/jit_tests/memset.das index 68499e3ac1..8a83a5586d 100644 --- a/tests/jit_tests/memset.das +++ b/tests/jit_tests/memset.das @@ -4,39 +4,27 @@ require dastest/testing_boost require daslib/constant_expression def jit_memset8(var data : void?; value : uint8; size : int) { - unsafe { - memset8(data, value, size) - } + unsafe(memset8(data, value, size)) } def jit_memset16(var data : void?; value : uint16; size : int) { - unsafe { - memset16(data, value, size) - } + unsafe(memset16(data, value, size)) } def jit_memset32(var data : void?; value : uint; size : int) { - unsafe { - memset32(data, value, size) - } + unsafe(memset32(data, value, size)) } def jit_memset64(var data : void?; value : uint64; size : int) { - unsafe { - memset64(data, value, size) - } + unsafe(memset64(data, value, size)) } def jit_memset128(var data : void?; value : uint4; size : int) { - unsafe { - memset128(data, value, size) - } + unsafe(memset128(data, value, size)) } def jit_memmove(var dst : void?; src : void?; size : int) { - unsafe { - memmove(dst, src, size) - } + unsafe(memmove(dst, src, size)) } [constant_expression(funcname), sideeffects] diff --git a/tests/jit_tests/new_ascend_and_delete.das b/tests/jit_tests/new_ascend_and_delete.das index 25168c0261..9f9d15359b 100644 --- a/tests/jit_tests/new_ascend_and_delete.das +++ b/tests/jit_tests/new_ascend_and_delete.das @@ -57,9 +57,7 @@ def return_smart_ptr(t : T?) { var ptr <- makeTestObjectSmart() t |> equal(1u, countTestObjectSmart(ptr)) t |> equal(1, getTotalTestObjectSmart()) - unsafe { - delete ptr - } + delete ptr t |> equal(null, ptr) t |> equal(0, getTotalTestObjectSmart()) } @@ -95,9 +93,7 @@ def move_test(t : T?) { t |> equal(0, getTotalTestObjectSmart()) var D <- inside_move_test(t) t |> equal(1, getTotalTestObjectSmart()) - unsafe { - delete D - } + delete D t |> equal(0, getTotalTestObjectSmart()) } @@ -124,21 +120,15 @@ def ref_count_test(t : T?) { t |> success(fptr == sptr) t |> equal(3u, smart_ptr_use_count(sptr)) t |> equal(1, getTotalTestObjectSmart()) - unsafe { - delete sptr // ref_count = 2 - } + delete sptr // ref_count = 2 t |> equal(1, getTotalTestObjectSmart()) t |> equal(0u, smart_ptr_use_count(sptr)) t |> equal(2u, smart_ptr_use_count(qptr)) - unsafe { - delete qptr // ref_count = 1 - } + delete qptr // ref_count = 1 t |> equal(1, getTotalTestObjectSmart()) t |> equal(0u, smart_ptr_use_count(qptr)) t |> equal(1u, smart_ptr_use_count(fptr)) - unsafe { - delete fptr // physical delete - } + delete fptr // physical delete t |> equal(0, getTotalTestObjectSmart()) t |> equal(0u, smart_ptr_use_count(fptr)) } @@ -151,9 +141,7 @@ def access_test(t : T?) { t |> equal(1234, D) ptr ?. fooData ?? D = 13 // ?? lvalue t |> equal(13, ptr.fooData) - unsafe { - delete ptr - } + delete ptr D = ptr ?. fooData ?? 2 t |> equal(2, D) unsafe { @@ -162,10 +150,8 @@ def access_test(t : T?) { } t |> success(ptr.first.fooData == 1234) t |> success(ptr ?. first ?. fooData ?? 13 == 1234) - unsafe { - delete ptr.first - delete ptr - } + delete ptr.first + delete ptr t |> equal(0, getTotalTestObjectSmart()) } diff --git a/tests/jit_tests/pointer.das b/tests/jit_tests/pointer.das index ee022b6744..973bad982c 100644 --- a/tests/jit_tests/pointer.das +++ b/tests/jit_tests/pointer.das @@ -8,18 +8,14 @@ def make13(var a : int?) { def makeAll13(var a : int?; count : int) { for (i in range(count)) { - unsafe { - a[i] = 13 - } + unsafe(a[i]) = 13 } } def addAll(var a : int?; count : int) { var c = 0 for (i in range(count)) { - unsafe { - c += a[i] - } + c += unsafe(a[i]) } return c } @@ -28,9 +24,7 @@ def ptrAdd(var a : int?; count : int) { var c = 0 for (_i in range(count)) { c += *a - unsafe { - ++ a - } + unsafe { ++ a } // nolint:STYLE025 - unsafe(++ a) does not authorize the lowered i_das_ptr_inc call } return c } diff --git a/tests/jit_tests/trap_block_ann.das b/tests/jit_tests/trap_block_ann.das index ef3c8e65b3..d3a8ad0fcc 100644 --- a/tests/jit_tests/trap_block_ann.das +++ b/tests/jit_tests/trap_block_ann.das @@ -107,13 +107,11 @@ def test_annotated_block_exe(t : T?) { t |> equal(write_exe_script(), true) if (!compile_to_exe(t)) return var output = "" - unsafe { - popen(EXE_BINARY) $(f) { - while (!feof(f)) { - output += fgets(f) - } + unsafe(popen(EXE_BINARY) $(f) { + while (!feof(f)) { + output += fgets(f) } - } + }) // ad=0x0 is the correct answer for a standalone exe, not a shortfall of the resolve: the payload // is made by the compiling process, and an exe context is built by jit_create_standalone_ctx // rather than simulate(), so it has no sid->data table for jit_ad_by_sid to read. Before the fix diff --git a/tests/jit_tests/variant.das b/tests/jit_tests/variant.das index 7d10e1a8cc..9e47c4236c 100644 --- a/tests/jit_tests/variant.das +++ b/tests/jit_tests/variant.das @@ -77,9 +77,7 @@ def ask_variant_index { [sideeffects] def change_variant_index { var f = FooT(b = 1.) - unsafe { - set_variant_index(f, 0) - } + unsafe(set_variant_index(f, 0)) return f as a } diff --git a/tests/jobque/test_jobque_jobs.das b/tests/jobque/test_jobque_jobs.das index daa6f09876..6c9a72b712 100644 --- a/tests/jobque/test_jobque_jobs.das +++ b/tests/jobque/test_jobque_jobs.das @@ -278,10 +278,7 @@ def test_persistent_que_frame_loop(t : T?) { let PASSES = 25 var data : array data |> resize(N) - var pdata : array? - unsafe { - pdata = addr(data) - } + var pdata = unsafe(addr(data)) var every_pass_ready = true for (_p in range(PASSES)) { var status = job_status_create() @@ -299,9 +296,7 @@ def test_persistent_que_frame_loop(t : T?) { } } every_pass_ready = every_pass_ready && poll_ready(status) - unsafe { - job_status_remove(status) - } + unsafe(job_status_remove(status)) } t |> success(every_pass_ready, "every pass reached isReady") var advanced = 0 @@ -326,10 +321,7 @@ def test_persistent_que_empty_band(t : T?) { let BANDS = 8 // more bands than elements: 6 of them get nothing var data : array data |> resize(N) - var pdata : array? - unsafe { - pdata = addr(data) - } + var pdata = unsafe(addr(data)) var status = job_status_create() status |> append(BANDS) let chunk = (N + BANDS - 1) / BANDS @@ -351,9 +343,7 @@ def test_persistent_que_empty_band(t : T?) { } } t |> success(poll_ready(status), "the wait group balances when bands outnumber work") - unsafe { - job_status_remove(status) - } + unsafe(job_status_remove(status)) t |> equal(data[0], 1) t |> equal(data[1], 1) destroy_job_que() diff --git a/tests/jobque/test_jobque_tracking.das b/tests/jobque/test_jobque_tracking.das index d2b8c85509..559c6398a5 100644 --- a/tests/jobque/test_jobque_tracking.das +++ b/tests/jobque/test_jobque_tracking.das @@ -15,20 +15,16 @@ def test_tracking_clean_run(t : T?) { } } t |> run("lockbox create+remove leaves no leak") @(t : T?) { - unsafe { - var box = lock_box_create() - t |> success(box != null) - box |> lock_box_remove - t |> success(box == null) - } + var box = lock_box_create() + t |> success(box != null) + unsafe(box |> lock_box_remove) + t |> success(box == null) } t |> run("job_status create+remove leaves no leak") @(t : T?) { - unsafe { - var js = job_status_create() - t |> success(js != null) - js |> job_status_remove - t |> success(js == null) - } + var js = job_status_create() + t |> success(js != null) + unsafe(js |> job_status_remove) + t |> success(js == null) } t |> run("with_channel scoped cleanup") @(t : T?) { with_channel() $(ch) { @@ -51,22 +47,18 @@ def test_tracking_clean_run(t : T?) { [test] def test_tracking_atomics_standalone(t : T?) { t |> run("atomic32 create+remove works without JobStatus") @(t : T?) { - unsafe { - var a = atomic32_create() - a |> set(42) - t |> equal(42, a |> get) - a |> atomic32_remove - t |> success(a == null) - } + var a = atomic32_create() + a |> set(42) + t |> equal(42, a |> get) + unsafe(a |> atomic32_remove) + t |> success(a == null) } t |> run("atomic64 create+remove works without JobStatus") @(t : T?) { - unsafe { - var a = atomic64_create() - a |> set(123l) - t |> equal(123l, a |> get) - a |> atomic64_remove - t |> success(a == null) - } + var a = atomic64_create() + a |> set(123l) + t |> equal(123l, a |> get) + unsafe(a |> atomic64_remove) + t |> success(a == null) } t |> run("with_atomic32 scoped") @(t : T?) { with_atomic32() $(a) { diff --git a/tests/json/test_sscan_json.das b/tests/json/test_sscan_json.das index a050a4a24b..37d8aa2002 100644 --- a/tests/json/test_sscan_json.das +++ b/tests/json/test_sscan_json.das @@ -145,9 +145,7 @@ def test_struct_pointer(t : T?) { let ok = sscan_json("\{\"inner\":\{\"x\":7,\"y\":1.0\},\"tag\":\"ptr\"\}", v) t |> success(ok) t |> success(v.inner != null, "ptr not null") - unsafe { - t |> equal(v.inner.x, 7) - } + t |> equal(v.inner.x, 7) t |> equal(v.tag, "ptr") } t |> run("null pointer") @(t : T?) { @@ -180,10 +178,8 @@ def test_arrays(t : T?) { t |> success(v.ptrs[0] != null, "ptrs[0] not null") t |> success(v.ptrs[1] == null, "ptrs[1] null") t |> success(v.ptrs[2] != null, "ptrs[2] not null") - unsafe { - t |> equal(v.ptrs[0].x, 10) - t |> equal(v.ptrs[2].x, 30) - } + t |> equal(v.ptrs[0].x, 10) + t |> equal(v.ptrs[2].x, 30) } t |> run("empty arrays") @(t : T?) { var v : WithArrays @@ -282,10 +278,8 @@ def test_deep_nesting(t : T?) { t |> success(ok) t |> equal(v.name, "deep") t |> success(v.l2 != null, "l2 not null") - unsafe { - t |> success(v.l2.l3 != null, "l3 not null") - t |> equal(v.l2.l3.value, 777) - } + t |> success(v.l2.l3 != null, "l3 not null") + t |> equal(v.l2.l3.value, 777) } } @@ -300,12 +294,10 @@ def test_array_of_struct_ptrs(t : T?) { let ok = sscan_json("\{\"messages\":[\{\"id\":1,\"text\":\"hi\",\"from\":\"alice\"\},\{\"id\":2,\"text\":\"bye\",\"from\":\"bob\"\}]\}", v) t |> success(ok) t |> equal(length(v.messages), 2) - unsafe { - t |> equal(v.messages[0].id, 1l) - t |> equal(v.messages[0].text, "hi") - t |> equal(v.messages[0]._from, "alice") - t |> equal(v.messages[1].id, 2l) - } + t |> equal(v.messages[0].id, 1l) + t |> equal(v.messages[0].text, "hi") + t |> equal(v.messages[0]._from, "alice") + t |> equal(v.messages[1].id, 2l) } } @@ -363,9 +355,7 @@ def test_round_trip(t : T?) { t |> equal(dst.name, "test") t |> equal(dst.flag, true) t |> success(dst.inner != null, "rt inner") - unsafe { - t |> equal(dst.inner.x, 7) - } + t |> equal(dst.inner.x, 7) t |> equal(length(dst.items), 3) t |> equal(dst.items[1], 20) } diff --git a/tests/jsonrpc/test_request_ownership.das b/tests/jsonrpc/test_request_ownership.das index 7fd8cc448c..097417c099 100644 --- a/tests/jsonrpc/test_request_ownership.das +++ b/tests/jsonrpc/test_request_ownership.das @@ -58,9 +58,7 @@ def test_response_parsers_own_their_document(t : T?) { for (_ in range(8)) { var rb <- parse_response_batch("[\{\"id\":1,\"result\":1},\{\"id\":2,\"result\":[1,2]}]") t |> equal(length(rb.responses), 2) - unsafe { - delete rb.responses - } + delete rb.responses } t |> equal(heap_bytes_allocated(), before, "no parse tree survives parse_response_batch") } diff --git a/tests/language/addr_cast_sugar.das b/tests/language/addr_cast_sugar.das index 0455557e32..d004a9d94c 100644 --- a/tests/language/addr_cast_sugar.das +++ b/tests/language/addr_cast_sugar.das @@ -18,9 +18,7 @@ def test_addr_cast_single_unsafe(t : T?) { var buf : array buf |> resize(4) var p = unsafe(addr(buf[0])) - unsafe { - *(p + 2) = uint8(0xAB) - } + *(unsafe(p + 2)) = uint8(0xAB) t |> equal(uint(buf[2]), 0xABu) } @@ -29,9 +27,7 @@ def test_addr_cast_exact_type(t : T?) { // exact-type addr folds to plain addr(x); unsafe still required (see cant_addr_cast_unsafe) var i = 42 var pi = unsafe(addr(i)) - unsafe { - *pi = 43 - } + *pi = 43 t |> equal(i, 43) } diff --git a/tests/language/annotation_info.das b/tests/language/annotation_info.das index fa1cd37bef..bbae4df323 100644 --- a/tests/language/annotation_info.das +++ b/tests/language/annotation_info.das @@ -153,17 +153,15 @@ def test_deprecated_structure_for_each_annotation(t : T?) { let s = AnnotatedStruct() let sinfo = (typeinfo rtti_typeinfo(s)).structType var seen = 0 - unsafe { - structure_for_each_annotation(*sinfo) $(ann; args) { - t |> equal("{ann.name}", "comment") - t |> equal(length(args), 5) - for (arg in args) { - if (arg.name == "v_int") { - t |> equal(arg.iValue, 13) - } + structure_for_each_annotation(*sinfo) $(ann; args) { + t |> equal("{ann.name}", "comment") + t |> equal(length(args), 5) + for (arg in args) { + if (arg.name == "v_int") { + t |> equal(arg.iValue, 13) } - seen ++ } + seen ++ } t |> equal(seen, 1) } diff --git a/tests/language/cast.das b/tests/language/cast.das index f542abc171..5f7986b286 100644 --- a/tests/language/cast.das +++ b/tests/language/cast.das @@ -90,11 +90,9 @@ def test_cast(t : T?) { } t |> run("reinterpret struct") @(t : T?) { let f2i = Int2Float(iv = 0x3f400000, fv = 1.0) - unsafe { - let i2f = reinterpret(f2i) - t |> equal(i2f.fv, 0.75) - t |> equal(i2f.iv, 0x3f800000) - } + let i2f = unsafe(reinterpret(f2i)) + t |> equal(i2f.fv, 0.75) + t |> equal(i2f.iv, 0x3f800000) } } diff --git a/tests/language/const_strip_write_through_passthrough.das b/tests/language/const_strip_write_through_passthrough.das index 3f8e043e0d..fcaec7b4b0 100644 --- a/tests/language/const_strip_write_through_passthrough.das +++ b/tests/language/const_strip_write_through_passthrough.das @@ -33,9 +33,7 @@ def passthrough2(p : float const?; n : int) { // control: mutable `var float?` params throughout, no reinterpret — always worked def leaf_mut(var p : float?; n : int) { - unsafe { - for (i in range(n)) { p[i] = 7.0 } - } + for (i in range(n)) { unsafe(p[i]) = 7.0 } } def passthrough_mut(var p : float?; n : int) { leaf_mut(p, n) @@ -58,9 +56,7 @@ def passthrough_alias2(p : float const?; n : int) { def writer_via_copy(var p : float?; n : int) { var w = p - unsafe { - for (i in range(n)) { w[i] = 7.0 } - } + for (i in range(n)) { unsafe(w[i]) = 7.0 } } def fill_zero(var a : float[4]) { @@ -73,14 +69,14 @@ def test_const_strip_write_through_passthrough(t : T?) { t |> run("direct leaf write") @(t : T?) { var a : float[4] fill_zero(a) - unsafe { leaf(addr(a[0]), 4) } + leaf(unsafe(addr(a[0])), 4) t |> equal(a[0], 7.0) } // (2) forwarded through a `float const?` pass-through — the bug (b stayed 0.0) t |> run("write forwarded through const? pass-through") @(t : T?) { var b : float[4] fill_zero(b) - unsafe { passthrough(addr(b[0]), 4) } + passthrough(unsafe(addr(b[0])), 4) t |> equal(b[0], 7.0) } // (3) forwarded through TWO chained `float const?` pass-throughs — transitive @@ -88,35 +84,35 @@ def test_const_strip_write_through_passthrough(t : T?) { t |> run("write forwarded through two const? hops") @(t : T?) { var c : float[4] fill_zero(c) - unsafe { passthrough2(addr(c[0]), 4) } + passthrough2(unsafe(addr(c[0])), 4) t |> equal(c[0], 7.0) } // (4) control: mutable-param pass-through — never lost the write t |> run("mutable-param pass-through control") @(t : T?) { var d : float[4] fill_zero(d) - unsafe { passthrough_mut(addr(d[0]), 4) } + passthrough_mut(unsafe(addr(d[0])), 4) t |> equal(d[0], 7.0) } // (5) write forwarded through a `let q = p` pointer-alias local t |> run("write through let-alias of const? param") @(t : T?) { var e : float[4] fill_zero(e) - unsafe { passthrough_alias(addr(e[0]), 4) } + passthrough_alias(unsafe(addr(e[0])), 4) t |> equal(e[0], 7.0) } // (6) two chained alias lets — chase must be transitive t |> run("write through chained let-aliases") @(t : T?) { var g : float[4] fill_zero(g) - unsafe { passthrough_alias2(addr(g[0]), 4) } + passthrough_alias2(unsafe(addr(g[0])), 4) t |> equal(g[0], 7.0) } // (7) direct write through `var w = p` copy of a mutable param — no reinterpret at all t |> run("write through var-copy of mutable param") @(t : T?) { var h : float[4] fill_zero(h) - unsafe { writer_via_copy(addr(h[0]), 4) } + writer_via_copy(unsafe(addr(h[0])), 4) t |> equal(h[0], 7.0) } } diff --git a/tests/language/container_finalize.das b/tests/language/container_finalize.das index bce85ea97a..17ac885dfc 100644 --- a/tests/language/container_finalize.das +++ b/tests/language/container_finalize.das @@ -147,9 +147,7 @@ def test_user_finalizers_never_run_implicitly(t : T?) { let after = heap_bytes_allocated() t |> equal(g_finalized, 0) t |> equal(int(before), int(after)) - unsafe { - delete arr - } + delete arr } t |> run("delete remains the full teardown") @(t : T?) { var inscope one <- make_probes(1) @@ -167,9 +165,7 @@ def test_user_finalizers_never_run_implicitly(t : T?) { tab |> erase("a") tab |> clear() t |> equal(g_finalized, 0) - unsafe { - delete tab - } + delete tab } } diff --git a/tests/language/container_init_off.das b/tests/language/container_init_off.das index 7e7d7242bb..8e2e1a74bb 100644 --- a/tests/language/container_init_off.das +++ b/tests/language/container_init_off.das @@ -33,9 +33,7 @@ def test_policy_off_no_finalize_banner(t : T?) { let after = heap_bytes_allocated() t |> equal(int(before), int(after)) arr |> clear() - unsafe { - delete arr - } + delete arr } t |> run("clear drops every slot without releasing") @(t : T?) { var arr <- make_bags(2) @@ -43,9 +41,7 @@ def test_policy_off_no_finalize_banner(t : T?) { arr |> clear() let after = heap_bytes_allocated() t |> equal(int(before), int(after)) - unsafe { - delete arr - } + delete arr } t |> run("table erase and clear drop values without releasing") @(t : T?) { var tab : table @@ -57,9 +53,7 @@ def test_policy_off_no_finalize_banner(t : T?) { tab |> clear() let after = heap_bytes_allocated() t |> equal(int(before), int(after)) - unsafe { - delete tab - } + delete tab } t |> run("the composite trait follows its policy") @(t : T?) { // the collect banner rides force_inscope_pod (default off) - not container init diff --git a/tests/language/each_ref.das b/tests/language/each_ref.das index 7ff760d68d..923a40ff30 100644 --- a/tests/language/each_ref.das +++ b/tests/language/each_ref.das @@ -12,9 +12,7 @@ def make_lam() : lambda<(var a : int?&) : bool> { if (idx >= length(g_src)) { return false } - unsafe { - a = addr(g_src[idx]) - } + a = unsafe(addr(g_src[idx])) idx++ return true } diff --git a/tests/language/lock_array.das b/tests/language/lock_array.das index 71982de7e2..ad7cbd3fdb 100644 --- a/tests/language/lock_array.das +++ b/tests/language/lock_array.das @@ -13,17 +13,13 @@ def test_lock_array(t : T?) { } lock_data(arr) $(data, _size) { for (j in range(10)) { - unsafe { - t |> equal(data[j], j) - } + t |> equal(unsafe(data[j]), j) } } var arr2 <- [for (x in range(10)); x] lock_data(arr2) $(data, _size) { for (j in range(10)) { - unsafe { - data[j] = j * 2 - } + unsafe(data[j]) = j * 2 } } for (j in range(10)) { diff --git a/tests/language/new_delete.das b/tests/language/new_delete.das index 34a9e0e63d..8573d1e4ea 100644 --- a/tests/language/new_delete.das +++ b/tests/language/new_delete.das @@ -112,9 +112,7 @@ def test_delete_string(t : T?) { let w0 = heap_bytes_allocated() var a = "{deref(getPtr())}" // assert(a=="0") - unsafe { - delete_string(a) - } + unsafe(delete_string(a)) let w1 = heap_bytes_allocated() t |> equal(w0, w1) t |> equal(a, "") @@ -125,9 +123,7 @@ def test_delete_string_array(t : T?) { let w0 = heap_bytes_allocated() var a = fixed_array("{deref(getPtr())}_1", "{deref(getPtr())}_2", "{deref(getPtr())}_3") for (AA in a) { - unsafe { - delete_string(AA) - } + unsafe(delete_string(AA)) } let w1 = heap_bytes_allocated() t |> equal(w0, w1) diff --git a/tests/language/offset_pointer_write_through_helper.das b/tests/language/offset_pointer_write_through_helper.das index f72c507419..5ddb88c018 100644 --- a/tests/language/offset_pointer_write_through_helper.das +++ b/tests/language/offset_pointer_write_through_helper.das @@ -27,7 +27,7 @@ def pk_direct(var d : float?; s : float const?) { // control: helper called with the pointer UNOFFSET — plain ExprVar arg, always propagated def pk_unoffset(var d : float?; s : float const?) { - unsafe { cpy2(d, s, 4l) } + cpy2(d, s, 4l) } def fill(var a : float[4]; base : float) { diff --git a/tests/language/optimization_auto_inline_functions.das b/tests/language/optimization_auto_inline_functions.das index 5c3dbfaca6..a0ead23f39 100644 --- a/tests/language/optimization_auto_inline_functions.das +++ b/tests/language/optimization_auto_inline_functions.das @@ -466,9 +466,7 @@ def target_upcast_param(var k : WrKid) { [export] def target_reinterpret_param(var w : WrTwin) { - unsafe { - poke_n(reinterpret(w)) - } + poke_n(unsafe(reinterpret(w))) } [export] diff --git a/tests/language/optimization_inline_unsafe.das b/tests/language/optimization_inline_unsafe.das index f5511275ba..98ae56b35a 100644 --- a/tests/language/optimization_inline_unsafe.das +++ b/tests/language/optimization_inline_unsafe.das @@ -21,11 +21,9 @@ require _inline_unsafe_helper def local_unsafe_sum(src : array; blk : block<(v : int) : int>) : int { // same-module callee: its own `unsafe { }` wrapper is still present at patch time var total = 0 - unsafe { - var p = addr(total) - for (v in src) { - *p += invoke(blk, v) - } + var p = unsafe(addr(total)) + for (v in src) { + *p += invoke(blk, v) } return total } diff --git a/tests/language/pointers.das b/tests/language/pointers.das index 6063fe3801..bda8561c58 100644 --- a/tests/language/pointers.das +++ b/tests/language/pointers.das @@ -30,21 +30,17 @@ def test_new_and_fields(t : T?) { } } t |> run("auto-deref field access") @(t : T?) { - unsafe { - var inscope p = new TestStruct(x = 42, y = 99) - // p.x auto-dereferences the pointer — no -> needed - t |> equal(p.x, 42) - t |> equal(p.y, 99) - } + var inscope p = new TestStruct(x = 42, y = 99) + // p.x auto-dereferences the pointer — no -> needed + t |> equal(p.x, 42) + t |> equal(p.y, 99) } t |> run("modify through pointer") @(t : T?) { - unsafe { - var inscope p = new TestStruct(x = 1, y = 2) - p.x = 100 - p.y = 200 - t |> equal(p.x, 100) - t |> equal(p.y, 200) - } + var inscope p = new TestStruct(x = 1, y = 2) + p.x = 100 + p.y = 200 + t |> equal(p.x, 100) + t |> equal(p.y, 200) } } @@ -52,27 +48,21 @@ def test_new_and_fields(t : T?) { def test_addr_and_deref(t : T?) { t |> run("addr and deref") @(t : T?) { var x = 42 - unsafe { - var p = addr(x) - t |> equal(*p, 42) - t |> equal(deref(p), 42) - } + var p = unsafe(addr(x)) + t |> equal(*p, 42) + t |> equal(deref(p), 42) } t |> run("modify through addr") @(t : T?) { var x = 10 - unsafe { - var p = addr(x) - *p = 99 - } + var p = unsafe(addr(x)) + *p = 99 t |> equal(x, 99) } t |> run("addr of struct field") @(t : T?) { var s = TestStruct(x = 7, y = 8) - unsafe { - var px = addr(s.x) - t |> equal(*px, 7) - *px = 77 - } + var px = unsafe(addr(s.x)) + t |> equal(*px, 7) + *px = 77 t |> equal(s.x, 77) } } @@ -115,11 +105,9 @@ def test_null_pointer(t : T?) { [test] def test_safe_navigation(t : T?) { t |> run("?. on valid pointer") @(t : T?) { - unsafe { - var inscope p = new TestStruct(x = 42, y = 99) - t |> equal(p?.x ?? -1, 42) - t |> equal(p?.y ?? -1, 99) - } + var inscope p = new TestStruct(x = 42, y = 99) + t |> equal(p?.x ?? -1, 42) + t |> equal(p?.y ?? -1, 99) } t |> run("?. on null pointer") @(t : T?) { var p : TestStruct? @@ -190,18 +178,14 @@ def test_pointer_arithmetic(t : T?) { def test_intptr(t : T?) { t |> run("intptr non-zero") @(t : T?) { var x = 42 - unsafe { - var p = addr(x) - let address = intptr(p) - t |> equal(address != uint64(0), true) - } + var p = unsafe(addr(x)) + let address = intptr(p) + t |> equal(address != uint64(0), true) } t |> run("intptr same pointer same value") @(t : T?) { var x = 42 - unsafe { - var p = addr(x) - t |> equal(intptr(p), intptr(p)) - } + var p = unsafe(addr(x)) + t |> equal(intptr(p), intptr(p)) } t |> run("intptr different pointers differ") @(t : T?) { var x = 1 @@ -225,9 +209,7 @@ def test_intptr(t : T?) { let lam <- @(a : int) : int { return a + 1 } let other_lam <- @(a : int) : int { return a + 2 } t |> equal(intptr(lam) != 0ul, true, "a lambda handle is not null") - unsafe { - t |> equal(intptr(lam), intptr(reinterpret(lam)), "the handle is the capture pointer") - } + t |> equal(intptr(lam), intptr(unsafe(reinterpret(lam))), "the handle is the capture pointer") t |> equal(intptr(lam) != intptr(other_lam), true, "two lambdas do not share a handle") } } @@ -279,9 +261,7 @@ def test_delete(t : T?) { t |> run("var inscope auto-deletes") @(t : T?) { // var inscope p = new ... — p is deleted at scope exit // We just verify it works without crash - unsafe { - var inscope p = new TestStruct(x = 5, y = 6) - t |> equal(p.x, 5) - } + var inscope p = new TestStruct(x = 5, y = 6) + t |> equal(p.x, 5) } } diff --git a/tests/language/properties.das b/tests/language/properties.das index 53b26e13f1..6231523e21 100644 --- a/tests/language/properties.das +++ b/tests/language/properties.das @@ -25,24 +25,18 @@ class sealed UIFrame { [test] def test_property_clone_assign(t : T?) { t |> run("clone-assign string via block") @(t : T?) { - var res : string - unsafe { - res := reinterpret("foo") - } + var res = "" + res := unsafe(reinterpret("foo")) t |> equal(res, "foo") } t |> run("clone-assign to struct field directly") @(t : T?) { var f : Foo - unsafe { - f.resz := reinterpret("bar") - } + f.resz := unsafe(reinterpret("bar")) t |> equal(f.resz, "bar") } t |> run("clone-assign via property operator") @(t : T?) { var f : Foo - unsafe { - f.res := reinterpret("baz") - } + f.res := unsafe(reinterpret("baz")) t |> equal(f.resz, "baz") } } diff --git a/tests/language/safe_ptr_at.das b/tests/language/safe_ptr_at.das index eb546d838c..c0503f80f9 100644 --- a/tests/language/safe_ptr_at.das +++ b/tests/language/safe_ptr_at.das @@ -12,9 +12,7 @@ def test_ptr_safe_at_int(t : T?) { var ar = fixed_array(10, 20, 30) var p : int? = unsafe(addr(ar[0])) var dummy = 0 - unsafe { - p?[0] ?? dummy = 1 - } + unsafe(p?[0]) ?? dummy = 1 t |> equal(ar[0], 1) t |> equal(dummy, 0) } @@ -22,43 +20,31 @@ def test_ptr_safe_at_int(t : T?) { var ar = fixed_array(10, 20, 30) var p : int? = unsafe(addr(ar[0])) var dummy = 0 - unsafe { - p?[2] ?? dummy = 42 - } + unsafe(p?[2]) ?? dummy = 42 t |> equal(ar[2], 42) t |> equal(dummy, 0) } t |> run("int pointer safe at - null") @(t : T?) { var p : int? var dummy = 0 - unsafe { - p?[0] ?? dummy = 99 - } + unsafe(p?[0]) ?? dummy = 99 t |> equal(dummy, 99) } t |> run("int pointer safe at - null with offset") @(t : T?) { var p : int? var dummy = 0 - unsafe { - p?[5] ?? dummy = 77 - } + unsafe(p?[5]) ?? dummy = 77 t |> equal(dummy, 77) } t |> run("int pointer safe at - read value") @(t : T?) { var ar = fixed_array(10, 20, 30) var p : int? = unsafe(addr(ar[0])) - var val : int - unsafe { - val = p?[1] ?? 0 - } + let val = unsafe(p?[1]) ?? 0 t |> equal(val, 20) } t |> run("int pointer safe at - read null") @(t : T?) { var p : int? - var val : int - unsafe { - val = p?[0] ?? 42 - } + let val = unsafe(p?[0]) ?? 42 t |> equal(val, 42) } } @@ -68,18 +54,12 @@ def test_ptr_safe_at_uint_index(t : T?) { t |> run("pointer safe at uint index - non null") @(t : T?) { var ar = fixed_array(10, 20, 30) var p : int? = unsafe(addr(ar[0])) - var val : int - unsafe { - val = p?[1u] ?? 0 - } + let val = unsafe(p?[1u]) ?? 0 t |> equal(val, 20) } t |> run("pointer safe at uint index - null") @(t : T?) { var p : int? - var val : int - unsafe { - val = p?[0u] ?? 42 - } + let val = unsafe(p?[0u]) ?? 42 t |> equal(val, 42) } } @@ -89,18 +69,12 @@ def test_ptr_safe_at_int64_index(t : T?) { t |> run("pointer safe at int64 index - non null") @(t : T?) { var ar = fixed_array(10, 20, 30) var p : int? = unsafe(addr(ar[0])) - var val : int - unsafe { - val = p?[2l] ?? 0 - } + let val = unsafe(p?[2l]) ?? 0 t |> equal(val, 30) } t |> run("pointer safe at int64 index - null") @(t : T?) { var p : int? - var val : int - unsafe { - val = p?[0l] ?? 42 - } + let val = unsafe(p?[0l]) ?? 42 t |> equal(val, 42) } } @@ -110,18 +84,12 @@ def test_ptr_safe_at_uint64_index(t : T?) { t |> run("pointer safe at uint64 index - non null") @(t : T?) { var ar = fixed_array(10, 20, 30) var p : int? = unsafe(addr(ar[0])) - var val : int - unsafe { - val = p?[1ul] ?? 0 - } + let val = unsafe(p?[1ul]) ?? 0 t |> equal(val, 20) } t |> run("pointer safe at uint64 index - null") @(t : T?) { var p : int? - var val : int - unsafe { - val = p?[0ul] ?? 42 - } + let val = unsafe(p?[0ul]) ?? 42 t |> equal(val, 42) } } @@ -132,20 +100,16 @@ def test_ptr_safe_at_struct(t : T?) { var ar = fixed_array(Foo(a = 1, b = 2), Foo(a = 3, b = 4)) var p : Foo? = unsafe(addr(ar[0])) let dummy = Foo() - unsafe { - let val = p?[1] ?? dummy - t |> equal(val.a, 3) - t |> equal(val.b, 4) - } + let val = unsafe(p?[1]) ?? dummy + t |> equal(val.a, 3) + t |> equal(val.b, 4) } t |> run("struct pointer safe at - null") @(t : T?) { var p : Foo? let dummy = Foo(a = 99, b = 88) - unsafe { - let val = p?[0] ?? dummy - t |> equal(val.a, 99) - t |> equal(val.b, 88) - } + let val = unsafe(p?[0]) ?? dummy + t |> equal(val.a, 99) + t |> equal(val.b, 88) } } @@ -157,18 +121,14 @@ def test_ptr_safe_at_ptr_to_ptr(t : T?) { var ptrs = fixed_array(unsafe(addr(a)), unsafe(addr(b))) var pp : int ?? = unsafe(addr(ptrs[0])) var dummy : int? - unsafe { - let val = pp?[1] ?? dummy - t |> success(val != null) - t |> equal(deref(val), 20) - } + let val = unsafe(pp?[1]) ?? dummy + t |> success(val != null) + t |> equal(deref(val), 20) } t |> run("pointer to pointer safe at - null") @(t : T?) { var pp : int ?? var dummy : int? - unsafe { - let val = pp?[0] ?? dummy - t |> success(val == null) - } + let val = unsafe(pp?[0]) ?? dummy + t |> success(val == null) } } diff --git a/tests/language/serialization.das b/tests/language/serialization.das index 57d9db0bd7..db3fceee54 100644 --- a/tests/language/serialization.das +++ b/tests/language/serialization.das @@ -177,23 +177,21 @@ def test_custom_serialize(t : T?) { t |> equal(loaded.b, 1.0) } t |> run("Color array uses custom serialize") @(t : T?) { - unsafe { - var colors <- [Color(r = 1.0, g = 0.0, b = 0.0), Color(r = 0.0, g = 1.0, b = 0.0)] - var writer = new MemSerializer() - var warch = Archive(reading = false, stream = writer) - warch |> serialize(colors) - var data <- writer->extractData() - // 4 bytes array length + 2 × 3 bytes = 10 - t |> equal(length(data), 10) - var reader = new MemSerializer(data) - var rarch = Archive(reading = true, stream = reader) - var loaded : array - rarch |> serialize(loaded) - t |> equal(length(loaded), 2) - t |> equal(loaded[0].r, 1.0) - t |> equal(loaded[0].g, 0.0) - t |> equal(loaded[1].g, 1.0) - t |> equal(loaded[1].b, 0.0) - } + var colors <- [Color(r = 1.0, g = 0.0, b = 0.0), Color(r = 0.0, g = 1.0, b = 0.0)] + var writer = new MemSerializer() + var warch = Archive(reading = false, stream = writer) + warch |> serialize(colors) + var data <- writer->extractData() + // 4 bytes array length + 2 × 3 bytes = 10 + t |> equal(length(data), 10) + var reader = new MemSerializer(data) + var rarch = Archive(reading = true, stream = reader) + var loaded : array + rarch |> serialize(loaded) + t |> equal(length(loaded), 2) + t |> equal(loaded[0].r, 1.0) + t |> equal(loaded[0].g, 0.0) + t |> equal(loaded[1].g, 1.0) + t |> equal(loaded[1].b, 0.0) } } diff --git a/tests/language/smart_ptr.das b/tests/language/smart_ptr.das index ac3492fb1d..4b3870978a 100644 --- a/tests/language/smart_ptr.das +++ b/tests/language/smart_ptr.das @@ -64,21 +64,15 @@ def ref_count_test(t : T?) { t |> equal(fptr, sptr) t |> equal(smart_ptr_use_count(sptr), 3u) t |> equal(getTotalTestObjectSmart(), 1) - unsafe { - delete sptr // ref_count = 2 - } + delete sptr // ref_count = 2 t |> equal(getTotalTestObjectSmart(), 1) t |> equal(smart_ptr_use_count(sptr), 0u) t |> equal(smart_ptr_use_count(qptr), 2u) - unsafe { - delete qptr // ref_count = 1 - } + delete qptr // ref_count = 1 t |> equal(getTotalTestObjectSmart(), 1) t |> equal(smart_ptr_use_count(qptr), 0u) t |> equal(smart_ptr_use_count(fptr), 1u) - unsafe { - delete fptr // physical delete - } + delete fptr // physical delete t |> equal(getTotalTestObjectSmart(), 0) t |> equal(smart_ptr_use_count(fptr), 0u) } @@ -91,9 +85,7 @@ def access_test(t : T?) { t |> equal(val, 1234) ptr ?. fooData ?? val = 13 // ?? lvalue t |> equal(ptr.fooData, 13) - unsafe { - delete ptr - } + delete ptr val = ptr ?. fooData ?? 2 t |> equal(val, 2) unsafe { @@ -102,10 +94,8 @@ def access_test(t : T?) { } t |> equal(ptr.first.fooData, 1234) t |> equal(ptr ?. first ?. fooData ?? 13, 1234) - unsafe { - delete ptr.first - delete ptr - } + delete ptr.first + delete ptr t |> equal(getTotalTestObjectSmart(), 0) } @@ -114,9 +104,7 @@ def fn_test(t : T?) { var inscope ptr <- makeTestObjectSmart() t |> equal(countTestObjectSmart(ptr), 1u) t |> equal(getTotalTestObjectSmart(), 1) - unsafe { - delete ptr - } + delete ptr t |> equal(getTotalTestObjectSmart(), 0) } diff --git a/tests/language/string_ops.das b/tests/language/string_ops.das index 6c6524d951..f442b30a85 100644 --- a/tests/language/string_ops.das +++ b/tests/language/string_ops.das @@ -156,9 +156,7 @@ multi line string" write(writer, zzx) } } - unsafe { - delete_string(zzs) - } + unsafe(delete_string(zzs)) t |> success(true) } } diff --git a/tests/language/test_rtti_init_mnh.das b/tests/language/test_rtti_init_mnh.das index fc8eb911d2..c385aafff4 100644 --- a/tests/language/test_rtti_init_mnh.das +++ b/tests/language/test_rtti_init_mnh.das @@ -24,7 +24,5 @@ def test_named_module_structure_init_mnh(t : T?) { t |> success(initializerHash != 0ul) let typeInfo = typeinfo rtti_typeinfo(type) - unsafe { - t |> equal(typeInfo.structType.init_mnh, initializerHash) - } + t |> equal(typeInfo.structType.init_mnh, initializerHash) } diff --git a/tests/language/to_array.das b/tests/language/to_array.das index 8c1abe44b4..e1c5d7b59c 100644 --- a/tests/language/to_array.das +++ b/tests/language/to_array.das @@ -21,31 +21,23 @@ def test_to_array(t : T?) { } t |> run("from static array") @(t : T?) { let d = fixed_array(1, 2, 3, 4) - unsafe { - for (x, y in d, each(d)) { - t |> equal(x, y) - } + for (x, y in d, each(d)) { + t |> equal(x, y) } for (x, y in d, to_array(d)) { t |> equal(x, y) } - unsafe { - for (x, y in d, to_array(each(d))) { - t |> equal(x, y) - } + for (x, y in d, to_array(unsafe(each(d)))) { + t |> equal(x, y) } } t |> run("from dynamic array") @(t : T?) { let a <- to_array(fixed_array(1, 2, 3, 4)) - unsafe { - for (x, y in a, each(a)) { - t |> equal(x, y) - } - } - unsafe { - for (x, y in a, to_array(each(a))) { - t |> equal(x, y) - } + for (x, y in a, each(a)) { + t |> equal(x, y) + } + for (x, y in a, to_array(unsafe(each(a)))) { + t |> equal(x, y) } } } diff --git a/tests/language/tuple.das b/tests/language/tuple.das index ad3380706d..1d0db41f43 100644 --- a/tests/language/tuple.das +++ b/tests/language/tuple.das @@ -58,15 +58,13 @@ def test_tuple(t : T?) { // nolint:STYLE038 - flat list of independent test arm tp._0 = 1 tp._1 = 2.0 tp._2 = "3" - unsafe { - var pq = addr(tp) - t |> equal(pq._0, 1) - t |> equal(pq._1, 2.0) - t |> equal(pq._2, "3") - t |> equal(pq?._0 ?? 0, 1) - t |> equal(pq?._1 ?? 0.0, 2.0) - t |> equal(pq?._2 ?? "nothing", "3") - } + var pq = unsafe(addr(tp)) + t |> equal(pq._0, 1) + t |> equal(pq._1, 2.0) + t |> equal(pq._2, "3") + t |> equal(pq?._0 ?? 0, 1) + t |> equal(pq?._1 ?? 0.0, 2.0) + t |> equal(pq?._2 ?? "nothing", "3") } t |> run("heap allocated tuple") @(t : T?) { var qq = new > diff --git a/tests/language/variant.das b/tests/language/variant.das index d2b3b10d6a..5dfa12ed30 100644 --- a/tests/language/variant.das +++ b/tests/language/variant.das @@ -66,24 +66,18 @@ def test_variant(t : T?) { // nolint:STYLE038 - flat list of independent test a t |> success(u is i_value) t |> equal(u as i_value, 0x3f800000) - unsafe { - set_variant_index(u, typeinfo variant_index(u)) // unsafe operation - } + unsafe(set_variant_index(u, typeinfo variant_index(u))) // unsafe operation t |> equal(u as f_value, 1.0) t |> equal(u ?as f_value ?? 2.0, 1.0) t |> equal(u ?as i_value ?? 1u, 1u) u as f_value = 2.0 - unsafe { - set_variant_index(u, typeinfo variant_index(u)) // unsafe operation - } + unsafe(set_variant_index(u, typeinfo variant_index(u))) // unsafe operation t |> equal(u as i_value, 0x40000000) u as i_value = 0x3f800000 - unsafe { - set_variant_index(u, typeinfo variant_index(u)) // unsafe operation - } + unsafe(set_variant_index(u, typeinfo variant_index(u))) // unsafe operation t |> equal(u as f_value, 1.0) var paniced = false @@ -105,9 +99,7 @@ def test_variant(t : T?) { // nolint:STYLE038 - flat list of independent test a t |> success(paniced_r2v) t |> equal((u as f_value) + 1.0, 2.0) - unsafe { - t |> equal(u.f_value, 1.0) - } + t |> equal(unsafe(u.f_value), 1.0) u = U_F(i_value = 0x40000000) t |> equal(u as i_value, 0x40000000) u = U_F(f_value = 1.0) diff --git a/tests/linq/test_linq_fold.das b/tests/linq/test_linq_fold.das index 8262ffc5c9..daaf732420 100644 --- a/tests/linq/test_linq_fold.das +++ b/tests/linq/test_linq_fold.das @@ -2786,24 +2786,22 @@ def test_join_multistatement_result_group_by(t : T?) { t |> run("join with multi-statement result lambda + group_by keeps its rows") @(tt : T?) { let cars = [(id = 1, dealer = 1), (id = 2, dealer = 2), (id = 3, dealer = 1)] let dealers = [(id = 1, region = "north"), (id = 2, region = "south")] - unsafe { - let rows <- _fold(each(cars) - |> _join(dealers, - $(l, r) => l.dealer == r.id, - $(l, r) { - let regionTag = r.region - return (Region = regionTag, CarId = l.id) - }) - |> _group_by(_.Region) - |> _select((R = _._0, N = _._1 |> count())) - |> to_array()) - tt |> equal(length(rows), 2) - var totalMembers = 0 - for (row in rows) { - totalMembers += row.N - } - tt |> equal(totalMembers, 3) + let rows <- _fold(each(cars) + |> _join(dealers, + $(l, r) => l.dealer == r.id, + $(l, r) { + let regionTag = r.region + return (Region = regionTag, CarId = l.id) + }) + |> _group_by(_.Region) + |> _select((R = _._0, N = _._1 |> count())) + |> to_array()) + tt |> equal(length(rows), 2) + var totalMembers = 0 + for (row in rows) { + totalMembers += row.N } + tt |> equal(totalMembers, 3) } } @@ -2818,20 +2816,18 @@ def impure_double_for_fold(x : int) : int { def test_chained_impure_selects_then_where(t : T?) { t |> run("chained impure selects + where compile and match plain semantics") @(tt : T?) { g_impure_counter = 0 - unsafe { - let vals <- _fold(each([1, 2, 3])._select(impure_double_for_fold(_))._select(_ + 1)._where(_ > 3).to_array()) - tt |> equal(length(vals), 2) - tt |> equal(vals[0], 5) - tt |> equal(vals[1], 7) - tt |> equal(g_impure_counter, 3) - let n = _fold(each([1, 2, 3])._select(impure_double_for_fold(_))._select(_ + 1)._where(_ > 3).count()) - tt |> equal(n, 2) - tt |> equal(g_impure_counter, 6) - let taken <- _fold(each([1, 2, 3, 4])._select(impure_double_for_fold(_))._select(_ + 1).take(3)._where(_ > 3).to_array()) - tt |> equal(length(taken), 2) - tt |> equal(taken[0], 5) - tt |> equal(taken[1], 7) - } + let vals <- _fold(each([1, 2, 3])._select(impure_double_for_fold(_))._select(_ + 1)._where(_ > 3).to_array()) + tt |> equal(length(vals), 2) + tt |> equal(vals[0], 5) + tt |> equal(vals[1], 7) + tt |> equal(g_impure_counter, 3) + let n = _fold(each([1, 2, 3])._select(impure_double_for_fold(_))._select(_ + 1)._where(_ > 3).count()) + tt |> equal(n, 2) + tt |> equal(g_impure_counter, 6) + let taken <- _fold(each([1, 2, 3, 4])._select(impure_double_for_fold(_))._select(_ + 1).take(3)._where(_ > 3).to_array()) + tt |> equal(length(taken), 2) + tt |> equal(taken[0], 5) + tt |> equal(taken[1], 7) } } @@ -2839,15 +2835,13 @@ def test_chained_impure_selects_then_where(t : T?) { def test_having_inner_select_distinct_selector(t : T?) { t |> run("having inner-select uses its own selector, not the visible _select slot") @(tt : T?) { let arr = [1, 2, 3, 4, 5, 6] - unsafe { - let got <- _fold(arr._group_by_lazy(_ % 3)._having(_._1 |> select($(x : int) => x * 10) |> sum > 60)._select((K = _._0, S = _._1 |> select($(x : int) => x * 1) |> sum))) - tt |> equal(length(got), 2) - var totalS = 0 - for (g in got) { - totalS += g.S - } - tt |> equal(totalS, 16) + let got <- _fold(arr._group_by_lazy(_ % 3)._having(_._1 |> select($(x : int) => x * 10) |> sum > 60)._select((K = _._0, S = _._1 |> select($(x : int) => x * 1) |> sum))) + tt |> equal(length(got), 2) + var totalS = 0 + for (g in got) { + totalS += g.S } + tt |> equal(totalS, 16) } } @@ -2861,7 +2855,7 @@ def test_min_max_family_splice_parity(t : T?) { t |> run("min_max family folds match plain evaluation") @(tt : T?) { let xs = [5, 1, 9, 3, 7, 3] var items <- [MmItem(id = 1, w = 30), MmItem(id = 2, w = 10), MmItem(id = 3, w = 20)] - unsafe { + unsafe { // nolint:STYLE024 - _fold rewrites the chain and erases the each whose unsafeOutsideOfFor needs the wrap let mm = _fold(each(xs) |> min_max()) tt |> equal(mm._0, 1) tt |> equal(mm._1, 9) @@ -2894,17 +2888,15 @@ def test_tier2_generated_names_do_not_capture_locals(t : T?) { t |> run("locals named like the generated binds do not hijack tier-2 chains") @(tt : T?) { let fsrc = [7] let other = [5] - unsafe { - let r <- _fold(other |> union(fsrc) |> unique()) - tt |> equal(length(r), 2) - tt |> equal(r[0], 5) - tt |> equal(r[1], 7) - let fpass_0 = [9] - let r2 <- _fold(other |> union(fpass_0) |> unique()) - tt |> equal(length(r2), 2) - tt |> equal(r2[0], 5) - tt |> equal(r2[1], 9) - } + let r <- _fold(other |> union(fsrc) |> unique()) + tt |> equal(length(r), 2) + tt |> equal(r[0], 5) + tt |> equal(r[1], 7) + let fpass_0 = [9] + let r2 <- _fold(other |> union(fpass_0) |> unique()) + tt |> equal(length(r2), 2) + tt |> equal(r2[0], 5) + tt |> equal(r2[1], 9) } } @@ -2912,30 +2904,26 @@ def test_tier2_generated_names_do_not_capture_locals(t : T?) { def test_early_exit_non_copyable_elements_cascade(t : T?) { t |> run("first over array> cascades instead of failing") @(tt : T?) { var arr2d <- [[1, 2], [3]] - unsafe { - let f <- _fold(each(arr2d) |> first()) - tt |> equal(length(f), 2) - tt |> equal(f[0], 1) - let g <- _fold(each(arr2d) |> skip(1) |> first()) - tt |> equal(length(g), 1) - tt |> equal(g[0], 3) - } + let f <- _fold(each(arr2d) |> first()) + tt |> equal(length(f), 2) + tt |> equal(f[0], 1) + let g <- _fold(each(arr2d) |> skip(1) |> first()) + tt |> equal(length(g), 1) + tt |> equal(g[0], 3) delete arr2d } t |> run("other element-returning terminators cascade over array> too") @(tt : T?) { var arr2d <- [[1, 2], [3]] - unsafe { - let lst <- _fold(each(arr2d) |> last()) - tt |> equal(length(lst), 1) - tt |> equal(lst[0], 3) - let ea <- _fold(each(arr2d) |> element_at(1)) - tt |> equal(length(ea), 1) - tt |> equal(ea[0], 3) - let mb <- _fold(each(arr2d) |> _min_by(length(_))) - tt |> equal(length(mb), 1) - let sg <- _fold(each(arr2d) |> skip(1) |> single()) - tt |> equal(length(sg), 1) - } + let lst <- _fold(each(arr2d) |> last()) + tt |> equal(length(lst), 1) + tt |> equal(lst[0], 3) + let ea <- _fold(each(arr2d) |> element_at(1)) + tt |> equal(length(ea), 1) + tt |> equal(ea[0], 3) + let mb <- _fold(each(arr2d) |> _min_by(length(_))) + tt |> equal(length(mb), 1) + let sg <- _fold(each(arr2d) |> skip(1) |> single()) + tt |> equal(length(sg), 1) delete arr2d } } @@ -2951,14 +2939,12 @@ def impure_having_sel(x : int) : int { def test_having_impure_selector_call_parity(t : T?) { t |> run("repeated impure having reducers evaluate as often fused as plain") @(tt : T?) { let arr = [1, 2, 3, 4, 5, 6] - unsafe { - g_having_sel_calls = 0 - let plain <- arr._group_by_lazy(_ % 3)._having((_._1 |> select($(x : int) => impure_having_sel(x)) |> sum > 4) && (_._1 |> select($(x : int) => impure_having_sel(x)) |> sum < 100))._select((K = _._0, N = _._1 |> length)) - let plainCalls = g_having_sel_calls - g_having_sel_calls = 0 - let fused <- _fold(arr._group_by_lazy(_ % 3)._having((_._1 |> select($(x : int) => impure_having_sel(x)) |> sum > 4) && (_._1 |> select($(x : int) => impure_having_sel(x)) |> sum < 100))._select((K = _._0, N = _._1 |> length))) - tt |> equal(length(fused), length(plain)) - tt |> equal(g_having_sel_calls, plainCalls, "impure selector side effects match tier-2") - } + g_having_sel_calls = 0 + let plain <- arr._group_by_lazy(_ % 3)._having((_._1 |> select($(x : int) => impure_having_sel(x)) |> sum > 4) && (_._1 |> select($(x : int) => impure_having_sel(x)) |> sum < 100))._select((K = _._0, N = _._1 |> length)) + let plainCalls = g_having_sel_calls + g_having_sel_calls = 0 + let fused <- _fold(arr._group_by_lazy(_ % 3)._having((_._1 |> select($(x : int) => impure_having_sel(x)) |> sum > 4) && (_._1 |> select($(x : int) => impure_having_sel(x)) |> sum < 100))._select((K = _._0, N = _._1 |> length))) + tt |> equal(length(fused), length(plain)) + tt |> equal(g_having_sel_calls, plainCalls, "impure selector side effects match tier-2") } } diff --git a/tests/linq/test_linq_fold_order_family.das b/tests/linq/test_linq_fold_order_family.das index 9126412372..432c729632 100644 --- a/tests/linq/test_linq_fold_order_family.das +++ b/tests/linq/test_linq_fold_order_family.das @@ -26,13 +26,11 @@ require dastest/testing_boost public def test_order_by_reverse_take_via_pattern_table(t : T?) { t |> run("order_by + reverse + take splices to descending top-N (single_name preserves the normalize swap)") @(tt : T?) { let scores <- [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] - unsafe { - let top3 <- _fold(each(scores)._order_by(_).reverse().take(3).to_array()) - tt |> equal(length(top3), 3) - tt |> equal(top3[0], 9) - tt |> equal(top3[1], 6) - tt |> equal(top3[2], 5) - } + let top3 <- _fold(each(scores)._order_by(_).reverse().take(3).to_array()) + tt |> equal(length(top3), 3) + tt |> equal(top3[0], 9) + tt |> equal(top3[1], 6) + tt |> equal(top3[2], 5) } } @@ -40,10 +38,8 @@ def test_order_by_reverse_take_via_pattern_table(t : T?) { def test_order_by_descending_reverse_first_via_pattern_table(t : T?) { t |> run("order_by_descending + reverse + first splices to ascending min (streaming_min path post-normalize)") @(tt : T?) { let scores <- [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] - unsafe { - let lo = _fold(each(scores)._order_by_descending(_).reverse().first()) - tt |> equal(lo, 1) - } + let lo = _fold(each(scores)._order_by_descending(_).reverse().first()) + tt |> equal(lo, 1) } } @@ -53,14 +49,12 @@ def test_order_by_descending_reverse_first_via_pattern_table(t : T?) { def test_chained_wheres_then_order_take(t : T?) { t |> run("two consecutive _where calls compose via collapse_chained_wheres, then route through fused_prefilter") @(tt : T?) { let scores <- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - unsafe { - // _ > 2 → [3..10]; _ < 9 → [3..8]; order_by → [3,4,5,6,7,8]; take(3) → [3,4,5]. - let buf <- _fold(each(scores)._where(_ > 2)._where(_ < 9)._order_by(_).take(3).to_array()) - tt |> equal(length(buf), 3) - tt |> equal(buf[0], 3) - tt |> equal(buf[1], 4) - tt |> equal(buf[2], 5) - } + // _ > 2 → [3..10]; _ < 9 → [3..8]; order_by → [3,4,5,6,7,8]; take(3) → [3,4,5]. + let buf <- _fold(each(scores)._where(_ > 2)._where(_ < 9)._order_by(_).take(3).to_array()) + tt |> equal(length(buf), 3) + tt |> equal(buf[0], 3) + tt |> equal(buf[1], 4) + tt |> equal(buf[2], 5) } } @@ -70,14 +64,12 @@ def test_chained_wheres_then_order_take(t : T?) { def test_order_then_plain_distinct(t : T?) { t |> run("order_by then plain distinct: whole-tuple equality is position-invariant; deduped sorted result") @(tt : T?) { let scores <- [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] - unsafe { - let buf <- _fold(each(scores)._order_by(_) |> distinct() |> to_array()) - // Ascending [1,1,2,3,3,4,5,5,5,6,9] then distinct → [1,2,3,4,5,6,9]. - tt |> equal(length(buf), 7) - tt |> equal(buf[0], 1) - tt |> equal(buf[1], 2) - tt |> equal(buf[6], 9) - } + let buf <- _fold(each(scores)._order_by(_) |> distinct() |> to_array()) + // Ascending [1,1,2,3,3,4,5,5,5,6,9] then distinct → [1,2,3,4,5,6,9]. + tt |> equal(length(buf), 7) + tt |> equal(buf[0], 1) + tt |> equal(buf[1], 2) + tt |> equal(buf[6], 9) } } @@ -87,14 +79,12 @@ def test_order_then_plain_distinct(t : T?) { def test_streaming_min_with_where(t : T?) { t |> run("where + order_by + first_or_default: streaming-min with prefilter, default on empty") @(tt : T?) { let scores <- [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] - unsafe { - let lo = _fold(each(scores)._where(_ > 4)._order_by(_).first_or_default(-1)) - // _ > 4 → [5,9,6,5,5]; ascending min → 5 - tt |> equal(lo, 5) - var empty_arr : array - let dflt = _fold(each(empty_arr)._where(_ > 4)._order_by(_).first_or_default(-1)) - tt |> equal(dflt, -1) - } + let lo = _fold(each(scores)._where(_ > 4)._order_by(_).first_or_default(-1)) + // _ > 4 → [5,9,6,5,5]; ascending min → 5 + tt |> equal(lo, 5) + var empty_arr : array + let dflt = _fold(each(empty_arr)._where(_ > 4)._order_by(_).first_or_default(-1)) + tt |> equal(dflt, -1) } } @@ -104,14 +94,12 @@ def test_streaming_min_with_where(t : T?) { def test_bounded_heap_with_distinct(t : T?) { t |> run("distinct + order_by + take: bounded-heap with dset gate; single-pass dedup-then-top-N") @(tt : T?) { let scores <- [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] - unsafe { - let top3 <- _fold(each(scores) |> distinct() |> _order_by(_) |> take(3) |> to_array()) - // distinct [3,1,4,5,9,2,6] → ascending [1,2,3,4,5,6,9] → top 3 → [1,2,3] - tt |> equal(length(top3), 3) - tt |> equal(top3[0], 1) - tt |> equal(top3[1], 2) - tt |> equal(top3[2], 3) - } + let top3 <- _fold(each(scores) |> distinct() |> _order_by(_) |> take(3) |> to_array()) + // distinct [3,1,4,5,9,2,6] → ascending [1,2,3,4,5,6,9] → top 3 → [1,2,3] + tt |> equal(length(top3), 3) + tt |> equal(top3[0], 1) + tt |> equal(top3[1], 2) + tt |> equal(top3[2], 3) } } @@ -119,40 +107,30 @@ def test_bounded_heap_with_distinct(t : T?) { def test_order_take_nonpositive_then_first(t : T?) { t |> run("order_by + take(0) + first_or_default returns the default") @(tt : T?) { let scores <- [5, 1, 4] - unsafe { - let v = _fold(each(scores)._order_by(_).take(0).first_or_default(-7)) - tt |> equal(v, -7) - } + let v = _fold(each(scores)._order_by(_).take(0).first_or_default(-7)) + tt |> equal(v, -7) } t |> run("where + order_by + take(0) + first_or_default returns the default") @(tt : T?) { let scores <- [5, 1, 4] - unsafe { - let v = _fold(each(scores)._where(_ > 0)._order_by(_).take(0).first_or_default(-7)) - tt |> equal(v, -7) - } + let v = _fold(each(scores)._where(_ > 0)._order_by(_).take(0).first_or_default(-7)) + tt |> equal(v, -7) } t |> run("order_by + take(negative) + first_or_default returns the default") @(tt : T?) { let scores <- [5, 1, 4] - unsafe { - let v = _fold(each(scores)._order_by(_).take(-3).first_or_default(-7)) - tt |> equal(v, -7) - } + let v = _fold(each(scores)._order_by(_).take(-3).first_or_default(-7)) + tt |> equal(v, -7) } t |> run("order_by + take(positive) + first_or_default still finds the min") @(tt : T?) { let scores <- [5, 1, 4] - unsafe { - let v = _fold(each(scores)._order_by(_).take(2).first_or_default(-7)) - tt |> equal(v, 1) - } + let v = _fold(each(scores)._order_by(_).take(2).first_or_default(-7)) + tt |> equal(v, 1) } t |> run("order_by + take(0) + first panics like plain") @(tt : T?) { let scores <- [5, 1, 4] var didPanic = false try { - unsafe { - let v = _fold(each(scores)._order_by(_).take(0).first()) - tt |> success(false, "expected panic; got {v}") - } + let v = _fold(each(scores)._order_by(_).take(0).first()) + tt |> success(false, "expected panic; got {v}") } recover { didPanic = true } @@ -162,10 +140,8 @@ def test_order_take_nonpositive_then_first(t : T?) { let scores <- [5, 1, 4] var didPanic = false try { - unsafe { - let v = _fold(each(scores)._where(_ > 0)._order_by(_).take(0).first()) - tt |> success(false, "expected panic; got {v}") - } + let v = _fold(each(scores)._where(_ > 0)._order_by(_).take(0).first()) + tt |> success(false, "expected panic; got {v}") } recover { didPanic = true } diff --git a/tests/linq/test_linq_fold_terminal_select.das b/tests/linq/test_linq_fold_terminal_select.das index f4c7f84dd5..e07e917c67 100644 --- a/tests/linq/test_linq_fold_terminal_select.das +++ b/tests/linq/test_linq_fold_terminal_select.das @@ -48,13 +48,11 @@ def test_order_take_select_array(t : T?) { t |> run("plan_order_family: take + terminal _select") @(tt : T?) { let sounds <- make_sounds() // Closest 3 by |x|; return their ids. - unsafe { - let ids <- _fold(each(sounds)._order_by(abs(_.x)).take(3)._select(_.id).to_array()) - // Sounds with smallest |x|: id 2 (1.0), id 4 (1.0), id 1 (3.0). - tt |> equal(length(ids), 3) - tt |> equal(true, ids[0] == 2 || ids[0] == 4) - tt |> equal(true, ids[2] == 1) - } + let ids <- _fold(each(sounds)._order_by(abs(_.x)).take(3)._select(_.id).to_array()) + // Sounds with smallest |x|: id 2 (1.0), id 4 (1.0), id 1 (3.0). + tt |> equal(length(ids), 3) + tt |> equal(true, ids[0] == 2 || ids[0] == 4) + tt |> equal(true, ids[2] == 1) } } @@ -62,13 +60,11 @@ def test_order_take_select_array(t : T?) { def test_where_order_take_select_array(t : T?) { t |> run("plan_order_family: where + take + terminal _select") @(tt : T?) { let sounds <- make_sounds() - unsafe { - let ids <- _fold(each(sounds)._where(_.rank >= 2)._order_by(_.x).take(2)._select(_.id).to_array()) - // After filter rank>=2: ids 2,3,4,5 (x = 1,4,1,5). Top 2 by x: ids 2 (1.0), 4 (1.0). - tt |> equal(length(ids), 2) - for (id in ids) { - tt |> equal(true, id == 2 || id == 4) - } + let ids <- _fold(each(sounds)._where(_.rank >= 2)._order_by(_.x).take(2)._select(_.id).to_array()) + // After filter rank>=2: ids 2,3,4,5 (x = 1,4,1,5). Top 2 by x: ids 2 (1.0), 4 (1.0). + tt |> equal(length(ids), 2) + for (id in ids) { + tt |> equal(true, id == 2 || id == 4) } } } @@ -77,12 +73,10 @@ def test_where_order_take_select_array(t : T?) { def test_where_order_bare_select_array(t : T?) { t |> run("plan_order_family: where + bare order + terminal _select") @(tt : T?) { let sounds <- make_sounds() - unsafe { - let ranks <- _fold(each(sounds)._where(_.id != 3)._order_by(_.x)._select(_.rank).to_array()) - // After filter id!=3: ids 1,2,4,5 (x = 3,1,1,5). Sorted by x: (2 or 4, 2 or 4, 1, 5). - tt |> equal(length(ranks), 4) - tt |> equal(ranks[3], 5) - } + let ranks <- _fold(each(sounds)._where(_.id != 3)._order_by(_.x)._select(_.rank).to_array()) + // After filter id!=3: ids 1,2,4,5 (x = 3,1,1,5). Sorted by x: (2 or 4, 2 or 4, 1, 5). + tt |> equal(length(ranks), 4) + tt |> equal(ranks[3], 5) } } @@ -93,10 +87,8 @@ def test_order_take_select_decs(t : T?) { create_entities(5) $(eid : EntityId; i : int; var cmp : ComponentMap) { apply_decs_template(cmp, DecsSound(id = i + 1, x = float((i % 2) * 5 + 1))) } - unsafe { - let ids <- _fold(from_decs_template(type)._order_by(_.x).take(2)._select(_.id).to_array()) - tt |> equal(length(ids), 2) - } + let ids <- _fold(from_decs_template(type)._order_by(_.x).take(2)._select(_.id).to_array()) + tt |> equal(length(ids), 2) restart() } } @@ -105,13 +97,11 @@ def test_order_take_select_decs(t : T?) { def test_reverse_take_select_array(t : T?) { t |> run("plan_reverse: where + reverse + take + terminal _select") @(tt : T?) { let sounds <- make_sounds() - unsafe { - let ids <- _fold(each(sounds)._where(_.rank > 0).reverse().take(2)._select(_.id).to_array()) - // After filter (all 5), reverse: 5,4,3,2,1. take 2: 5,4. - tt |> equal(length(ids), 2) - tt |> equal(ids[0], 5) - tt |> equal(ids[1], 4) - } + let ids <- _fold(each(sounds)._where(_.rank > 0).reverse().take(2)._select(_.id).to_array()) + // After filter (all 5), reverse: 5,4,3,2,1. take 2: 5,4. + tt |> equal(length(ids), 2) + tt |> equal(ids[0], 5) + tt |> equal(ids[1], 4) } } @@ -129,13 +119,11 @@ def test_reverse_take_select_array(t : T?) { def test_reverse_take_select_array_bare(t : T?) { t |> run("plan_reverse R6: bare reverse + take + terminal _select — backward index walk projects K only") @(tt : T?) { let sounds <- make_sounds() - unsafe { - // ids 1..5; reverse: 5,4,3,2,1; take 2: 5,4; select _.id: 5,4 - let ids <- _fold(each(sounds).reverse().take(2)._select(_.id).to_array()) - tt |> equal(length(ids), 2) - tt |> equal(ids[0], 5) - tt |> equal(ids[1], 4) - } + // ids 1..5; reverse: 5,4,3,2,1; take 2: 5,4; select _.id: 5,4 + let ids <- _fold(each(sounds).reverse().take(2)._select(_.id).to_array()) + tt |> equal(length(ids), 2) + tt |> equal(ids[0], 5) + tt |> equal(ids[1], 4) } } @@ -143,14 +131,12 @@ def test_reverse_take_select_array_bare(t : T?) { def test_reverse_take_select_array_take_exceeds(t : T?) { t |> run("plan_reverse R6: bare reverse + take(N>len) + _select clamps to length") @(tt : T?) { let sounds <- make_sounds() - unsafe { - // ids 1..5; reverse: 5,4,3,2,1; take 100 clamps to 5; select _.id*2 - let xs <- _fold(each(sounds).reverse().take(100)._select(_.id * 2).to_array()) - tt |> equal(length(xs), 5) - tt |> equal(xs[0], 10) - tt |> equal(xs[1], 8) - tt |> equal(xs[4], 2) - } + // ids 1..5; reverse: 5,4,3,2,1; take 100 clamps to 5; select _.id*2 + let xs <- _fold(each(sounds).reverse().take(100)._select(_.id * 2).to_array()) + tt |> equal(length(xs), 5) + tt |> equal(xs[0], 10) + tt |> equal(xs[1], 8) + tt |> equal(xs[4], 2) } } @@ -158,10 +144,8 @@ def test_reverse_take_select_array_take_exceeds(t : T?) { def test_reverse_take_select_array_take_zero(t : T?) { t |> run("plan_reverse R6: bare reverse + take(0) + _select returns empty") @(tt : T?) { let sounds <- make_sounds() - unsafe { - let ids <- _fold(each(sounds).reverse().take(0)._select(_.id).to_array()) - tt |> equal(length(ids), 0) - } + let ids <- _fold(each(sounds).reverse().take(0)._select(_.id).to_array()) + tt |> equal(length(ids), 0) } } @@ -169,10 +153,8 @@ def test_reverse_take_select_array_take_zero(t : T?) { def test_reverse_take_select_array_empty(t : T?) { t |> run("plan_reverse R6: bare reverse + take + _select on empty source") @(tt : T?) { var empty_sounds : array - unsafe { - let ids <- _fold(each(empty_sounds).reverse().take(3)._select(_.id).to_array()) - tt |> equal(length(ids), 0) - } + let ids <- _fold(each(empty_sounds).reverse().take(3)._select(_.id).to_array()) + tt |> equal(length(ids), 0) } } @@ -180,11 +162,9 @@ def test_reverse_take_select_array_empty(t : T?) { def test_reverse_select_first_array(t : T?) { t |> run("plan_reverse: where + reverse + _select + first") @(tt : T?) { let sounds <- make_sounds() - unsafe { - let id = _fold(each(sounds)._where(_.rank > 0).reverse()._select(_.id).first()) - // Reverse of ids 1..5 is 5,4,3,2,1; first = 5. - tt |> equal(id, 5) - } + let id = _fold(each(sounds)._where(_.rank > 0).reverse()._select(_.id).first()) + // Reverse of ids 1..5 is 5,4,3,2,1; first = 5. + tt |> equal(id, 5) } } @@ -198,17 +178,15 @@ def test_reverse_select_first_array(t : T?) { def test_reverse_pre_and_post_select_array(t : T?) { t |> run("plan_reverse R1-R4: where + select(f) + reverse + take + select(g) — both selects compose") @(tt : T?) { let sounds <- make_sounds() - unsafe { - // pre-select: id*10 → [10, 20, 30, 40, 50] - // reverse: → [50, 40, 30, 20, 10] - // take 3: → [50, 40, 30] - // post-select: +1 → [51, 41, 31] - let out <- _fold(each(sounds)._where(_.rank > 0)._select(_.id * 10).reverse().take(3)._select(_ + 1).to_array()) - tt |> equal(length(out), 3) - tt |> equal(out[0], 51) - tt |> equal(out[1], 41) - tt |> equal(out[2], 31) - } + // pre-select: id*10 → [10, 20, 30, 40, 50] + // reverse: → [50, 40, 30, 20, 10] + // take 3: → [50, 40, 30] + // post-select: +1 → [51, 41, 31] + let out <- _fold(each(sounds)._where(_.rank > 0)._select(_.id * 10).reverse().take(3)._select(_ + 1).to_array()) + tt |> equal(length(out), 3) + tt |> equal(out[0], 51) + tt |> equal(out[1], 41) + tt |> equal(out[2], 31) } } @@ -216,14 +194,12 @@ def test_reverse_pre_and_post_select_array(t : T?) { def test_reverse_pre_and_post_select_first(t : T?) { t |> run("plan_reverse Rb: where + select(f) + reverse + select(g) + first — both selects compose") @(tt : T?) { let sounds <- make_sounds() - unsafe { - // pre-select: id*10 → [10, 20, 30, 40, 50] - // reverse: → [50, 40, 30, 20, 10] - // post-select: +1 → [51, 41, 31, 21, 11] - // first: → 51 - let v = _fold(each(sounds)._where(_.rank > 0)._select(_.id * 10).reverse()._select(_ + 1).first()) - tt |> equal(v, 51) - } + // pre-select: id*10 → [10, 20, 30, 40, 50] + // reverse: → [50, 40, 30, 20, 10] + // post-select: +1 → [51, 41, 31, 21, 11] + // first: → 51 + let v = _fold(each(sounds)._where(_.rank > 0)._select(_.id * 10).reverse()._select(_ + 1).first()) + tt |> equal(v, 51) } } @@ -235,11 +211,9 @@ def test_reverse_pre_and_post_select_first(t : T?) { def test_reverse_pre_and_post_select_first_or_default_nonempty(t : T?) { t |> run("plan_reverse Rb: where + select(f) + reverse + select(g) + first_or_default — nonempty hits found branch") @(tt : T?) { let sounds <- make_sounds() - unsafe { - // sequence non-empty: termsel(lastName) = (50)+1 = 51 - let v = _fold(each(sounds)._where(_.rank > 0)._select(_.id * 10).reverse()._select(_ + 1).first_or_default(-99)) - tt |> equal(v, 51) - } + // sequence non-empty: termsel(lastName) = (50)+1 = 51 + let v = _fold(each(sounds)._where(_.rank > 0)._select(_.id * 10).reverse()._select(_ + 1).first_or_default(-99)) + tt |> equal(v, 51) } } @@ -247,12 +221,10 @@ def test_reverse_pre_and_post_select_first_or_default_nonempty(t : T?) { def test_reverse_pre_and_post_select_first_or_default_empty(t : T?) { t |> run("plan_reverse Rb: where + select(f) + reverse + select(g) + first_or_default — empty seq returns RAW default, not termsel(default)") @(tt : T?) { let sounds <- make_sounds() - unsafe { - // where filters everything out → empty sequence → default branch fires. - // If emit re-projects, result would be (-99)+1 = -98 (wrong). Must be -99. - let v = _fold(each(sounds)._where(_.rank > 9999)._select(_.id * 10).reverse()._select(_ + 1).first_or_default(-99)) - tt |> equal(v, -99) - } + // where filters everything out → empty sequence → default branch fires. + // If emit re-projects, result would be (-99)+1 = -98 (wrong). Must be -99. + let v = _fold(each(sounds)._where(_.rank > 9999)._select(_.id * 10).reverse()._select(_ + 1).first_or_default(-99)) + tt |> equal(v, -99) } } @@ -263,13 +235,11 @@ def test_reverse_take_select_decs(t : T?) { create_entities(4) $(eid : EntityId; i : int; var cmp : ComponentMap) { apply_decs_template(cmp, DecsSound(id = i + 1, x = float(i))) } - unsafe { - // ids: [1,2,3,4]; reverse: [4,3,2,1]; take 2: [4,3]; select _.id: [4,3] - let ids <- _fold(from_decs_template(type).reverse().take(2)._select(_.id).to_array()) - tt |> equal(length(ids), 2) - tt |> equal(ids[0], 4) - tt |> equal(ids[1], 3) - } + // ids: [1,2,3,4]; reverse: [4,3,2,1]; take 2: [4,3]; select _.id: [4,3] + let ids <- _fold(from_decs_template(type).reverse().take(2)._select(_.id).to_array()) + tt |> equal(length(ids), 2) + tt |> equal(ids[0], 4) + tt |> equal(ids[1], 3) restart() } } @@ -281,14 +251,12 @@ def test_reverse_take_select_decs_take_exceeds(t : T?) { create_entities(3) $(eid : EntityId; i : int; var cmp : ComponentMap) { apply_decs_template(cmp, DecsSound(id = i + 10, x = float(i))) } - unsafe { - // ids: [10,11,12]; reverse: [12,11,10]; take 100 clamps to 3: [12,11,10]; select _.id - let ids <- _fold(from_decs_template(type).reverse().take(100)._select(_.id).to_array()) - tt |> equal(length(ids), 3) - tt |> equal(ids[0], 12) - tt |> equal(ids[1], 11) - tt |> equal(ids[2], 10) - } + // ids: [10,11,12]; reverse: [12,11,10]; take 100 clamps to 3: [12,11,10]; select _.id + let ids <- _fold(from_decs_template(type).reverse().take(100)._select(_.id).to_array()) + tt |> equal(length(ids), 3) + tt |> equal(ids[0], 12) + tt |> equal(ids[1], 11) + tt |> equal(ids[2], 10) restart() } } @@ -297,10 +265,8 @@ def test_reverse_take_select_decs_take_exceeds(t : T?) { def test_reverse_take_select_decs_empty(t : T?) { t |> run("plan_decs_reverse: reverse + take + terminal _select on empty source") @(tt : T?) { restart() - unsafe { - let ids <- _fold(from_decs_template(type).reverse().take(5)._select(_.id).to_array()) - tt |> equal(length(ids), 0) - } + let ids <- _fold(from_decs_template(type).reverse().take(5)._select(_.id).to_array()) + tt |> equal(length(ids), 0) restart() } } @@ -315,15 +281,13 @@ def test_join_select_to_array(t : T?) { create_entities(2) $(eid : EntityId; i : int; var cmp : ComponentMap) { apply_decs_template(cmp, DecsDealer(id = i + 1, name = "Dealer{i}")) } - unsafe { - let names <- _fold(from_decs_template(type) |> _join(from_decs_template(type), - $(l, r) => l.dealer_id == r.id, - $(l, r) => (CarName = l.name, DealerName = r.name)) - |> _select(_.CarName) - |> to_array()) - // 3 cars × 1 matching dealer each = 3 results. - tt |> equal(length(names), 3) - } + let names <- _fold(from_decs_template(type) |> _join(from_decs_template(type), + $(l, r) => l.dealer_id == r.id, + $(l, r) => (CarName = l.name, DealerName = r.name)) + |> _select(_.CarName) + |> to_array()) + // 3 cars × 1 matching dealer each = 3 results. + tt |> equal(length(names), 3) restart() } } @@ -333,11 +297,9 @@ def test_zip_3arg_sum(t : T?) { t |> run("plan_zip: 3-arg zip + sum") @(tt : T?) { let a <- [1, 2, 3, 4] let b <- [10, 20, 30, 40] - unsafe { - let total = _fold(each(a) |> zip(each(b), $(x, y : int) => x * y) |> sum()) - // 1*10 + 2*20 + 3*30 + 4*40 = 10 + 40 + 90 + 160 = 300. - tt |> equal(total, 300) - } + let total = _fold(each(a) |> zip(each(b), $(x, y : int) => x * y) |> sum()) + // 1*10 + 2*20 + 3*30 + 4*40 = 10 + 40 + 90 + 160 = 300. + tt |> equal(total, 300) } } @@ -346,12 +308,10 @@ def test_zip_3arg_to_array(t : T?) { t |> run("plan_zip: 3-arg zip + to_array") @(tt : T?) { let a <- [1, 2, 3] let b <- [10, 20, 30] - unsafe { - let r <- _fold(each(a) |> zip(each(b), $(x, y : int) => x + y) |> to_array()) - tt |> equal(length(r), 3) - tt |> equal(r[0], 11) - tt |> equal(r[1], 22) - tt |> equal(r[2], 33) - } + let r <- _fold(each(a) |> zip(each(b), $(x, y : int) => x + y) |> to_array()) + tt |> equal(length(r), 3) + tt |> equal(r[0], 11) + tt |> equal(r[1], 22) + tt |> equal(r[2], 33) } } diff --git a/tests/linq/test_linq_fold_theme2_trailing_where.das b/tests/linq/test_linq_fold_theme2_trailing_where.das index f46e906395..e137d4d89c 100644 --- a/tests/linq/test_linq_fold_theme2_trailing_where.das +++ b/tests/linq/test_linq_fold_theme2_trailing_where.das @@ -75,15 +75,13 @@ def test_join_where_count(t : T?) { create_entities(2) $(eid : EntityId; i : int; var cmp : ComponentMap) { apply_decs_template(cmp, DecsDealer(id = i + 1, name = "Dealer{i}")) } - unsafe { - let filtered = _fold(from_decs_template(type) |> _join(from_decs_template(type), - $(l, r) => l.dealer_id == r.id, - $(l, r) => (CarName = l.name, DealerName = r.name)) - |> _where(_.DealerName == "Dealer0") - |> count()) - // 4 cars × dealer_id 1,2,1,2; matching Dealer0 (id=1) → cars i=0,2 → 2 results. - tt |> equal(filtered, 2) - } + let filtered = _fold(from_decs_template(type) |> _join(from_decs_template(type), + $(l, r) => l.dealer_id == r.id, + $(l, r) => (CarName = l.name, DealerName = r.name)) + |> _where(_.DealerName == "Dealer0") + |> count()) + // 4 cars × dealer_id 1,2,1,2; matching Dealer0 (id=1) → cars i=0,2 → 2 results. + tt |> equal(filtered, 2) restart() } } @@ -98,14 +96,12 @@ def test_join_where_to_array(t : T?) { create_entities(2) $(eid : EntityId; i : int; var cmp : ComponentMap) { apply_decs_template(cmp, DecsDealer(id = i + 1, name = "Dealer{i}")) } - unsafe { - let rows <- _fold(from_decs_template(type) |> _join(from_decs_template(type), - $(l, r) => l.dealer_id == r.id, - $(l, r) => (CarName = l.name, DealerName = r.name)) - |> _where(_.DealerName == "Dealer1") - |> to_array()) - tt |> equal(length(rows), 2) - } + let rows <- _fold(from_decs_template(type) |> _join(from_decs_template(type), + $(l, r) => l.dealer_id == r.id, + $(l, r) => (CarName = l.name, DealerName = r.name)) + |> _where(_.DealerName == "Dealer1") + |> to_array()) + tt |> equal(length(rows), 2) restart() } } @@ -120,15 +116,13 @@ def test_join_where_select_to_array(t : T?) { create_entities(2) $(eid : EntityId; i : int; var cmp : ComponentMap) { apply_decs_template(cmp, DecsDealer(id = i + 1, name = "Dealer{i}")) } - unsafe { - let names <- _fold(from_decs_template(type) |> _join(from_decs_template(type), - $(l, r) => l.dealer_id == r.id, - $(l, r) => (CarName = l.name, DealerName = r.name)) - |> _where(_.DealerName == "Dealer0") - |> _select(_.CarName) - |> to_array()) - tt |> equal(length(names), 2) - } + let names <- _fold(from_decs_template(type) |> _join(from_decs_template(type), + $(l, r) => l.dealer_id == r.id, + $(l, r) => (CarName = l.name, DealerName = r.name)) + |> _where(_.DealerName == "Dealer0") + |> _select(_.CarName) + |> to_array()) + tt |> equal(length(names), 2) restart() } } @@ -139,14 +133,12 @@ def test_join_where_select_to_array(t : T?) { def test_groupby_having_where_to_array(t : T?) { t |> run("plan_group_by: trailing _where (HAVING) on post-aggregate tuple (probe 4a)") @(tt : T?) { let items <- make_items() - unsafe { - let rows <- _fold(each(items) - ._group_by(_.category) - ._select((Cat = _._0, Total = _._1 |> select(@(i : Item) => i.price) |> sum)) - ._where(_.Total > 500) |> to_array()) - // Category totals: A=400, B=1200, C=50. Filter Total > 500 → only B. - tt |> equal(length(rows), 1) - } + let rows <- _fold(each(items) + ._group_by(_.category) + ._select((Cat = _._0, Total = _._1 |> select(@(i : Item) => i.price) |> sum)) + ._where(_.Total > 500) |> to_array()) + // Category totals: A=400, B=1200, C=50. Filter Total > 500 → only B. + tt |> equal(length(rows), 1) } } @@ -154,15 +146,13 @@ def test_groupby_having_where_to_array(t : T?) { def test_groupby_having_where_count(t : T?) { t |> run("plan_group_by: trailing _where + count") @(tt : T?) { let items <- make_items() - unsafe { - let n = _fold(each(items) - ._group_by(_.category) - ._select((Cat = _._0, Total = _._1 |> select(@(i : Item) => i.price) |> sum)) - ._where(_.Total > 100) - |> count()) - // Buckets with Total > 100: A (400), B (1200) → 2. - tt |> equal(n, 2) - } + let n = _fold(each(items) + ._group_by(_.category) + ._select((Cat = _._0, Total = _._1 |> select(@(i : Item) => i.price) |> sum)) + ._where(_.Total > 100) + |> count()) + // Buckets with Total > 100: A (400), B (1200) → 2. + tt |> equal(n, 2) } } @@ -175,15 +165,13 @@ def test_groupby_having_where_decs(t : T?) { let prices = [100, 300, 200, 800, 200, 50] apply_decs_template(cmp, DecsItem(category = cats[i], price = prices[i])) } - unsafe { - let rows <- _fold(from_decs_template(type) - ._group_by(_.category) - ._select((Cat = _._0, Total = _._1 |> select(@(i : tuple) => i.price) |> sum)) - ._where(_.Total > 500) - |> to_array()) - // Same data as array: A=400, B=1200, C=50. Filter keeps B. - tt |> equal(length(rows), 1) - } + let rows <- _fold(from_decs_template(type) + ._group_by(_.category) + ._select((Cat = _._0, Total = _._1 |> select(@(i : tuple) => i.price) |> sum)) + ._where(_.Total > 500) + |> to_array()) + // Same data as array: A=400, B=1200, C=50. Filter keeps B. + tt |> equal(length(rows), 1) restart() } } @@ -194,14 +182,12 @@ def test_groupby_having_where_decs(t : T?) { def test_take_where_count(t : T?) { t |> run("plan_loop_or_count: take(N)._where(p).count() (counter lane, probe 5c)") @(tt : T?) { let items <- make_act_items() - unsafe { - // First 5: active = [T,F,T,F,T]. Count active = 3. - // Semantic distinction from _where(p).take(5): would be 5 (5 active in items). - let r1 = _fold(each(items).take(5)._where(_.active).count()) - tt |> equal(r1, 3) - let r2 = _fold(each(items)._where(_.active).take(5).count()) - tt |> equal(r2, 5) - } + // First 5: active = [T,F,T,F,T]. Count active = 3. + // Semantic distinction from _where(p).take(5): would be 5 (5 active in items). + let r1 = _fold(each(items).take(5)._where(_.active).count()) + tt |> equal(r1, 3) + let r2 = _fold(each(items)._where(_.active).take(5).count()) + tt |> equal(r2, 5) } } @@ -209,11 +195,9 @@ def test_take_where_count(t : T?) { def test_take_where_sum(t : T?) { t |> run("plan_loop_or_count: take(N)._where(p).sum() (accumulator lane)") @(tt : T?) { let items <- make_act_items() - unsafe { - // _select projects scores. take(5) → [10,20,30,40,50]. _where(>0) keeps all. sum=150. - let s = _fold(each(items)._select(_.score).take(5)._where(_ > 0).sum()) - tt |> equal(s, 150) - } + // _select projects scores. take(5) → [10,20,30,40,50]. _where(>0) keeps all. sum=150. + let s = _fold(each(items)._select(_.score).take(5)._where(_ > 0).sum()) + tt |> equal(s, 150) } } @@ -221,11 +205,9 @@ def test_take_where_sum(t : T?) { def test_take_where_first(t : T?) { t |> run("plan_loop_or_count: take(N)._where(p).first_or_default() (early-exit lane)") @(tt : T?) { let items <- make_act_items() - unsafe { - // take(3) → first 3 (T,F,T). First active = 10. - let f = _fold(each(items).take(3)._where(_.active).first_or_default(ActItem(active = false, score = -1))) - tt |> equal(f.score, 10) - } + // take(3) → first 3 (T,F,T). First active = 10. + let f = _fold(each(items).take(3)._where(_.active).first_or_default(ActItem(active = false, score = -1))) + tt |> equal(f.score, 10) } } @@ -233,13 +215,11 @@ def test_take_where_first(t : T?) { def test_take_where_to_array(t : T?) { t |> run("plan_loop_or_count: take(N)._where(p).to_array() (array lane)") @(tt : T?) { let items <- make_act_items() - unsafe { - // take(5) → first 5 (T,F,T,F,T). where(active) → 3 items, scores 10,30,50. - let arr <- _fold(each(items).take(5)._where(_.active).to_array()) - tt |> equal(length(arr), 3) - tt |> equal(arr[0].score, 10) - tt |> equal(arr[2].score, 50) - } + // take(5) → first 5 (T,F,T,F,T). where(active) → 3 items, scores 10,30,50. + let arr <- _fold(each(items).take(5)._where(_.active).to_array()) + tt |> equal(length(arr), 3) + tt |> equal(arr[0].score, 10) + tt |> equal(arr[2].score, 50) } } @@ -247,10 +227,8 @@ def test_take_where_to_array(t : T?) { def test_take_zero_where(t : T?) { t |> run("plan_loop_or_count: take(0)._where edge case") @(tt : T?) { let items <- make_act_items() - unsafe { - let r = _fold(each(items).take(0)._where(_.active).count()) - tt |> equal(r, 0) - } + let r = _fold(each(items).take(0)._where(_.active).count()) + tt |> equal(r, 0) } } @@ -271,12 +249,10 @@ def test_take_where_count_decs(t : T?) { t |> run("plan_loop_or_count: decs take(N)._where(p).count() (counter lane, probe 5c)") @(tt : T?) { restart() populate_decs_act_items() - unsafe { - let r1 = _fold(from_decs_template(type).take(5)._where(_.category == "T").count()) - tt |> equal(r1, 3) - let r2 = _fold(from_decs_template(type)._where(_.category == "T").take(5).count()) - tt |> equal(r2, 5) - } + let r1 = _fold(from_decs_template(type).take(5)._where(_.category == "T").count()) + tt |> equal(r1, 3) + let r2 = _fold(from_decs_template(type)._where(_.category == "T").take(5).count()) + tt |> equal(r2, 5) restart() } } @@ -286,13 +262,11 @@ def test_take_where_sum_decs(t : T?) { t |> run("plan_loop_or_count: decs take(N)._where(p).sum() (accumulator lane)") @(tt : T?) { restart() populate_decs_act_items() - unsafe { - // _select(price) → [10..80]. take(5) → [10,20,30,40,50]. _where(>25) → [30,40,50]. sum=120. - // Threshold chosen above the first taken element so the gate actually filters — `_ > 0` would - // pass all 5 and let a bypassed gate vacuously match the expected sum. - let s = _fold(from_decs_template(type)._select(_.price).take(5)._where(_ > 25).sum()) - tt |> equal(s, 120) - } + // _select(price) → [10..80]. take(5) → [10,20,30,40,50]. _where(>25) → [30,40,50]. sum=120. + // Threshold chosen above the first taken element so the gate actually filters — `_ > 0` would + // pass all 5 and let a bypassed gate vacuously match the expected sum. + let s = _fold(from_decs_template(type)._select(_.price).take(5)._where(_ > 25).sum()) + tt |> equal(s, 120) restart() } } @@ -302,10 +276,8 @@ def test_take_where_first_decs(t : T?) { t |> run("plan_loop_or_count: decs take(N)._where(p).first_or_default() (early-exit lane)") @(tt : T?) { restart() populate_decs_act_items() - unsafe { - let f = _fold(from_decs_template(type).take(3)._where(_.category == "T").first_or_default((category = "", price = -1))) - tt |> equal(f.price, 10) - } + let f = _fold(from_decs_template(type).take(3)._where(_.category == "T").first_or_default((category = "", price = -1))) + tt |> equal(f.price, 10) restart() } } @@ -315,12 +287,10 @@ def test_take_where_to_array_decs(t : T?) { t |> run("plan_loop_or_count: decs take(N)._where(p).to_array() (array lane)") @(tt : T?) { restart() populate_decs_act_items() - unsafe { - let arr <- _fold(from_decs_template(type).take(5)._where(_.category == "T").to_array()) - tt |> equal(length(arr), 3) - tt |> equal(arr[0].price, 10) - tt |> equal(arr[2].price, 50) - } + let arr <- _fold(from_decs_template(type).take(5)._where(_.category == "T").to_array()) + tt |> equal(length(arr), 3) + tt |> equal(arr[0].price, 10) + tt |> equal(arr[2].price, 50) restart() } } @@ -330,11 +300,9 @@ def test_head_where_take_post_where_count_decs(t : T?) { t |> run("plan_loop_or_count: decs _where(P1)._take(N)._where(P2).count() (head + gate fire together)") @(tt : T?) { restart() populate_decs_act_items() - unsafe { - // _where(price > 15) drops [10] → [20,30,40,50,60,70,80]. take(4) → [20,30,40,50]. _where("T") → [30,50]. count=2. - let r = _fold(from_decs_template(type)._where(_.price > 15).take(4)._where(_.category == "T").count()) - tt |> equal(r, 2) - } + // _where(price > 15) drops [10] → [20,30,40,50,60,70,80]. take(4) → [20,30,40,50]. _where("T") → [30,50]. count=2. + let r = _fold(from_decs_template(type)._where(_.price > 15).take(4)._where(_.category == "T").count()) + tt |> equal(r, 2) restart() } } @@ -344,11 +312,9 @@ def test_select_take_post_where_count_decs(t : T?) { t |> run("plan_loop_or_count: decs _select(f).take(N)._where(p).count() (gate peels against finalBind)") @(tt : T?) { restart() populate_decs_act_items() - unsafe { - // _select(price) → [10..80]. take(5) → [10,20,30,40,50]. _where(>25) → [30,40,50]. count=3. - let r = _fold(from_decs_template(type)._select(_.price).take(5)._where(_ > 25).count()) - tt |> equal(r, 3) - } + // _select(price) → [10..80]. take(5) → [10,20,30,40,50]. _where(>25) → [30,40,50]. count=3. + let r = _fold(from_decs_template(type)._select(_.price).take(5)._where(_ > 25).count()) + tt |> equal(r, 3) restart() } } @@ -358,11 +324,9 @@ def test_skip_take_post_where_count_decs(t : T?) { t |> run("plan_loop_or_count: decs skip(M).take(N)._where(p).count() (skip + post-take gate)") @(tt : T?) { restart() populate_decs_act_items() - unsafe { - // skip(2) → [30,40,50,60,70,80]. take(4) → [30,40,50,60]. _where("T") → [30,50]. count=2. - let r = _fold(from_decs_template(type).skip(2).take(4)._where(_.category == "T").count()) - tt |> equal(r, 2) - } + // skip(2) → [30,40,50,60,70,80]. take(4) → [30,40,50,60]. _where("T") → [30,50]. count=2. + let r = _fold(from_decs_template(type).skip(2).take(4)._where(_.category == "T").count()) + tt |> equal(r, 2) restart() } } diff --git a/tests/linq/test_linq_fold_theme3_c1_c5_distinct_order_take.das b/tests/linq/test_linq_fold_theme3_c1_c5_distinct_order_take.das index 7470130ba8..bd722cb099 100644 --- a/tests/linq/test_linq_fold_theme3_c1_c5_distinct_order_take.das +++ b/tests/linq/test_linq_fold_theme3_c1_c5_distinct_order_take.das @@ -219,24 +219,22 @@ def populate_c1_decs() { def test_c1_decs_distinct_by_order_take(t : T?) { t |> run("C1-decs: from_decs_template + _distinct_by(_.user) + _order_by(_.ts) + take + to_array — decs lane bounded-heap with set-gate") @(tt : T?) { populate_c1_decs() - unsafe { - let rows <- _fold(from_decs_template(type) - |> _distinct_by(_.user) - |> _order_by(_.ts) - |> take(5) - |> to_array()) - tt |> equal(length(rows), 5) - tt |> equal(rows[0].user, "U0") - tt |> equal(rows[0].ts, 0) - tt |> equal(rows[1].user, "U8") - tt |> equal(rows[1].ts, 4) - tt |> equal(rows[2].user, "U1") - tt |> equal(rows[2].ts, 13) - tt |> equal(rows[3].user, "U9") - tt |> equal(rows[3].ts, 17) - tt |> equal(rows[4].user, "U2") - tt |> equal(rows[4].ts, 26) - } + let rows <- _fold(from_decs_template(type) + |> _distinct_by(_.user) + |> _order_by(_.ts) + |> take(5) + |> to_array()) + tt |> equal(length(rows), 5) + tt |> equal(rows[0].user, "U0") + tt |> equal(rows[0].ts, 0) + tt |> equal(rows[1].user, "U8") + tt |> equal(rows[1].ts, 4) + tt |> equal(rows[2].user, "U1") + tt |> equal(rows[2].ts, 13) + tt |> equal(rows[3].user, "U9") + tt |> equal(rows[3].ts, 17) + tt |> equal(rows[4].user, "U2") + tt |> equal(rows[4].ts, 26) restart() } } @@ -269,24 +267,22 @@ def populate_c5_decs() { def test_c5_decs_order_distinct_take(t : T?) { t |> run("C5-decs: from_decs_template + _order_by(_.score) + distinct() + take + to_array — decs lane with whole-tuple set") @(tt : T?) { populate_c5_decs() - unsafe { - let rows <- _fold(from_decs_template(type) - |> _order_by(_.score) - |> distinct() - |> take(3) - |> to_array()) - tt |> equal(length(rows), 3) - // 3 distinct TUPLES with smallest scores: (a,10), (b,10), (c,20). Track uniqueness by combined key so a buggy name-only dedup wouldn't pass. - var seenWhole : table - for (r in rows) { - seenWhole |> insert("{r.name}:{r.score}") - tt |> equal(r.score <= 20, true) - } - tt |> equal(length(seenWhole), 3) - tt |> equal(key_exists(seenWhole, "a:10"), true) - tt |> equal(key_exists(seenWhole, "b:10"), true) - tt |> equal(key_exists(seenWhole, "c:20"), true) + let rows <- _fold(from_decs_template(type) + |> _order_by(_.score) + |> distinct() + |> take(3) + |> to_array()) + tt |> equal(length(rows), 3) + // 3 distinct TUPLES with smallest scores: (a,10), (b,10), (c,20). Track uniqueness by combined key so a buggy name-only dedup wouldn't pass. + var seenWhole : table + for (r in rows) { + seenWhole |> insert("{r.name}:{r.score}") + tt |> equal(r.score <= 20, true) } + tt |> equal(length(seenWhole), 3) + tt |> equal(key_exists(seenWhole, "a:10"), true) + tt |> equal(key_exists(seenWhole, "b:10"), true) + tt |> equal(key_exists(seenWhole, "c:20"), true) restart() } } diff --git a/tests/linq/test_linq_fold_theme3_c2_group_by_order_by.das b/tests/linq/test_linq_fold_theme3_c2_group_by_order_by.das index f54a46c53e..8353f24f72 100644 --- a/tests/linq/test_linq_fold_theme3_c2_group_by_order_by.das +++ b/tests/linq/test_linq_fold_theme3_c2_group_by_order_by.das @@ -185,20 +185,18 @@ def populate_c2_decs() { def test_c2_decs_order_by_desc(t : T?) { t |> run("C2-decs: from_decs_template + _group_by + _select(count) + _order_by_descending + to_array — decs adapter feeds inline sort") @(tt : T?) { populate_c2_decs() - unsafe { - let rows <- _fold(from_decs_template(type) - |> _group_by(_.region) - |> _select((R = _._0, N = _._1 |> count())) - |> _order_by_descending(_.N) - |> to_array()) - tt |> equal(length(rows), 3) - tt |> equal(rows[0].R, "R") - tt |> equal(rows[0].N, 4) - tt |> equal(rows[1].R, "S") - tt |> equal(rows[1].N, 2) - tt |> equal(rows[2].R, "T") - tt |> equal(rows[2].N, 1) - } + let rows <- _fold(from_decs_template(type) + |> _group_by(_.region) + |> _select((R = _._0, N = _._1 |> count())) + |> _order_by_descending(_.N) + |> to_array()) + tt |> equal(length(rows), 3) + tt |> equal(rows[0].R, "R") + tt |> equal(rows[0].N, 4) + tt |> equal(rows[1].R, "S") + tt |> equal(rows[1].N, 2) + tt |> equal(rows[2].R, "T") + tt |> equal(rows[2].N, 1) restart() } } @@ -234,22 +232,20 @@ def populate_c2_decs_join() { def test_c2_decs_join_order_by(t : T?) { t |> run("C2-decs-join: from_decs_template(Car) + _join(Dealer) + _group_by(Region) + _select(count) + _order_by + to_array — isDecsJoin adapter + inline sort, single pass end-to-end") @(tt : T?) { populate_c2_decs_join() - unsafe { - let rows <- _fold(from_decs_template(type) - |> _join(from_decs_template(type), - $(l, r) => l.dealer_id == r.id, - $(l, r) => (Region = r.region, CarId = l.id)) - |> _group_by(_.Region) - |> _select((R = _._0, N = _._1 |> count())) - |> _order_by(_.N) - |> to_array()) - // south(2), north(4) ascending. - tt |> equal(length(rows), 2) - tt |> equal(rows[0].R, "south") - tt |> equal(rows[0].N, 2) - tt |> equal(rows[1].R, "north") - tt |> equal(rows[1].N, 4) - } + let rows <- _fold(from_decs_template(type) + |> _join(from_decs_template(type), + $(l, r) => l.dealer_id == r.id, + $(l, r) => (Region = r.region, CarId = l.id)) + |> _group_by(_.Region) + |> _select((R = _._0, N = _._1 |> count())) + |> _order_by(_.N) + |> to_array()) + // south(2), north(4) ascending. + tt |> equal(length(rows), 2) + tt |> equal(rows[0].R, "south") + tt |> equal(rows[0].N, 2) + tt |> equal(rows[1].R, "north") + tt |> equal(rows[1].N, 4) restart() } } diff --git a/tests/linq/test_linq_fold_theme3_decs_join_groupby.das b/tests/linq/test_linq_fold_theme3_decs_join_groupby.das index ec8f41affd..7c21913759 100644 --- a/tests/linq/test_linq_fold_theme3_decs_join_groupby.das +++ b/tests/linq/test_linq_fold_theme3_decs_join_groupby.das @@ -55,17 +55,15 @@ def c3e_make_result(carName, dealerRegion : string) : tuple run("C3a: _join + _group_by(_.Region) + _select(N=count()) + count() (bucket count)") @(tt : T?) { populate_c3_fixture() - unsafe { - let nBuckets = _fold(from_decs_template(type) - |> _join(from_decs_template(type), - $(l, r) => l.dealer_id == r.id, - $(l, r) => (Region = r.region, CarName = l.name)) - |> _group_by(_.Region) - |> _select((R = _._0, N = _._1 |> count())) - |> count()) - // 2 distinct regions across the 6 join pairs → 2 buckets. - tt |> equal(nBuckets, 2) - } + let nBuckets = _fold(from_decs_template(type) + |> _join(from_decs_template(type), + $(l, r) => l.dealer_id == r.id, + $(l, r) => (Region = r.region, CarName = l.name)) + |> _group_by(_.Region) + |> _select((R = _._0, N = _._1 |> count())) + |> count()) + // 2 distinct regions across the 6 join pairs → 2 buckets. + tt |> equal(nBuckets, 2) restart() } } @@ -76,16 +74,14 @@ def test_c3a_count_count(t : T?) { def test_c3b_sum_count(t : T?) { t |> run("C3b: _join + _group_by(_.Region) + _select(S=sum(r.CarId)) + count()") @(tt : T?) { populate_c3_fixture() - unsafe { - let nBuckets = _fold(from_decs_template(type) - |> _join(from_decs_template(type), - $(l, r) => l.dealer_id == r.id, - $(l, r) => (Region = r.region, CarId = l.id)) - |> _group_by(_.Region) - |> _select((R = _._0, S = _._1 |> select(@(r : tuple) => r.CarId) |> sum)) - |> count()) - tt |> equal(nBuckets, 2) - } + let nBuckets = _fold(from_decs_template(type) + |> _join(from_decs_template(type), + $(l, r) => l.dealer_id == r.id, + $(l, r) => (Region = r.region, CarId = l.id)) + |> _group_by(_.Region) + |> _select((R = _._0, S = _._1 |> select(@(r : tuple) => r.CarId) |> sum)) + |> count()) + tt |> equal(nBuckets, 2) restart() } } @@ -171,18 +167,16 @@ def test_c3e_result_lambda_called_once_per_pair(t : T?) { t |> run("C3e: result lambda fires exactly len(srcA)·matchesPerKey times (no double-eval)") @(tt : T?) { populate_c3_fixture() g_c3e_result_calls = 0 - unsafe { - let nBuckets = _fold(from_decs_template(type) - |> _join(from_decs_template(type), - $(l, r) => l.dealer_id == r.id, - $(l, r) => c3e_make_result(l.name, r.region)) - |> _group_by(_.Region) - |> _select((R = _._0, N = _._1 |> count())) - |> count()) - tt |> equal(nBuckets, 2) - // 6 cars × 1 dealer match per car = 6 result-lam invocations. - tt |> equal(g_c3e_result_calls, 6) - } + let nBuckets = _fold(from_decs_template(type) + |> _join(from_decs_template(type), + $(l, r) => l.dealer_id == r.id, + $(l, r) => c3e_make_result(l.name, r.region)) + |> _group_by(_.Region) + |> _select((R = _._0, N = _._1 |> count())) + |> count()) + tt |> equal(nBuckets, 2) + // 6 cars × 1 dealer match per car = 6 result-lam invocations. + tt |> equal(g_c3e_result_calls, 6) restart() } } @@ -193,20 +187,18 @@ def test_c3e_result_lambda_called_once_per_pair(t : T?) { def test_c3_anti_having_cascades(t : T?) { t |> run("C3-anti-having: _join + _group_by + _select + _where (HAVING) — v1 cascades, must produce correct result") @(tt : T?) { populate_c3_fixture() - unsafe { - let rows <- _fold(from_decs_template(type) - |> _join(from_decs_template(type), - $(l, r) => l.dealer_id == r.id, - $(l, r) => (Region = r.region, CarName = l.name)) - |> _group_by(_.Region) - |> _select((R = _._0, N = _._1 |> count())) - |> _where(_.N >= 3) - |> to_array()) - // Only "north" (4 cars) passes N>=3; "south" (2 cars) filtered out. - tt |> equal(length(rows), 1) - tt |> equal(rows[0].R, "north") - tt |> equal(rows[0].N, 4) - } + let rows <- _fold(from_decs_template(type) + |> _join(from_decs_template(type), + $(l, r) => l.dealer_id == r.id, + $(l, r) => (Region = r.region, CarName = l.name)) + |> _group_by(_.Region) + |> _select((R = _._0, N = _._1 |> count())) + |> _where(_.N >= 3) + |> to_array()) + // Only "north" (4 cars) passes N>=3; "south" (2 cars) filtered out. + tt |> equal(length(rows), 1) + tt |> equal(rows[0].R, "north") + tt |> equal(rows[0].N, 4) restart() } } @@ -217,18 +209,16 @@ def test_c3_anti_having_cascades(t : T?) { def test_c3_anti_segment_cascades(t : T?) { t |> run("C3-anti-segment: _join + _where + _group_by — segment between join and group_by_lazy cascades, must produce correct result") @(tt : T?) { populate_c3_fixture() - unsafe { - let nBuckets = _fold(from_decs_template(type) - |> _join(from_decs_template(type), - $(l, r) => l.dealer_id == r.id, - $(l, r) => (Region = r.region, CarName = l.name)) - |> _where(_.Region == "north") - |> _group_by(_.Region) - |> _select((R = _._0, N = _._1 |> count())) - |> count()) - // After WHERE filter: only north (4 cars) survives → 1 bucket. - tt |> equal(nBuckets, 1) - } + let nBuckets = _fold(from_decs_template(type) + |> _join(from_decs_template(type), + $(l, r) => l.dealer_id == r.id, + $(l, r) => (Region = r.region, CarName = l.name)) + |> _where(_.Region == "north") + |> _group_by(_.Region) + |> _select((R = _._0, N = _._1 |> count())) + |> count()) + // After WHERE filter: only north (4 cars) survives → 1 bucket. + tt |> equal(nBuckets, 1) restart() } } diff --git a/tests/linq/test_linq_fold_theme45_quick_wins.das b/tests/linq/test_linq_fold_theme45_quick_wins.das index 5e0781cd8d..5028efb26e 100644 --- a/tests/linq/test_linq_fold_theme45_quick_wins.das +++ b/tests/linq/test_linq_fold_theme45_quick_wins.das @@ -54,12 +54,10 @@ def make_users() : array { def test_distinct_count_pred(t : T?) { t |> run("plan_distinct: distinct_by(region).count(active)") @(tt : T?) { let users <- make_users() - unsafe { - // distinct_by keeps FIRST occurrence per region: us→active=true, eu→active=true, ap→active=false. - // count(active) over deduped → 2. - let n = _fold(each(users)._distinct_by(_.region) |> count($(u) => u.active)) - tt |> equal(n, 2) - } + // distinct_by keeps FIRST occurrence per region: us→active=true, eu→active=true, ap→active=false. + // count(active) over deduped → 2. + let n = _fold(each(users)._distinct_by(_.region) |> count($(u) => u.active)) + tt |> equal(n, 2) } } @@ -67,10 +65,8 @@ def test_distinct_count_pred(t : T?) { def test_distinct_long_count_pred(t : T?) { t |> run("plan_distinct: distinct_by(region).long_count(active)") @(tt : T?) { let users <- make_users() - unsafe { - let n = _fold(each(users)._distinct_by(_.region) |> long_count($(u) => u.active)) - tt |> equal(n, 2l) - } + let n = _fold(each(users)._distinct_by(_.region) |> long_count($(u) => u.active)) + tt |> equal(n, 2l) } } @@ -78,11 +74,9 @@ def test_distinct_long_count_pred(t : T?) { def test_distinct_count_pred_all_match(t : T?) { t |> run("plan_distinct: distinct_by + count(p) where all distinct match") @(tt : T?) { let users <- make_users() - unsafe { - // All distinct regions have score > 0 → all 3 inserted. - let n = _fold(each(users)._distinct_by(_.region) |> count($(u) => u.score > 0)) - tt |> equal(n, 3) - } + // All distinct regions have score > 0 → all 3 inserted. + let n = _fold(each(users)._distinct_by(_.region) |> count($(u) => u.score > 0)) + tt |> equal(n, 3) } } @@ -98,13 +92,11 @@ def test_decs_distinct_count_pred(t : T?) { create_entities(7) $(eid : EntityId; i : int; var cmp : ComponentMap) { apply_decs_template(cmp, DecsRecord(region = regions[i], active = actives[i], score = scores[i])) } - unsafe { - let n = _fold(from_decs_template(type) - |> _distinct_by(_.region) - |> count($(r) => r.active)) - // distinct_by keeps FIRST per region: us→true, eu→true, ap→false. count(active) → 2. - tt |> equal(n, 2) - } + let n = _fold(from_decs_template(type) + |> _distinct_by(_.region) + |> count($(r) => r.active)) + // distinct_by keeps FIRST per region: us→true, eu→true, ap→false. count(active) → 2. + tt |> equal(n, 2) restart() } } @@ -116,11 +108,9 @@ def test_zip_count_pred(t : T?) { t |> run("plan_zip: zip + count(p) over pair") @(tt : T?) { let a <- [1, 2, 3, 4, 5] let b <- [10, 20, 30, 40, 50] - unsafe { - // Pairs: (1,10)=11, (2,20)=22, (3,30)=33, (4,40)=44, (5,50)=55. count where sum>30 → 3. - let n = _fold(each(a) |> zip(each(b)) |> count($(p) => p._0 + p._1 > 30)) - tt |> equal(n, 3) - } + // Pairs: (1,10)=11, (2,20)=22, (3,30)=33, (4,40)=44, (5,50)=55. count where sum>30 → 3. + let n = _fold(each(a) |> zip(each(b)) |> count($(p) => p._0 + p._1 > 30)) + tt |> equal(n, 3) } } @@ -129,10 +119,8 @@ def test_zip_long_count_pred(t : T?) { t |> run("plan_zip: zip + long_count(p)") @(tt : T?) { let a <- [1, 2, 3] let b <- [10, 20, 30] - unsafe { - let n = _fold(each(a) |> zip(each(b)) |> long_count($(p) => p._0 < 3)) - tt |> equal(n, 2l) - } + let n = _fold(each(a) |> zip(each(b)) |> long_count($(p) => p._0 < 3)) + tt |> equal(n, 2l) } } @@ -141,11 +129,9 @@ def test_zip_where_then_count_pred(t : T?) { t |> run("plan_zip: zip + where + count(p) AND merge") @(tt : T?) { let a <- [1, 2, 3, 4, 5] let b <- [10, 20, 30, 40, 50] - unsafe { - // zip pairs filtered where p._0 > 1 → 4 pairs (2,3,4,5); count where p._1 < 50 → 3. - let n = _fold(each(a) |> zip(each(b)) |> _where(_._0 > 1) |> count($(p) => p._1 < 50)) - tt |> equal(n, 3) - } + // zip pairs filtered where p._0 > 1 → 4 pairs (2,3,4,5); count where p._1 < 50 → 3. + let n = _fold(each(a) |> zip(each(b)) |> _where(_._0 > 1) |> count($(p) => p._1 < 50)) + tt |> equal(n, 3) } } @@ -154,12 +140,10 @@ def test_zip_select_then_count_pred(t : T?) { t |> run("plan_zip: zip + select(F) + count(p) — p binds to post-select element") @(tt : T?) { let a <- [1, 2, 3, 4, 5] let b <- [10, 20, 30, 40, 50] - unsafe { - // Pairs: (1,10),(2,20),(3,30),(4,40),(5,50). Projected sums: 11,22,33,44,55. Count where sum > 30 → 3. - // Critical: P's `s` must bind to the projected sum, not the pre-select tuple. - let n = _fold(each(a) |> zip(each(b)) |> select($(p : tuple) => p._0 + p._1) |> count($(s) => s > 30)) - tt |> equal(n, 3) - } + // Pairs: (1,10),(2,20),(3,30),(4,40),(5,50). Projected sums: 11,22,33,44,55. Count where sum > 30 → 3. + // Critical: P's `s` must bind to the projected sum, not the pre-select tuple. + let n = _fold(each(a) |> zip(each(b)) |> select($(p : tuple) => p._0 + p._1) |> count($(s) => s > 30)) + tt |> equal(n, 3) } } @@ -168,11 +152,9 @@ def test_zip_select_then_long_count_pred(t : T?) { t |> run("plan_zip: zip + select(F) + long_count(p) — p binds to post-select element") @(tt : T?) { let a <- [1, 2, 3, 4, 5] let b <- [10, 20, 30, 40, 50] - unsafe { - // Projected products: 10,40,90,160,250. Count where product > 50 → 3 (90,160,250). - let n = _fold(each(a) |> zip(each(b)) |> select($(p : tuple) => p._0 * p._1) |> long_count($(v) => v > 50)) - tt |> equal(n, 3l) - } + // Projected products: 10,40,90,160,250. Count where product > 50 → 3 (90,160,250). + let n = _fold(each(a) |> zip(each(b)) |> select($(p : tuple) => p._0 * p._1) |> long_count($(v) => v > 50)) + tt |> equal(n, 3l) } } @@ -191,17 +173,15 @@ def test_zip_where_select_count_pred_side_effect_order(t : T?) { // Upstream where keeps 5 elements (a._0 in {2,4,6,8,10}). Eager `where(W).select(F).count(P)` runs F only on those 5. // If counterPred merged into whereCond (old bug), F would run on all 10 — driving g_side_effect_calls to 10. g_side_effect_calls = 0 - unsafe { - let n = _fold( - each(a) |> zip(each(b)) - |> where_($(p : tuple) => p._0 % 2 == 0) - |> select($(p : tuple) => side_effect_proj(p._0)) - |> count($(v) => v > 5) - ) - // 5 elements survive where (2,4,6,8,10) → projected to (4,8,12,16,20) → 4 are > 5. - tt |> equal(n, 4) - tt |> equal(g_side_effect_calls, 5) - } + let n = _fold( + each(a) |> zip(each(b)) + |> where_($(p : tuple) => p._0 % 2 == 0) + |> select($(p : tuple) => side_effect_proj(p._0)) + |> count($(v) => v > 5) + ) + // 5 elements survive where (2,4,6,8,10) → projected to (4,8,12,16,20) → 4 are > 5. + tt |> equal(n, 4) + tt |> equal(g_side_effect_calls, 5) } } @@ -216,10 +196,8 @@ def test_decs_bare_count(t : T?) { let prices = [100, 200, 300, 400, 500, 600] apply_decs_template(cmp, DecsItem(category = cats[i], price = prices[i])) } - unsafe { - let n = _fold(from_decs_template(type) |> count()) - tt |> equal(n, 6) - } + let n = _fold(from_decs_template(type) |> count()) + tt |> equal(n, 6) restart() } } @@ -233,10 +211,8 @@ def test_decs_bare_count_pred(t : T?) { let prices = [100, 200, 300, 400, 500, 600] apply_decs_template(cmp, DecsItem(category = cats[i], price = prices[i])) } - unsafe { - let n = _fold(from_decs_template(type) |> count($(x) => x.category == "B")) - tt |> equal(n, 3) - } + let n = _fold(from_decs_template(type) |> count($(x) => x.category == "B")) + tt |> equal(n, 3) restart() } } @@ -247,14 +223,12 @@ def test_decs_bare_count_pred(t : T?) { def test_order_by_reverse_take(t : T?) { t |> run("Theme 5 1b: _order_by(_).reverse().take(3) normalizes to _order_by_descending(_).take(3)") @(tt : T?) { let scores <- [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] - unsafe { - // Ascending: [1,1,2,3,3,4,5,5,5,6,9]. Reversed: [9,6,5,5,5,4,3,3,2,1,1]. Take 3: [9,6,5]. - let top3 <- _fold(each(scores)._order_by(_).reverse().take(3).to_array()) - tt |> equal(length(top3), 3) - tt |> equal(top3[0], 9) - tt |> equal(top3[1], 6) - tt |> equal(top3[2], 5) - } + // Ascending: [1,1,2,3,3,4,5,5,5,6,9]. Reversed: [9,6,5,5,5,4,3,3,2,1,1]. Take 3: [9,6,5]. + let top3 <- _fold(each(scores)._order_by(_).reverse().take(3).to_array()) + tt |> equal(length(top3), 3) + tt |> equal(top3[0], 9) + tt |> equal(top3[1], 6) + tt |> equal(top3[2], 5) } } @@ -262,14 +236,12 @@ def test_order_by_reverse_take(t : T?) { def test_order_by_descending_reverse_take(t : T?) { t |> run("Theme 5 symmetric: _order_by_descending(_).reverse().take(3) → _order_by(_).take(3)") @(tt : T?) { let scores <- [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] - unsafe { - // Descending: [9,6,5,5,5,4,3,3,2,1,1]. Reversed: ascending. Take 3: [1,1,2]. - let bottom3 <- _fold(each(scores)._order_by_descending(_).reverse().take(3).to_array()) - tt |> equal(length(bottom3), 3) - tt |> equal(bottom3[0], 1) - tt |> equal(bottom3[1], 1) - tt |> equal(bottom3[2], 2) - } + // Descending: [9,6,5,5,5,4,3,3,2,1,1]. Reversed: ascending. Take 3: [1,1,2]. + let bottom3 <- _fold(each(scores)._order_by_descending(_).reverse().take(3).to_array()) + tt |> equal(length(bottom3), 3) + tt |> equal(bottom3[0], 1) + tt |> equal(bottom3[1], 1) + tt |> equal(bottom3[2], 2) } } @@ -277,14 +249,12 @@ def test_order_by_descending_reverse_take(t : T?) { def test_double_reverse_after_order_descending(t : T?) { t |> run("Theme 5: _order_by_descending(_).reverse().reverse() cancels to _order_by_descending(_)") @(tt : T?) { let scores <- [3, 1, 4, 1, 5] - unsafe { - // After cancellation: descending [5,4,3,1,1]. - let r <- _fold(each(scores)._order_by_descending(_).reverse().reverse().to_array()) - tt |> equal(length(r), 5) - tt |> equal(r[0], 5) - tt |> equal(r[1], 4) - tt |> equal(r[2], 3) - } + // After cancellation: descending [5,4,3,1,1]. + let r <- _fold(each(scores)._order_by_descending(_).reverse().reverse().to_array()) + tt |> equal(length(r), 5) + tt |> equal(r[0], 5) + tt |> equal(r[1], 4) + tt |> equal(r[2], 3) } } @@ -297,13 +267,11 @@ def test_decs_order_by_reverse(t : T?) { let prices = [100, 500, 200, 800, 50] apply_decs_template(cmp, DecsItem(category = cats[i], price = prices[i])) } - unsafe { - // Normalized to _order_by_descending(_.price).take(2) — top 2 by price. - let top2 <- _fold(from_decs_template(type)._order_by(_.price).reverse().take(2).to_array()) - tt |> equal(length(top2), 2) - tt |> equal(top2[0].price, 800) - tt |> equal(top2[1].price, 500) - } + // Normalized to _order_by_descending(_.price).take(2) — top 2 by price. + let top2 <- _fold(from_decs_template(type)._order_by(_.price).reverse().take(2).to_array()) + tt |> equal(length(top2), 2) + tt |> equal(top2[0].price, 800) + tt |> equal(top2[1].price, 500) restart() } } diff --git a/tests/linq/test_linq_fold_theme6_decs_bridge_warn.das b/tests/linq/test_linq_fold_theme6_decs_bridge_warn.das index 24d7dd288f..279edf7cb2 100644 --- a/tests/linq/test_linq_fold_theme6_decs_bridge_warn.das +++ b/tests/linq/test_linq_fold_theme6_decs_bridge_warn.das @@ -32,11 +32,9 @@ def test_theme6_warning_fires_cascade_correct(t : T?) { // `_select(F)._skip_while(P).count()` over decs — predicate is post-projection so // `plan_decs_unroll`'s range-suffix path bails (audit chain 6a). Tier-2 cascade // emits select_to_array → skip_while → count. - unsafe { - let c = _fold(from_decs_template(type)._select(_.val)._skip_while(_ < 5).count()) - // vals are 0..19, skip while < 5 drops 5 elements, count remaining 15. - tt |> equal(c, 15) - } + let c = _fold(from_decs_template(type)._select(_.val)._skip_while(_ < 5).count()) + // vals are 0..19, skip while < 5 drops 5 elements, count remaining 15. + tt |> equal(c, 15) restart() } } diff --git a/tests/linq/test_linq_fold_theme6_decs_bridge_warn_silenced.das b/tests/linq/test_linq_fold_theme6_decs_bridge_warn_silenced.das index c1d4d16726..500d3ceeb1 100644 --- a/tests/linq/test_linq_fold_theme6_decs_bridge_warn_silenced.das +++ b/tests/linq/test_linq_fold_theme6_decs_bridge_warn_silenced.das @@ -29,10 +29,8 @@ def populate(n : int) { def test_theme6_silenced_no_warn_cascade_correct(t : T?) { t |> run("Theme 6: `_no_linq_perf_warn` suppresses warning, cascade still correct") @(tt : T?) { populate(20) - unsafe { - let c = _fold(from_decs_template(type)._select(_.val)._skip_while(_ < 5).count()) - tt |> equal(c, 15) - } + let c = _fold(from_decs_template(type)._select(_.val)._skip_while(_ < 5).count()) + tt |> equal(c, 15) restart() } } diff --git a/tests/linq/test_linq_fold_theme8_fusion_arms.das b/tests/linq/test_linq_fold_theme8_fusion_arms.das index a155e3fdaf..9ba0e02bc1 100644 --- a/tests/linq/test_linq_fold_theme8_fusion_arms.das +++ b/tests/linq/test_linq_fold_theme8_fusion_arms.das @@ -226,14 +226,12 @@ def test_c4_zip_reverse_to_array(t : T?) { var a : array; var b : array a |> push(1); a |> push(2); a |> push(3); a |> push(4) b |> push(10); b |> push(20); b |> push(30); b |> push(40) - unsafe { - let got <- _fold(each(a) |> zip(each(b)) |> reverse() |> to_array()) - tt |> equal(length(got), 4) - tt |> equal(got[0]._0, 4); tt |> equal(got[0]._1, 40) - tt |> equal(got[1]._0, 3); tt |> equal(got[1]._1, 30) - tt |> equal(got[2]._0, 2); tt |> equal(got[2]._1, 20) - tt |> equal(got[3]._0, 1); tt |> equal(got[3]._1, 10) - } + let got <- _fold(each(a) |> zip(each(b)) |> reverse() |> to_array()) + tt |> equal(length(got), 4) + tt |> equal(got[0]._0, 4); tt |> equal(got[0]._1, 40) + tt |> equal(got[1]._0, 3); tt |> equal(got[1]._1, 30) + tt |> equal(got[2]._0, 2); tt |> equal(got[2]._1, 20) + tt |> equal(got[3]._0, 1); tt |> equal(got[3]._1, 10) } } @@ -243,10 +241,8 @@ def test_c4_zip_reverse_count(t : T?) { var a <- [for (i in range(20)); i] var b <- [for (i in range(15)); i] // zip stops at shorter (15); reverse is identity for count - unsafe { - let got = _fold(each(a) |> zip(each(b)) |> reverse() |> count()) - tt |> equal(got, 15) - } + let got = _fold(each(a) |> zip(each(b)) |> reverse() |> count()) + tt |> equal(got, 15) } } @@ -257,10 +253,8 @@ def test_c4_zip_reverse_sum(t : T?) { a |> push(1); a |> push(2); a |> push(3) b |> push(10); b |> push(20); b |> push(30) // pair sums: 11, 22, 33; sum after reverse = 66 (identity) - unsafe { - let got = _fold(each(a) |> zip(each(b)) |> _select(_._0 + _._1) |> reverse() |> sum()) - tt |> equal(got, 66) - } + let got = _fold(each(a) |> zip(each(b)) |> _select(_._0 + _._1) |> reverse() |> sum()) + tt |> equal(got, 66) } } @@ -270,13 +264,11 @@ def test_c4_zip_where_reverse(t : T?) { var a <- [for (i in range(6)); i] var b <- [for (i in range(6)); i * 10] // pairs: (0,0),(1,10),(2,20),(3,30),(4,40),(5,50); where(_._0 % 2 == 0) → (0,0),(2,20),(4,40); reverse → (4,40),(2,20),(0,0) - unsafe { - let got <- _fold(each(a) |> zip(each(b)) |> _where(_._0 % 2 == 0) |> reverse() |> to_array()) - tt |> equal(length(got), 3) - tt |> equal(got[0]._0, 4); tt |> equal(got[0]._1, 40) - tt |> equal(got[1]._0, 2); tt |> equal(got[1]._1, 20) - tt |> equal(got[2]._0, 0); tt |> equal(got[2]._1, 0) - } + let got <- _fold(each(a) |> zip(each(b)) |> _where(_._0 % 2 == 0) |> reverse() |> to_array()) + tt |> equal(length(got), 3) + tt |> equal(got[0]._0, 4); tt |> equal(got[0]._1, 40) + tt |> equal(got[1]._0, 2); tt |> equal(got[1]._1, 20) + tt |> equal(got[2]._0, 0); tt |> equal(got[2]._1, 0) } } @@ -296,14 +288,12 @@ def test_c4_parity_handwritten(t : T?) { t |> run("C4-parity: spliced vs handwritten zip+reverse — 50-pair match") @(tt : T?) { var a <- [for (i in range(50)); i * 3] var b <- [for (i in range(50)); i * 5] - unsafe { - let spliced <- _fold(each(a) |> zip(each(b)) |> reverse() |> to_array()) - let hand <- theme8_c4_handwritten(a, b) - tt |> equal(length(spliced), length(hand)) - for (s, h in spliced, hand) { - tt |> equal(s._0, h._0) - tt |> equal(s._1, h._1) - } + let spliced <- _fold(each(a) |> zip(each(b)) |> reverse() |> to_array()) + let hand <- theme8_c4_handwritten(a, b) + tt |> equal(length(spliced), length(hand)) + for (s, h in spliced, hand) { + tt |> equal(s._0, h._0) + tt |> equal(s._1, h._1) } } } @@ -351,11 +341,9 @@ def test_anti_c4_zip_reverse_first_cascades(t : T?) { var a : array; var b : array a |> push(1); a |> push(2); a |> push(3) b |> push(10); b |> push(20); b |> push(30) - unsafe { - let got = _fold(each(a) |> zip(each(b)) |> reverse() |> first()) - // reverse → [(3,30),(2,20),(1,10)]; first = (3,30) - tt |> equal(got._0, 3); tt |> equal(got._1, 30) - } + let got = _fold(each(a) |> zip(each(b)) |> reverse() |> first()) + // reverse → [(3,30),(2,20),(1,10)]; first = (3,30) + tt |> equal(got._0, 3); tt |> equal(got._1, 30) } } @@ -365,11 +353,9 @@ def test_anti_c4_zip_reverse_select_cascades(t : T?) { var a : array; var b : array a |> push(1); a |> push(2); a |> push(3) b |> push(10); b |> push(20); b |> push(30) - unsafe { - let got <- _fold(each(a) |> zip(each(b)) |> reverse() |> _select(_._0 + _._1) |> to_array()) - tt |> equal(length(got), 3) - tt |> equal(got[0], 33); tt |> equal(got[1], 22); tt |> equal(got[2], 11) - } + let got <- _fold(each(a) |> zip(each(b)) |> reverse() |> _select(_._0 + _._1) |> to_array()) + tt |> equal(length(got), 3) + tt |> equal(got[0], 33); tt |> equal(got[1], 22); tt |> equal(got[2], 11) } } diff --git a/tests/linq/test_linq_from_decs.das b/tests/linq/test_linq_from_decs.das index 033a6300fd..e806f3c563 100644 --- a/tests/linq/test_linq_from_decs.das +++ b/tests/linq/test_linq_from_decs.das @@ -3719,14 +3719,12 @@ def test_decs_unknown_terminator_cascades(t : T?) { } commit() t |> run("min_max family over decs returns tuples, not the element array") @(t : T?) { - unsafe { - let mm = _fold(from_decs_template(type)._select(_.v) |> min_max()) - t |> equal(mm._0, 10) - t |> equal(mm._1, 14) - let mma = _fold(from_decs_template(type)._select(_.v) |> min_max_average()) - t |> equal(mma._0, 10) - t |> equal(mma._1, 14) - t |> equal(mma._2, 12) - } + let mm = _fold(from_decs_template(type)._select(_.v) |> min_max()) + t |> equal(mm._0, 10) + t |> equal(mm._1, 14) + let mma = _fold(from_decs_template(type)._select(_.v) |> min_max_average()) + t |> equal(mma._0, 10) + t |> equal(mma._1, 14) + t |> equal(mma._2, 12) } } diff --git a/tests/linq/test_linq_table_source.das b/tests/linq/test_linq_table_source.das index 1211735cba..d24dbc8eac 100644 --- a/tests/linq/test_linq_table_source.das +++ b/tests/linq/test_linq_table_source.das @@ -765,14 +765,12 @@ def test_table_group_by(t : T?) { // nolint:STYLE038 flat list of independent ru def test_table_kv_positional_fields(t : T?) { t |> run("each_kv chains accept positional _0/_1 access") @(tt : T?) { var tab <- { 1 => 10, 2 => 20, 3 => 30 } - unsafe { - let s = _fold(each_kv(tab)._select(_._1) |> sum()) - tt |> equal(s, 60) - let ks = _fold(each_kv(tab)._select(_._0) |> sum()) - tt |> equal(ks, 6) - let mixed = _fold(each_kv(tab)._select(_._0 * 100 + _._1) |> sum()) - tt |> equal(mixed, 660) - } + let s = _fold(each_kv(tab)._select(_._1) |> sum()) + tt |> equal(s, 60) + let ks = _fold(each_kv(tab)._select(_._0) |> sum()) + tt |> equal(ks, 6) + let mixed = _fold(each_kv(tab)._select(_._0 * 100 + _._1) |> sum()) + tt |> equal(mixed, 660) } } @@ -789,10 +787,8 @@ def test_user_keys_overload_not_hijacked(t : T?) { plainCount ++ } tt |> equal(plainCount, 1) - unsafe { - let n = _fold(keys(tab) |> count()) - tt |> equal(n, 1) - } + let n = _fold(keys(tab) |> count()) + tt |> equal(n, 1) } } @@ -801,14 +797,12 @@ def test_join_probe_kv_positional_fields(t : T?) { t |> run("a table srcB joined on its key accepts positional _1 in the result") @(tt : T?) { var tab <- { 1 => 100, 2 => 200 } let leads = [1, 2, 2] - unsafe { - let rows <- _fold(each(leads) - |> _join(each_kv(tab), $(l, d) => l == d.key, $(l, d) => l * 1000 + d._1) - |> to_array()) - tt |> equal(length(rows), 3) - tt |> equal(rows[0], 1100) - tt |> equal(rows[1], 2200) - tt |> equal(rows[2], 2200) - } + let rows <- _fold(each(leads) + |> _join(each_kv(tab), $(l, d) => l == d.key, $(l, d) => l * 1000 + d._1) + |> to_array()) + tt |> equal(length(rows), 3) + tt |> equal(rows[0], 1100) + tt |> equal(rows[1], 2200) + tt |> equal(rows[2], 2200) } } diff --git a/tests/long_array_table/test_dim_int64_indexing.das b/tests/long_array_table/test_dim_int64_indexing.das index be0a2802bd..8ee2dc2a22 100644 --- a/tests/long_array_table/test_dim_int64_indexing.das +++ b/tests/long_array_table/test_dim_int64_indexing.das @@ -136,18 +136,11 @@ def test_dim_i64_safe_at(t : T?) { let good : int64 = 3_l let bad : int64 = 99_l let neg : int64 = -1_l - var val : int - unsafe { - val = arr?[good] ?? -1 - } + var val = arr?[good] ?? -1 t |> equal(val, 30) - unsafe { - val = arr?[bad] ?? -1 - } + val = arr?[bad] ?? -1 t |> equal(val, -1) - unsafe { - val = arr?[neg] ?? -1 - } + val = arr?[neg] ?? -1 t |> equal(val, -1) } @@ -159,13 +152,8 @@ def test_dim_u64_safe_at(t : T?) { } let good : uint64 = 4_ul let bad : uint64 = 100_ul - var val : int - unsafe { - val = arr?[good] ?? -1 - } + var val = arr?[good] ?? -1 t |> equal(val, 40) - unsafe { - val = arr?[bad] ?? -1 - } + val = arr?[bad] ?? -1 t |> equal(val, -1) } diff --git a/tests/long_array_table/test_huge_array_iterate.das b/tests/long_array_table/test_huge_array_iterate.das index 58b8ffde1c..de4958ea81 100644 --- a/tests/long_array_table/test_huge_array_iterate.das +++ b/tests/long_array_table/test_huge_array_iterate.das @@ -76,11 +76,9 @@ def test_iterate_via_long_enumerate(t : T?) { arr |> resize(HUGE_N) var last_index = -1_l var count = 0_l - unsafe { - for ((i, _v) in long_enumerate(each(arr))) { - last_index = i - count++ - } + for ((i, _v) in long_enumerate(unsafe(each(arr)))) { + last_index = i + count++ } t |> equal(count, HUGE_N) t |> equal(last_index, HUGE_N - 1_l) diff --git a/tests/long_array_table/test_huge_temp_array.das b/tests/long_array_table/test_huge_temp_array.das index 019ff06676..a1d864e02a 100644 --- a/tests/long_array_table/test_huge_temp_array.das +++ b/tests/long_array_table/test_huge_temp_array.das @@ -34,12 +34,10 @@ def test_temp_array_arr_huge(t : T?) { arr |> resize(HUGE_N) arr[0_l] = uint8(0xC0) arr[HUGE_N - 1_l] = uint8(0xDE) - unsafe { - let view <- temp_array(arr) - t |> equal(long_length(view), HUGE_N) - t |> equal(view[0_l], uint8(0xC0)) - t |> equal(view[HUGE_N - 1_l], uint8(0xDE)) - } + let view <- unsafe(temp_array(arr)) + t |> equal(long_length(view), HUGE_N) + t |> equal(view[0_l], uint8(0xC0)) + t |> equal(view[HUGE_N - 1_l], uint8(0xDE)) delete arr } diff --git a/tests/long_array_table/test_long_iterators.das b/tests/long_array_table/test_long_iterators.das index 311c4cb070..7ba4d38dd7 100644 --- a/tests/long_array_table/test_long_iterators.das +++ b/tests/long_array_table/test_long_iterators.das @@ -26,11 +26,9 @@ def test_long_enumerate(t : T?) { arr[3] = 40 var sum_idx = 0_l var sum_val = 0 - unsafe { - for ((i, v) in long_enumerate(each(arr))) { - sum_idx += i - sum_val += v - } + for ((i, v) in long_enumerate(unsafe(each(arr)))) { + sum_idx += i + sum_val += v } t |> equal(sum_idx, 0_l + 1_l + 2_l + 3_l) t |> equal(sum_val, 100) diff --git a/tests/match/all_matches.das b/tests/match/all_matches.das index 4db9bf4d8a..5ae876c207 100644 --- a/tests/match/all_matches.das +++ b/tests/match/all_matches.das @@ -435,9 +435,7 @@ def match_copy(var cmdm : CmdLocate; cmd : Cmd) { if (cmd.rtti != "CmdLocate") { return false } - unsafe { - cmdm = reinterpret(cmd) - } + cmdm = unsafe(reinterpret(cmd)) return true } diff --git a/tests/math/mat_let_handle.das b/tests/math/mat_let_handle.das index 6edda74d15..e92b8b5cfb 100644 --- a/tests/math/mat_let_handle.das +++ b/tests/math/mat_let_handle.das @@ -59,8 +59,6 @@ def get_col3(s : S?&) : float3 { def test_mat_field_idx_through_ptr(t : T?) { var s : S s.m[3] = float3(1.0, 2.0, 3.0) - unsafe { - var p : S? = addr(s) - t |> equal(get_col3(p), float3(1.0, 2.0, 3.0)) - } + var p : S? = unsafe(addr(s)) + t |> equal(get_col3(p), float3(1.0, 2.0, 3.0)) } diff --git a/tests/mcp/test_mcp_jsonrpc.das b/tests/mcp/test_mcp_jsonrpc.das index 379d534a13..bc36efa388 100644 --- a/tests/mcp/test_mcp_jsonrpc.das +++ b/tests/mcp/test_mcp_jsonrpc.das @@ -55,20 +55,17 @@ def private read_complete_line(stdout_r : FILE const?) : string { def run_mcp_session(requests : array; var responses : array) : int { let exe = get_das_exe() let script = mcp_script() - var rc : int - unsafe { - rc = popen_argv_pipe([exe, script]) $(stdin_w, stdout_r) { - return if (stdin_w == null || stdout_r == null) - for (req in requests) { - fprint(stdin_w, "{req}\n") - fflush(stdin_w) - let line = read_complete_line(stdout_r) - if (!empty(line)) { - responses |> push(line) - } + let rc = unsafe(popen_argv_pipe([exe, script]) $(stdin_w, stdout_r) { + return if (stdin_w == null || stdout_r == null) + for (req in requests) { + fprint(stdin_w, "{req}\n") + fflush(stdin_w) + let line = read_complete_line(stdout_r) + if (!empty(line)) { + responses |> push(line) } } - } + }) return rc } diff --git a/tests/mcp/test_popen_argv_pipe.das b/tests/mcp/test_popen_argv_pipe.das index 46d07a6778..8656542164 100644 --- a/tests/mcp/test_popen_argv_pipe.das +++ b/tests/mcp/test_popen_argv_pipe.das @@ -21,20 +21,17 @@ def test_echo_roundtrip(t : T?) { let exe = get_das_exe() let echo = fixture_path("_fixture_echo.das") var responses : array - var rc : int - unsafe { - rc = popen_argv_pipe([exe, "-dasroot", get_das_root(), echo]) $(stdin_w, stdout_r) { - return if (stdin_w == null || stdout_r == null) - fprint(stdin_w, "hello\n") - fflush(stdin_w) - let l1 = fgets(stdout_r) - responses |> push(clone_string(l1)) - fprint(stdin_w, "world\n") - fflush(stdin_w) - let l2 = fgets(stdout_r) - responses |> push(clone_string(l2)) - } - } + let rc = unsafe(popen_argv_pipe([exe, "-dasroot", get_das_root(), echo]) $(stdin_w, stdout_r) { + return if (stdin_w == null || stdout_r == null) + fprint(stdin_w, "hello\n") + fflush(stdin_w) + let l1 = fgets(stdout_r) + responses |> push(clone_string(l1)) + fprint(stdin_w, "world\n") + fflush(stdin_w) + let l2 = fgets(stdout_r) + responses |> push(clone_string(l2)) + }) t |> equal(rc, 0, "subprocess exit code") t |> equal(length(responses), 2) return if (length(responses) != 2) @@ -49,14 +46,11 @@ def test_exit_code_propagated(t : T?) { t |> run("subprocess exit code returned to caller") @(t : T?) { let exe = get_das_exe() let exit_script = fixture_path("_fixture_exit.das") - var rc : int - unsafe { - rc = popen_argv_pipe([exe, "-dasroot", get_das_root(), exit_script]) $(stdin_w, stdout_r) { - // No I/O. Block returns immediately; parent closes pipes, - // waits for the child (which returns 7), captures exit code. - pass - } - } + let rc = unsafe(popen_argv_pipe([exe, "-dasroot", get_das_root(), exit_script]) $(stdin_w, stdout_r) { + // No I/O. Block returns immediately; parent closes pipes, + // waits for the child (which returns 7), captures exit code. + pass + }) t |> equal(rc, 7) } } @@ -69,12 +63,9 @@ def test_stdin_eof_after_block(t : T?) { // Don't write anything — block returns, stdin closes, echo loop // sees feof, exits with 0. Verifies the parent-side close-stdin // path doesn't leave the child hanging. - var rc : int - unsafe { - rc = popen_argv_pipe([exe, "-dasroot", get_das_root(), echo]) $(stdin_w, stdout_r) { - pass - } - } + let rc = unsafe(popen_argv_pipe([exe, "-dasroot", get_das_root(), echo]) $(stdin_w, stdout_r) { + pass + }) t |> equal(rc, 0) } } diff --git a/tests/module_tests/test_modules.das b/tests/module_tests/test_modules.das index eaf20a8aab..757ae0dde5 100644 --- a/tests/module_tests/test_modules.das +++ b/tests/module_tests/test_modules.das @@ -57,9 +57,7 @@ def run_module_test(base_path, main_file : string; use_project : bool) : bool { if (!sok) { return } - unsafe { - invoke_in_context(context, "test") - } + unsafe(invoke_in_context(context, "test")) result = true } } @@ -127,9 +125,7 @@ def run_module_test_option_ignored(base_path, main_file, ignored_opt, applied_op if (!sok) { return } - unsafe { - invoke_in_context(context, "test") - } + unsafe(invoke_in_context(context, "test")) result = true } } diff --git a/tests/network/test_client.das b/tests/network/test_client.das index 7a05fda808..28ac28c71b 100644 --- a/tests/network/test_client.das +++ b/tests/network/test_client.das @@ -23,10 +23,8 @@ class private Echo : Server { pass } def override onData(buf : uint8?; size : int) { - unsafe { - for (i in range(size)) { - got = "{got}{to_char(int(buf[i]))}" - } + for (i in range(size)) { + got = "{got}{to_char(int(unsafe(buf[i])))}" } send(buf, size) } @@ -52,10 +50,8 @@ class private Peer : Client { disconnects++ } def override onData(buf : uint8?; size : int) { - unsafe { - for (i in range(size)) { - got = "{got}{to_char(int(buf[i]))}" - } + for (i in range(size)) { + got = "{got}{to_char(int(unsafe(buf[i])))}" } } def override onError(msg : string; code : int) { diff --git a/tests/stbimage/test_apng.das b/tests/stbimage/test_apng.das index e8e9fa3d30..cffc8afeb3 100644 --- a/tests/stbimage/test_apng.das +++ b/tests/stbimage/test_apng.das @@ -107,10 +107,7 @@ def test_apng_basic(t : T?) { for (frame in range(4)) { var pixels : array make_gradient_frame(pixels, W, H, frame) - var ok : int - unsafe { - ok = stbi_apng_frame(writer, addr(pixels[0]), W * 4, 100) - } + let ok = stbi_apng_frame(writer, unsafe(addr(pixels[0])), W * 4, 100) tt |> equal(ok, 1) } let end_ok = stbi_apng_end(writer) @@ -200,9 +197,7 @@ def test_apng_drop_accounting(t : T?) { } // Submit 40 frames as fast as possible — queue cap is 4, so we expect drops. for (_i in range(40)) { - unsafe { - stbi_apng_frame(writer, addr(pixels[0]), W * 4, 33) - } + stbi_apng_frame(writer, unsafe(addr(pixels[0])), W * 4, 33) } let dropped_before_end = stbi_apng_dropped(writer) let end_ok = stbi_apng_end(writer) @@ -285,16 +280,12 @@ def test_apng_dropped_zero_when_keeping_up(t : T?) { var pixels : array pixels |> resize(W * H * 4) for (_frame in range(3)) { - unsafe { - stbi_apng_frame(writer, addr(pixels[0]), W * 4, 100) - } + stbi_apng_frame(writer, unsafe(addr(pixels[0])), W * 4, 100) sleep(50u) // ms — give worker time to drain } let dropped = stbi_apng_dropped(writer) tt |> equal(dropped, 0) - unsafe { - stbi_apng_end(writer) - } + stbi_apng_end(writer) remove(fname) } } diff --git a/tests/strings/delete_strings.das b/tests/strings/delete_strings.das index e363055c0a..494bbf53a2 100644 --- a/tests/strings/delete_strings.das +++ b/tests/strings/delete_strings.das @@ -6,23 +6,23 @@ require daslib/random [test] def test_delete_string(t : T?) { var constStr = "123" - unsafe { - let removed = delete_string(constStr) + { + let removed = unsafe(delete_string(constStr)) t.equal(removed, false) // const heap string should not be removed t.equal(constStr, "123") } var seed = random_seed(0) var str = "test{random_float(seed)}" - unsafe { - let removed = delete_string(str) + { + let removed = unsafe(delete_string(str)) t.equal(removed, true) // heap string should be removed t.equal(str, "") } - unsafe { + { var emptyStr : string - let removed = delete_string(emptyStr) + let removed = unsafe(delete_string(emptyStr)) t.equal(removed, false) // corner case: empty string should not be removed t.equal(emptyStr, "") } @@ -32,16 +32,16 @@ def test_delete_string(t : T?) { [test] def test_delete_temp_string(t : T?) { var tempString = unsafe(reinterpret("123")) - unsafe { - let removed = delete_string(tempString) + { + let removed = unsafe(delete_string(tempString)) t.equal(removed, false) // const string should not be removed t.equal(tempString, "123") } var seed = random_seed(0) var tempString2 = unsafe(reinterpret("test{random_float(seed)}")) - unsafe { - let removed = delete_string(tempString2) + { + let removed = unsafe(delete_string(tempString2)) t.equal(removed, true) // heap string should be removed t.equal(tempString2, "") // temp string should be empty after removal } diff --git a/tests/table_packed/test_packed.das b/tests/table_packed/test_packed.das index e9750eb6f4..1e48c895bd 100644 --- a/tests/table_packed/test_packed.das +++ b/tests/table_packed/test_packed.das @@ -44,7 +44,7 @@ def test_packed_int_basic(t : T?) { t |> equal(key_exists(tab, 3), true) t |> equal(key_exists(tab, 99), false) check_keys(t, tab, [0, 1, 2, 3, 4, 5]) - unsafe { delete tab; } + delete tab } [test] @@ -58,7 +58,7 @@ def test_packed_string(t : T?) { } t |> equal(tab?[dkey("k", 99)] ?? -1, -1) t |> equal(key_exists(tab, dkey("k", 2)), true) - unsafe { delete tab; } + delete tab } // "k1832" and "k16303" share the same 32-bit table hashKey (0xf9102e8c) but are different @@ -76,7 +76,7 @@ def test_packed_string_hashkey32_collision(t : T?) { t |> equal(key_exists(tab, kcopy(1832)), true) t |> equal(key_exists(tab, kcopy(16303)), true) t |> equal(tab?[kcopy(9999)] ?? -1, -1) - unsafe { delete tab; } + delete tab } // False-positive guard: a single-entry packed table whose only key shares a 32-bit hashKey with @@ -89,7 +89,7 @@ def test_packed_string_hashkey32_miss(t : T?) { t |> equal(tab?[kcopy(16303)] ?? -777, -777) // 32-bit hashKey clash, distinct 64-bit hash -> miss t |> equal(key_exists(tab, kcopy(16303)), false) t |> equal(tab?[kcopy(1832)] ?? -1, 111) // the real key still hits - unsafe { delete tab; } + delete tab } [test] @@ -104,7 +104,7 @@ def test_packed_promote(t : T?) { t |> equal(tab?[i] ?? -1, i * 10) } t |> equal(tab?[100] ?? -1, -1) - unsafe { delete tab; } + delete tab } [test] @@ -126,7 +126,7 @@ def test_packed_erase_swap(t : T?) { t |> equal(key_exists(tab, 2), false) t |> equal(key_exists(tab, 5), false) check_keys(t, tab, [1, 3, 4]) - unsafe { delete tab; } + delete tab } [test] @@ -142,7 +142,7 @@ def test_packed_erase_reinsert(t : T?) { t |> equal(tab?[10] ?? -1, 100) t |> equal(tab?[1] ?? -1, -1) check_keys(t, tab, [0, 2, 3, 10]) - unsafe { delete tab; } + delete tab } [test] @@ -159,7 +159,7 @@ def test_packed_grow_then_shrink(t : T?) { t |> equal(tab?[18] ?? -1, 18) t |> equal(tab?[19] ?? -1, 19) t |> equal(key_exists(tab, 0), false) - unsafe { delete tab; } + delete tab } struct PackVal { @@ -191,5 +191,5 @@ def test_packed_struct_value(t : T?) { t |> equal(v4.c, 12) } t |> equal(key_exists(tab, 2), false) - unsafe { delete tab; } + delete tab } diff --git a/tests/table_packed/test_packed_constkey.das b/tests/table_packed/test_packed_constkey.das index 9f846b9ad6..56b4be7c68 100644 --- a/tests/table_packed/test_packed_constkey.das +++ b/tests/table_packed/test_packed_constkey.das @@ -21,7 +21,7 @@ def test_constkey_index(t : T?) { tab["foo"] = 11 // overwrite, no new slot t |> equal(tab["foo"], 11) t |> equal(length(tab), 3) - unsafe { delete tab; } + delete tab } [test] @@ -33,7 +33,7 @@ def test_constkey_safe_index(t : T?) { t |> equal(tab?["bar"] ?? -1, 2) t |> equal(tab?["missing"] ?? -1, -1) // SafeTableIndex_WithHash (miss, no insert) t |> equal(length(tab), 2) // safe-index miss did not grow the table - unsafe { delete tab; } + delete tab } [test] @@ -44,7 +44,7 @@ def test_constkey_builtin_key_exists(t : T?) { t |> equal(__builtin_table_key_exists(tab, "foo"), true) // KeyExists_WithHash (hit) t |> equal(__builtin_table_key_exists(tab, "bar"), true) t |> equal(__builtin_table_key_exists(tab, "missing"), false) // KeyExists_WithHash (miss) - unsafe { delete tab; } + delete tab } [test] @@ -59,7 +59,7 @@ def test_constkey_builtin_find(t : T?) { } let pm = __builtin_table_find(tab, "missing") // TableFind_WithHash (miss) t |> equal(pm == null, true) - unsafe { delete tab; } + delete tab } // "k1832" and "k16303" share the same 32-bit table hashKey but differ in the full 64-bit hash. @@ -77,5 +77,5 @@ def test_constkey_hashkey32_collision(t : T?) { t |> equal(__builtin_table_key_exists(tab, "k1832"), true) t |> equal(__builtin_table_key_exists(tab, "k16303"), true) t |> equal(tab?["k9999"] ?? -1, -1) - unsafe { delete tab; } + delete tab } diff --git a/tests/table_packed/test_packed_large.das b/tests/table_packed/test_packed_large.das index 36f3e665f1..bd4daf6dde 100644 --- a/tests/table_packed/test_packed_large.das +++ b/tests/table_packed/test_packed_large.das @@ -48,7 +48,7 @@ def test_large_int_hit_miss(t : T?) { var expected <- [for (i in range(40)); i] check_int_keys(t, tab, expected) delete expected - unsafe { delete tab; } + delete tab } [test] @@ -82,7 +82,7 @@ def test_large_int_erase_tombstone(t : T?) { t |> equal(tab?[i] ?? -1, want) } t |> equal(length(tab), 40) - unsafe { delete tab; } + delete tab } [test] @@ -98,7 +98,7 @@ def test_large_int_grow_rehash(t : T?) { t |> equal(tab?[i] ?? -1, i * 2) } t |> equal(tab?[300] ?? -1, -1) - unsafe { delete tab; } + delete tab } [test] @@ -124,7 +124,7 @@ def test_large_int_churn(t : T?) { t |> equal(tab?[i] ?? -1, lastRound * 1000 + i) } } - unsafe { delete tab; } + delete tab } [test] @@ -148,7 +148,7 @@ def test_large_string(t : T?) { t |> equal(tab?[dkey(1000)] ?? -1, 7000) t |> equal(tab?[dkey(13)] ?? -1, -1) t |> equal(tab?[dkey(0)] ?? -1, 0) - unsafe { delete tab; } + delete tab } struct LargeVal { @@ -176,7 +176,7 @@ def test_large_struct_value(t : T?) { } t |> equal(key_exists(tab, 10), false) t |> equal(length(tab), 38) - unsafe { delete tab; } + delete tab } [test] @@ -193,7 +193,7 @@ def test_promote_packed_to_large(t : T?) { for (i in range(9)) { t |> equal(tab?[i] ?? -1, i * 100) } - unsafe { delete tab; } + delete tab } [test] @@ -220,5 +220,5 @@ def test_keys_iter_packed_no_overread(t : T?) { n2++ } t |> equal(n2, 0) - unsafe { delete tab; } + delete tab } diff --git a/tests/type_traits/test_iterator_variance.das b/tests/type_traits/test_iterator_variance.das index a6f1fb2697..8326a427b6 100644 --- a/tests/type_traits/test_iterator_variance.das +++ b/tests/type_traits/test_iterator_variance.das @@ -36,10 +36,8 @@ def test_mut_iter_flows_into_const_param(t : T?) { // each(array) yields iterator (mut element). Passing it into a // function expecting iterator should succeed via variance. let arr <- [1, 2, 3, 4, 5] - unsafe { - let total = sum_const_iter(each(arr)) - t |> equal(15, total) - } + let total = sum_const_iter(unsafe(each(arr))) + t |> equal(15, total) } [test] diff --git a/tutorials/dasPUGIXML/05_linq_over_xml.das b/tutorials/dasPUGIXML/05_linq_over_xml.das index 99aa6c84ab..1d6765f328 100644 --- a/tutorials/dasPUGIXML/05_linq_over_xml.das +++ b/tutorials/dasPUGIXML/05_linq_over_xml.das @@ -122,13 +122,11 @@ def reverse_iteration() { print("\n") // Fused _fold reverse: the last two cars, reversed, as typed rows — the // macro walks backward and stops after 2, never touching cars #1/#2. - unsafe { - let last_two <- _fold(from_xml_node(doc.document_element, type).reverse().take(2).to_array()) - print(" last 2 (reversed): {[for (c in last_two); c.make]}\n") - // reverse |> take(1) is the last car in a single backward step. - let newest <- _fold(from_xml_node(doc.document_element, type).reverse().take(1).to_array()) - print(" last car: #{newest[0].id} {newest[0].make}\n") - } + let last_two <- _fold(from_xml_node(doc.document_element, type).reverse().take(2).to_array()) + print(" last 2 (reversed): {[for (c in last_two); c.make]}\n") + // reverse |> take(1) is the last car in a single backward step. + let newest <- _fold(from_xml_node(doc.document_element, type).reverse().take(1).to_array()) + print(" last car: #{newest[0].id} {newest[0].make}\n") } } diff --git a/tutorials/language/22_unsafe.das b/tutorials/language/22_unsafe.das index 11d2bbd0b9..fa2f1cf841 100644 --- a/tutorials/language/22_unsafe.das +++ b/tutorials/language/22_unsafe.das @@ -22,8 +22,8 @@ def main { // nolint:STYLE038 - tutorial walkthrough, the sequence IS the less print("addr:\n") var x = 42 - unsafe { - var p = addr(x) // p is int? + { + var p = unsafe(addr(x)) // p is int? print(" *p = {*p}\n") // Modify through pointer @@ -36,9 +36,9 @@ def main { // nolint:STYLE038 - tutorial walkthrough, the sequence IS the less // deref(p) is the same as *p. print("deref:\n") - unsafe { + { var y = 7 - var p = addr(y) + var p = unsafe(addr(y)) print(" *p = {*p}\n") print(" deref(p) = {deref(p)}\n") } @@ -46,9 +46,7 @@ def main { // nolint:STYLE038 - tutorial walkthrough, the sequence IS the less // Null pointer dereference panics (can be caught with try/recover): try { var p : int? // null pointer - unsafe { - print(" {*p}\n") // panics - } + print(" {*p}\n") // panics } recover { print(" caught null dereference\n") } @@ -57,9 +55,9 @@ def main { // nolint:STYLE038 - tutorial walkthrough, the sequence IS the less // Pointers are nullable. Check with != null or ??. print("null check:\n") - unsafe { + { var a = 42 - var p = addr(a) + var p = unsafe(addr(a)) var q : int? // null if (p != null) { @@ -102,9 +100,7 @@ def main { // nolint:STYLE038 - tutorial walkthrough, the sequence IS the less print("unsafe expression:\n") var z = 99 let ptr = unsafe(addr(z)) - unsafe { - print(" unsafe(addr(z)) = {*ptr}\n") - } + print(" unsafe(addr(z)) = {*ptr}\n") // === addr — typed address-of === // addr(x) is sugar for reinterpret(addr(x)): take the address, @@ -114,9 +110,7 @@ def main { // nolint:STYLE038 - tutorial walkthrough, the sequence IS the less print("addr:\n") var w = 1.0 let bits = unsafe(addr(w)) - unsafe { - print(" 1.0 bits via addr: 0x{*bits:08x}\n") // same 0x3f800000 - } + print(" 1.0 bits via addr: 0x{*bits:08x}\n") // same 0x3f800000 // === When unsafe is required === // diff --git a/tutorials/language/36_pointers.das b/tutorials/language/36_pointers.das index a506d0892d..3983d712a1 100644 --- a/tutorials/language/36_pointers.das +++ b/tutorials/language/36_pointers.das @@ -72,11 +72,9 @@ def main() { // nolint:STYLE038 - tutorial walkthrough, the sequence IS the le // when it goes out of scope. No manual delete needed. print("=== var inscope ===\n") - unsafe { - var inscope pt = new Point(x = 1.0, y = 2.0) - print(" pt.x = {pt.x}, pt.y = {pt.y}\n") - // pt is automatically deleted at end of scope - } + var inscope pt = new Point(x = 1.0, y = 2.0) + print(" pt.x = {pt.x}, pt.y = {pt.y}\n") + // pt is automatically deleted at end of scope // === addr() — pointer to existing variable === // @@ -85,12 +83,10 @@ def main() { // nolint:STYLE038 - tutorial walkthrough, the sequence IS the le print("=== addr ===\n") var a = 42 - unsafe { - var pa = addr(a) // pa is int? - print(" *pa = {*pa}\n") - *pa = 100 // modify through pointer - print(" a = {a}\n") // a is now 100 - } + var pa = unsafe(addr(a)) // pa is int? + print(" *pa = {*pa}\n") + *pa = 100 // modify through pointer + print(" a = {a}\n") // a is now 100 // === safe_addr() — without unsafe === // @@ -108,12 +104,10 @@ def main() { // nolint:STYLE038 - tutorial walkthrough, the sequence IS the le // They panic if the pointer is null. print("=== deref ===\n") - unsafe { - var c = 5 - var pc = addr(c) - print(" *pc = {*pc}\n") - print(" deref(pc) = {deref(pc)}\n") - } + var c = 5 + var pc = unsafe(addr(c)) + print(" *pc = {*pc}\n") + print(" deref(pc) = {deref(pc)}\n") // For struct pointers, field access auto-dereferences: // p.x is the same as (*p).x @@ -130,9 +124,7 @@ def main() { // nolint:STYLE038 - tutorial walkthrough, the sequence IS the le // Catch null dereference with try/recover: try { - unsafe { - print(" {*np}\n") // panics — np is null - } + print(" {*np}\n") // panics — np is null } recover { print(" caught null deref\n") } @@ -160,9 +152,7 @@ def main() { // nolint:STYLE038 - tutorial walkthrough, the sequence IS the le print(" after move: pt2.x = {pt2.x}, pt2.y = {pt2.y}\n") var val = 21 - unsafe { - double_value(addr(val)) - } + double_value(unsafe(addr(val))) print(" after double: val = {val}\n") // === Pointer arithmetic (unsafe) === @@ -210,12 +200,10 @@ def main() { // nolint:STYLE038 - tutorial walkthrough, the sequence IS the le print("=== intptr ===\n") var e = 42 - unsafe { - var pe = addr(e) - let address = intptr(pe) - print(" address != 0: {address != uint64(0)}\n") - print(" same pointer: {intptr(pe) == address}\n") - } + var pe = unsafe(addr(e)) + let address = intptr(pe) + print(" address != 0: {address != uint64(0)}\n") + print(" same pointer: {intptr(pe) == address}\n") // === reinterpret — raw bit cast === // diff --git a/tutorials/language/44_compile_and_run.das b/tutorials/language/44_compile_and_run.das index 3031cbfd9f..46e57e5762 100644 --- a/tutorials/language/44_compile_and_run.das +++ b/tutorials/language/44_compile_and_run.das @@ -58,9 +58,7 @@ def hello() \{ print("simulate error: {serrors}\n") return } - unsafe { - invoke_in_context(context, "hello") - } + unsafe(invoke_in_context(context, "hello")) } } } @@ -92,9 +90,7 @@ def compile_from_file() { return } // Call "main" in the child context - unsafe { - invoke_in_context(context, "main") - } + unsafe(invoke_in_context(context, "main")) } } } @@ -134,9 +130,7 @@ def greet(name : string) \{ print("simulate error: {serrors}\n") return } - unsafe { - invoke_in_context(context, "greet", "World") - } + unsafe(invoke_in_context(context, "greet", "World")) } } } @@ -180,9 +174,7 @@ def sum3(a, b, c : int) \{ if (!has_function(*context, "nonexistent")) { print(" has_function(\"nonexistent\") = false\n") } - unsafe { - invoke_in_context(context, "sum3", 10, 20, 30) - } + unsafe(invoke_in_context(context, "sum3", 10, 20, 30)) } } } @@ -219,9 +211,7 @@ def read_global_variable() { return } // Call compute(7) — sets global `result` to 7*7+1 = 50 - unsafe { - invoke_in_context(context, "compute", 7) - } + unsafe(invoke_in_context(context, "compute", 7)) // Read back the global variable "result" let ptr = unsafe(get_context_global_variable(context, "result")) if (ptr != null) { @@ -334,9 +324,7 @@ def produce(var ch : Channel?) \{ } // Create a channel, pass it to the child, drain results with_channel(1) $(ch) { - unsafe { - invoke_in_context(context, "produce", ch) - } + unsafe(invoke_in_context(context, "produce", ch)) ch |> for_each_clone() $(val : IntResult#) { print(" channel received: {val.value}\n") } @@ -396,9 +384,7 @@ def crash() \{ return } try { - unsafe { - invoke_in_context(context, "crash") - } + unsafe(invoke_in_context(context, "crash")) } recover { print(" runtime error caught (expected)\n") } diff --git a/tutorials/language/44_helper.das b/tutorials/language/44_helper.das index e84d5b95b2..8db577c115 100644 --- a/tutorials/language/44_helper.das +++ b/tutorials/language/44_helper.das @@ -16,9 +16,7 @@ def compute(x : int) { [export] def store_via_ptr(val : int; var dst : int?) { - unsafe { - *dst = val * 10 - } + *dst = val * 10 } [export] diff --git a/tutorials/language/45_debug_agents.das b/tutorials/language/45_debug_agents.das index 4d2a3ccd33..f1951af39a 100644 --- a/tutorials/language/45_debug_agents.das +++ b/tutorials/language/45_debug_agents.das @@ -103,9 +103,7 @@ def install_log_agent(ctx : Context) { [export, pinvoke] def read_log_count(var result : int?) { - unsafe { - *result = log_intercept_count - } + *result = log_intercept_count } def demo_on_log() { @@ -156,9 +154,7 @@ def agent_increment() { [export, pinvoke] def agent_get(var result : int?) { - unsafe { - *result = agent_counter - } + *result = agent_counter } def demo_invoke_in_context() { @@ -201,9 +197,7 @@ class CalcAgent : DapiDebugAgent { self.accumulator += amount } def get_result(var result : int?) { - unsafe { - *result = self.accumulator - } + *result = self.accumulator } } @@ -264,10 +258,8 @@ class StateAgent : DapiDebugAgent { } // onVariable is called for each variable reported above def override onVariable(var ctx : Context; category, name : string; info : TypeInfo; data : void?) : void { - unsafe { - let value = sprint_data(data, addr(info), print_flags.singleLine) - print(" {category}: {name} = {value}\n") - } + let value = sprint_data(data, unsafe(addr(info)), print_flags.singleLine) + print(" {category}: {name} = {value}\n") } } @@ -409,9 +401,7 @@ def add_data(amount : int) { [export, pinvoke] def get_data(var result : int?) { - unsafe { - *result = shared_data - } + *result = shared_data } [unused_argument(ctx)] @@ -471,9 +461,7 @@ class ThreadLocalAgent : DapiDebugAgent { self.value = val } def get_value(var result : int?) { - unsafe { - *result = self.value - } + *result = self.value } } @@ -487,9 +475,7 @@ def demo_thread_local_agent() { fork_debug_agent_context(@@install_thread_local_agent) // Use "" (empty string) to target the thread-local agent - unsafe { - invoke_debug_agent_method("", "set_value", 42) - } + unsafe(invoke_debug_agent_method("", "set_value", 42)) var result = 0 unsafe { diff --git a/tutorials/language/47_data_walker.das b/tutorials/language/47_data_walker.das index 6872af558d..60e4216a06 100644 --- a/tutorials/language/47_data_walker.das +++ b/tutorials/language/47_data_walker.das @@ -65,27 +65,19 @@ def demo_scalar_types() { // typeinfo rtti_typeinfo(var) returns the TypeInfo for any variable var x = 42 print("Walking int 42:\n") - unsafe { - adapter |> walk_data(addr(x), typeinfo rtti_typeinfo(x)) - } + adapter |> walk_data(unsafe(addr(x)), typeinfo rtti_typeinfo(x)) var f = 3.14 print("Walking float 3.14:\n") - unsafe { - adapter |> walk_data(addr(f), typeinfo rtti_typeinfo(f)) - } + adapter |> walk_data(unsafe(addr(f)), typeinfo rtti_typeinfo(f)) var s = "hello" print("Walking string \"hello\":\n") - unsafe { - adapter |> walk_data(addr(s), typeinfo rtti_typeinfo(s)) - } + adapter |> walk_data(unsafe(addr(s)), typeinfo rtti_typeinfo(s)) var b = true print("Walking bool true:\n") - unsafe { - adapter |> walk_data(addr(b), typeinfo rtti_typeinfo(b)) - } + adapter |> walk_data(unsafe(addr(b)), typeinfo rtti_typeinfo(b)) } unsafe { @@ -164,9 +156,7 @@ def demo_structures() { make_data_walker(walker) $(adapter) { var player = Player(name = "Alice", health = 100, pos = Vec3(x = 1.0, y = 2.5, z = -3.0)) print("Walking Player:\n") - unsafe { - adapter |> walk_data(addr(player), typeinfo rtti_typeinfo(player)) - } + adapter |> walk_data(unsafe(addr(player)), typeinfo rtti_typeinfo(player)) } unsafe { @@ -260,15 +250,11 @@ def demo_arrays_and_tables() { make_data_walker(walker) $(adapter) { var nums = [10, 20, 30, 40, 50] print("Walking array:\n") - unsafe { - adapter |> walk_data(addr(nums), typeinfo rtti_typeinfo(nums)) - } + adapter |> walk_data(unsafe(addr(nums)), typeinfo rtti_typeinfo(nums)) var scores <- { "Alice" => 95, "Bob" => 87, "Charlie" => 72 } print("\nWalking table:\n") - unsafe { - adapter |> walk_data(addr(scores), typeinfo rtti_typeinfo(scores)) - } + adapter |> walk_data(unsafe(addr(scores)), typeinfo rtti_typeinfo(scores)) } unsafe { @@ -346,21 +332,15 @@ def demo_tuples_and_variants() { make_data_walker(walker) $(adapter) { var t = ("hello", 42, 3.14) print("Walking tuple:\n") - unsafe { - adapter |> walk_data(addr(t), typeinfo rtti_typeinfo(t)) - } + adapter |> walk_data(unsafe(addr(t)), typeinfo rtti_typeinfo(t)) var ok_result = Result(ok = 42) print("\nWalking variant (ok=42):\n") - unsafe { - adapter |> walk_data(addr(ok_result), typeinfo rtti_typeinfo(ok_result)) - } + adapter |> walk_data(unsafe(addr(ok_result)), typeinfo rtti_typeinfo(ok_result)) var err_result = Result(err = "not found") print("\nWalking variant (err=\"not found\"):\n") - unsafe { - adapter |> walk_data(addr(err_result), typeinfo rtti_typeinfo(err_result)) - } + adapter |> walk_data(unsafe(addr(err_result)), typeinfo rtti_typeinfo(err_result)) } unsafe { @@ -413,9 +393,7 @@ class EnumBitfieldPrinter : DapiDataWalker { print(", ") } first = false - unsafe { - print("{ti.argNames[i]}") - } + print("{unsafe(ti.argNames[i])}") } } print("]\n") @@ -429,15 +407,11 @@ def demo_enums_and_bitfields() { make_data_walker(walker) $(adapter) { var color = Color.Green print("Walking enum Color.Green:\n") - unsafe { - adapter |> walk_data(addr(color), typeinfo rtti_typeinfo(color)) - } + adapter |> walk_data(unsafe(addr(color)), typeinfo rtti_typeinfo(color)) var perms : Permissions = Permissions.readable | Permissions.executable print("Walking bitfield (readable | executable):\n") - unsafe { - adapter |> walk_data(addr(perms), typeinfo rtti_typeinfo(perms)) - } + adapter |> walk_data(unsafe(addr(perms)), typeinfo rtti_typeinfo(perms)) } unsafe { @@ -740,9 +714,7 @@ def demo_filtering() { ) print("Walking PublicRecord (Secret fields skipped):\n") - unsafe { - adapter |> walk_data(addr(record), typeinfo rtti_typeinfo(record)) - } + adapter |> walk_data(unsafe(addr(record)), typeinfo rtti_typeinfo(record)) } unsafe { @@ -788,9 +760,7 @@ def demo_mutation() { var walker = new FloatClamper() make_data_walker(walker) $(adapter) { - unsafe { - adapter |> walk_data(addr(particle), typeinfo rtti_typeinfo(particle)) - } + adapter |> walk_data(unsafe(addr(particle)), typeinfo rtti_typeinfo(particle)) } print("After clamping: x={particle.x} y={particle.y} z={particle.z} alpha={particle.alpha}\n") diff --git a/tutorials/macros/structure_macro_mod.das b/tutorials/macros/structure_macro_mod.das index 6472d28669..9d61c9cf09 100644 --- a/tutorials/macros/structure_macro_mod.das +++ b/tutorials/macros/structure_macro_mod.das @@ -149,19 +149,17 @@ class SerializableMacro : AstStructureAnnotation { } // Get body as ExprBlock so we can append statements - unsafe { - var blk = reinterpret(fn.body) - - // Append one print group per serializable field - for (fld in st.fields) { - // Skip _version + non-serializable types (only known after inference) - if (fld.name == "_version" - || fld._type.baseType == Type.tLambda - || fld._type.baseType == Type.tFunction) continue - blk.list |> emplace_new <| qmacro(print($v(" {fld.name} = "))) - blk.list |> emplace_new <| qmacro(print("{obj.$f(fld.name)}")) - blk.list |> emplace_new <| qmacro(print($v("\n"))) - } + var blk = unsafe(reinterpret(fn.body)) + + // Append one print group per serializable field + for (fld in st.fields) { + // Skip _version + non-serializable types (only known after inference) + if (fld.name == "_version" + || fld._type.baseType == Type.tLambda + || fld._type.baseType == Type.tFunction) continue + blk.list |> emplace_new <| qmacro(print($v(" {fld.name} = "))) + blk.list |> emplace_new <| qmacro(print("{obj.$f(fld.name)}")) + blk.list |> emplace_new <| qmacro(print($v("\n"))) } // Mark as patched and trigger re-inference diff --git a/utils/benchctl/utils.das b/utils/benchctl/utils.das index 2f29eb1552..3d8dd68373 100644 --- a/utils/benchctl/utils.das +++ b/utils/benchctl/utils.das @@ -8,15 +8,13 @@ var colored_output = true def cmd_exec(cmd : string) : string { var out = "" - unsafe { - popen(cmd) $(f) { - out = build_string() $(var w) { - while (!feof(f)) { - w |> write(fgets(f)) - } + unsafe(popen(cmd) $(f) { + out = build_string() $(var w) { + while (!feof(f)) { + w |> write(fgets(f)) } } - } + }) return trim(out) } diff --git a/utils/dap/dap_bridge.das b/utils/dap/dap_bridge.das index 57e9564cef..1750ea7904 100644 --- a/utils/dap/dap_bridge.das +++ b/utils/dap/dap_bridge.das @@ -293,10 +293,8 @@ class public DapClient : Client { } def override onData(buf : uint8?; size : int) { - unsafe { - for (i in range(size)) { - buffer |> push(buf[i]) - } + for (i in range(size)) { + buffer |> push(unsafe(buf[i])) } while (!empty(buffer)) { var parsed = parse_dap_frame(buffer, false) diff --git a/utils/das-fmt/dasfmt.das b/utils/das-fmt/dasfmt.das index 3fabb9af31..c1e862cb78 100644 --- a/utils/das-fmt/dasfmt.das +++ b/utils/das-fmt/dasfmt.das @@ -330,9 +330,7 @@ def main() { var files : array if (!collect_files(inputPaths, seen, files)) { log::error("Unable to collect files list\n") - unsafe { - fio::exit(1) - } + unsafe(fio::exit(1)) return } @@ -341,9 +339,7 @@ def main() { for (lf in listPaths) { if (!collect_files_from_list(lf, seen, files)) { log::error("Unable to collect files list\n") - unsafe { - fio::exit(1) - } + unsafe(fio::exit(1)) return } } @@ -365,9 +361,7 @@ def main() { if (strip_failures > 0) { log::info("Failed! {strip_failures} file(s) not stripped in {time_dt_hr(get_time_usec(startTime))}") - unsafe { - fio::exit(1) - } + unsafe(fio::exit(1)) return } @@ -377,9 +371,7 @@ def main() { return } else { log::info("Verification failed! {filesNum} files in {time_dt_hr(get_time_usec(startTime))}") - unsafe { - fio::exit(1) - } + unsafe(fio::exit(1)) } } diff --git a/utils/dasllama-server/model_catalog.das b/utils/dasllama-server/model_catalog.das index 70164d94f3..7de604ad41 100644 --- a/utils/dasllama-server/model_catalog.das +++ b/utils/dasllama-server/model_catalog.das @@ -157,9 +157,7 @@ def public catalog_events_shutdown { if (catalog_download_running()) { to_log(LOG_WARNING, "dasllama-server: shutdown with a catalog download still running — channel left to the worker\n") } else { - unsafe { - ev |> channel_remove - } + unsafe(ev |> channel_remove) } } } diff --git a/utils/daspkg/index.das b/utils/daspkg/index.das index 817a824fe5..2d12cc1c2f 100644 --- a/utils/daspkg/index.das +++ b/utils/daspkg/index.das @@ -305,9 +305,7 @@ def cmd_search(root, query : string; json : bool = false) : int { var infos : array for (r in results) { if (index |> key_exists(r.name)) { - unsafe { - infos |> emplace(make_package_info(r.name, index[r.name])) - } + unsafe(infos |> emplace(make_package_info(r.name, index[r.name]))) } } print(sprint_json(infos, false)) @@ -316,9 +314,7 @@ def cmd_search(root, query : string; json : bool = false) : int { } for (r in results) { if (index |> key_exists(r.name)) { - unsafe { - format_entry(r.name, index[r.name]) - } + unsafe(format_entry(r.name, index[r.name])) print("\n") } } @@ -343,9 +339,7 @@ def cmd_search_all(root : string; json : bool = false) : int { var infos : array for (name in names) { if (index |> key_exists(name)) { - unsafe { - infos |> emplace(make_package_info(name, index[name])) - } + unsafe(infos |> emplace(make_package_info(name, index[name]))) } } print(sprint_json(infos, false)) @@ -354,9 +348,7 @@ def cmd_search_all(root : string; json : bool = false) : int { } for (name in names) { if (index |> key_exists(name)) { - unsafe { - format_entry(name, index[name]) - } + unsafe(format_entry(name, index[name])) print("\n") } } @@ -586,9 +578,7 @@ def private tag_index_lines(names : array; entries : array) } for (t in tag_names) { if (all_tags |> key_exists(t)) { - unsafe { - lines |> push("{t}\t{join(all_tags[t], ", ")}") - } + unsafe(lines |> push("{t}\t{join(all_tags[t], ", ")}")) } } return <- lines diff --git a/utils/daspkg/test_daspkg.das b/utils/daspkg/test_daspkg.das index ce105360bc..399a91778e 100644 --- a/utils/daspkg/test_daspkg.das +++ b/utils/daspkg/test_daspkg.das @@ -842,9 +842,7 @@ def test_remove_from_index_json(t : T?) { var error : string var js = read_json(result, error) t |> success(js != null) - unsafe { - t |> equal(length(js.value as _array), 0) - } + unsafe(t |> equal(length(js.value as _array), 0)) } t |> run("preserves other entries") @(t : T?) { var input = add_to_index_json("[]", "pkg1", "github.com/user/pkg1", "First") diff --git a/utils/jobque-timeline/tl_launch.das b/utils/jobque-timeline/tl_launch.das index e005e4107d..f26bb6de70 100644 --- a/utils/jobque-timeline/tl_launch.das +++ b/utils/jobque-timeline/tl_launch.das @@ -44,9 +44,7 @@ def public split_args(s : string) : array { in_quote = !in_quote } elif (!in_quote && (c == ' ' || c == '\t' || c == '\n' || c == '\r')) { if (!empty(cur)) { - unsafe { - out |> push(string(cur)) - } + out |> push(string(cur)) cur |> clear() } } else { @@ -55,9 +53,7 @@ def public split_args(s : string) : array { } } if (!empty(cur)) { - unsafe { - out |> push(string(cur)) - } + out |> push(string(cur)) } delete cur return <- out @@ -155,9 +151,7 @@ def public launch_pump(var L : LaunchRail) : bool { finished = true } else { var line = "" - unsafe { - line = clone_string(m.text) - } + line = clone_string(m.text) L.tail |> push(line) if (length(L.tail) > 60) { L.tail |> erase(0) @@ -166,9 +160,7 @@ def public launch_pump(var L : LaunchRail) : bool { } } if (finished) { - unsafe { - channel_remove(L.ch) - } + unsafe(channel_remove(L.ch)) L.ch = null } return finished diff --git a/utils/jobque-timeline/tl_loader.das b/utils/jobque-timeline/tl_loader.das index 07ba8df20b..d3652f24df 100644 --- a/utils/jobque-timeline/tl_loader.das +++ b/utils/jobque-timeline/tl_loader.das @@ -72,10 +72,7 @@ def private read_json_string(data : array const#; var pos : int&; line_en sb |> push(data[pos]) pos++ } - var out : string - unsafe { - out = string(sb) - } + let out = string(sb) delete sb return out } diff --git a/utils/lint/tests/style024_redundant_unsafe.das b/utils/lint/tests/style024_redundant_unsafe.das index 73fa9a152d..d2d4a28d22 100644 --- a/utils/lint/tests/style024_redundant_unsafe.das +++ b/utils/lint/tests/style024_redundant_unsafe.das @@ -38,7 +38,7 @@ options auto_inline_functions = false // lint fixtures assert SOURCE shapes; s // only trip STYLE024 under `utils/lint/main.das`. The block form fires // under regular compile too. -expect 31209:5 +expect 31209:6 require daslib/style_lint @@ -150,10 +150,10 @@ def good_unsafe_block_delete_pointer() : void { } } -def good_unsafe_block_delete_container() : void { +def bad_unsafe_block_delete_container() : void { var arr : array arr |> push(1) - unsafe { + unsafe { // STYLE024 - a plain container is safe to delete delete arr } } diff --git a/utils/lint/tests/style025_unsafe_block_narrow.das b/utils/lint/tests/style025_unsafe_block_narrow.das index d0170fa683..72f8236e70 100644 --- a/utils/lint/tests/style025_unsafe_block_narrow.das +++ b/utils/lint/tests/style025_unsafe_block_narrow.das @@ -69,6 +69,17 @@ def good_narrowed_expression_form() : void { unsafe(my_unsafe_void(5)) // expression form — no STYLE025 } +class FixtureWidget { + x : int +} + +def good_stack_class_declaration() : void { + unsafe { + let w = FixtureWidget() + print("{w.x}\n") + } +} + def good_nested_addr_block() : void { // Block form is required when nested `addr(x)` needs unsafeDepth to // propagate — STYLE025 should NOT fire here. diff --git a/utils/mcp/mcp_core.das b/utils/mcp/mcp_core.das index cbfecd85d2..0e66e61de9 100644 --- a/utils/mcp/mcp_core.das +++ b/utils/mcp/mcp_core.das @@ -635,9 +635,7 @@ def serve_stdio(server : McpServer; reg : array) { let str_used = string_heap_bytes_allocated() if (heap_used > HEAP_COLLECT_THRESHOLD || str_used > HEAP_COLLECT_THRESHOLD) { logger_info("mcp.heap", "collecting — heap: {int(heap_used)}, string heap: {int(str_used)}") - unsafe { - heap_collect(str_used > HEAP_COLLECT_THRESHOLD, false) - } + unsafe(heap_collect(str_used > HEAP_COLLECT_THRESHOLD, false)) } } logger_info("mcp", "stdin closed, shutting down") diff --git a/utils/mcp/protocol_core.das b/utils/mcp/protocol_core.das index 317498a30c..69bc1049bf 100644 --- a/utils/mcp/protocol_core.das +++ b/utils/mcp/protocol_core.das @@ -78,7 +78,7 @@ def register_shutdown(var reg : array) { []), main_thread = true, handler = @@(arg1, arg2, arg3, arg4, arg5, arg6, project, project_root : string; load_modules : array) : string { - unsafe { exit(0); } + unsafe(exit(0)) return make_tool_result("shutting down") })) } diff --git a/utils/mcp/tools/grep_usage.das b/utils/mcp/tools/grep_usage.das index 0c0f394182..e3db1ec85a 100644 --- a/utils/mcp/tools/grep_usage.das +++ b/utils/mcp/tools/grep_usage.das @@ -102,16 +102,14 @@ def do_grep_usage(symbol, directory, context_lines_str, glob_filter : string) : cmd = "{cd_root}{sg} run -p \"{symbol}\" -l daslang --globs \"{glob_filter}\" --json \"{search_dir}\"" } var raw_json : string - unsafe { - popen(cmd) $(f) { - if (f == null) return - raw_json = build_string() $(var w) { - while (!feof(f)) { - write(w, fgets(f)) - } + unsafe(popen(cmd) $(f) { + if (f == null) return + raw_json = build_string() $(var w) { + while (!feof(f)) { + write(w, fgets(f)) } } - } + }) raw_json = strip_ast_grep_banner(raw_json) if (empty(raw_json) || raw_json == "[]") return make_tool_result("No matches found for '{symbol}' in {search_dir}") // parse JSON array from ast-grep @@ -155,9 +153,7 @@ def private format_grep_matches(symbol : string; var by_file : table Date: Thu, 17 Sep 2026 00:35:36 +0300 Subject: [PATCH 08/12] rtti: a deserialized program finalizes against the caller's module group deserialize_program reached finalizeAnnotations with thisModuleGroup unset, so ast_annotations.cpp bound `*program->thisModuleGroup` from a null pointer - undefined the moment the reference forms, which the UBSAN lane reports against the rtti round-trip test. Nothing crashed because no finalize body reads the group; the adapter hands it to a [function_macro]'s finish, and none of the fixtures has one. The group could not be supplied at all: the header says it is passed from top-level, the compile path passes it, and the das API had no parameter for it. dastest already knew - it opens a ModuleGroup around its --deser loop and had to name it `_mg`, unused, because there was nowhere to put it. So the parameter is the fix rather than a stand-in group: an empty one would let a finish see empty user data instead of the caller's, trading a sanitizer finding for a silent wrong answer. Both overloads take it after access, the way compile_file does, and both in-tree callers pass the group they already had. --- dastest/dastest.das | 4 ++-- ...nction-rtti-deserialize_program-0x15d628ec5a8ce8da.rst | 5 ----- ...nction-rtti-deserialize_program-0x6822cf0d160c8c65.rst | 8 ++++++++ include/daScript/ast/ast_serializer.h | 4 ++-- skills/daslang/references/everything.md | 2 +- src/builtin/module_builtin_ast_serialize.cpp | 7 ++++--- src/builtin/module_builtin_rtti.cpp | 4 ++-- tests/module_cache/test_rtti_serializer.das | 2 +- 8 files changed, 20 insertions(+), 16 deletions(-) delete mode 100644 doc/source/stdlib/handmade/function-rtti-deserialize_program-0x15d628ec5a8ce8da.rst create mode 100644 doc/source/stdlib/handmade/function-rtti-deserialize_program-0x6822cf0d160c8c65.rst diff --git a/dastest/dastest.das b/dastest/dastest.das index cb136e3410..d24bdfd4f8 100644 --- a/dastest/dastest.das +++ b/dastest/dastest.das @@ -437,9 +437,9 @@ def deserialize_path(var ctx : SuiteCtx, _files : array, in_file : strin // the reader's access: a stream carries none, and a program's late require takes its program's var inscope access <- make_file_access(ctx.projectPath) access |> add_file_access_root("dastest", ctx.dastestRoot) - using() $(var _mg : ModuleGroup) { + using() $(var mg : ModuleGroup) { for (i in range(count)) { - deserialize_program(ser, access) $(ok, program, error) { + deserialize_program(ser, access, unsafe(addr(mg))) $(ok, program, error) { if (!ok) { log::error("Deserialization failed at program {i}: {error}") res.errors++ diff --git a/doc/source/stdlib/handmade/function-rtti-deserialize_program-0x15d628ec5a8ce8da.rst b/doc/source/stdlib/handmade/function-rtti-deserialize_program-0x15d628ec5a8ce8da.rst deleted file mode 100644 index c03094257a..0000000000 --- a/doc/source/stdlib/handmade/function-rtti-deserialize_program-0x15d628ec5a8ce8da.rst +++ /dev/null @@ -1,5 +0,0 @@ -Deserializes the next program from the stream and calls ``block`` with it, the way the -two-argument form does, and gives the restored program ``access`` as its own: a stream carries -no file access, and a ``require_module_now`` issued from the program's macros or ``[init]`` -walks through its program's access, so a reader that restores programs whose code requires -modules late passes the access it would have compiled them with. diff --git a/doc/source/stdlib/handmade/function-rtti-deserialize_program-0x6822cf0d160c8c65.rst b/doc/source/stdlib/handmade/function-rtti-deserialize_program-0x6822cf0d160c8c65.rst new file mode 100644 index 0000000000..5b5cf4c02f --- /dev/null +++ b/doc/source/stdlib/handmade/function-rtti-deserialize_program-0x6822cf0d160c8c65.rst @@ -0,0 +1,8 @@ +Deserializes the next program from the stream and calls ``block`` with it, the way the +three-argument form does, and gives the restored program ``access`` as its own: a stream carries +no file access, and a ``require_module_now`` issued from the program's macros or ``[init]`` +walks through its program's access, so a reader that restores programs whose code requires +modules late passes the access it would have compiled them with. ``libGroup`` is the module +group the restored program finalizes its annotations against, the way ``compile_file`` takes +one: a function or block annotation's ``finish`` is handed this group, so it must be the +caller's own rather than an empty stand-in. diff --git a/include/daScript/ast/ast_serializer.h b/include/daScript/ast/ast_serializer.h index 5f54bb3e9a..c53f7331b9 100644 --- a/include/daScript/ast/ast_serializer.h +++ b/include/daScript/ast/ast_serializer.h @@ -584,12 +584,12 @@ namespace das { // Deserialize one program (reading mode). void rtti_ast_serializer_deserialize_program ( - AstSerializerState * state, + AstSerializerState * state, ModuleGroup * libGroup, const TBlock,const string> & block, Context * context, LineInfoArg * at ); // the same, with the access the restored program's late requires walk through void rtti_ast_serializer_deserialize_program_ex ( - AstSerializerState * state, smart_ptr access, + AstSerializerState * state, smart_ptr access, ModuleGroup * libGroup, const TBlock,const string> & block, Context * context, LineInfoArg * at ); diff --git a/skills/daslang/references/everything.md b/skills/daslang/references/everything.md index 6358b9bf67..c4457a01b9 100644 --- a/skills/daslang/references/everything.md +++ b/skills/daslang/references/everything.md @@ -3533,7 +3533,7 @@ The RTTI module exposes runtime type information and program introspection facil - `create_ast_deserializer` - Creates deserializer. - `create_ast_serializer` - Creates serializer object. - `delete_ast_serializer` - Frees memory for ast_serializer. -- `deserialize_program` - Deserializes the next program from the stream and calls `block` with it, the way the two-argument form does, and gives the restored program `access` as its own: a stream carries no file access, and a `require_module_now` issued from the program's macros or `[init]` walks through its program's access, so a reader that restores programs whose code requires modules late passes the access it would have compiled them with. +- `deserialize_program` - Deserializes the next program from the stream and calls `block` with it, the way the three-argument form does, and gives the restored program `access` as its own: a stream carries no file access, and a `require_module_now` issued from the program's macros or `[init]` walks through its program's access, so a reader that restores programs whose code requires modules late passes the access it would have compiled them with. - `for_each_expected_error` - Iterates through each expected compilation error declared in the `Program` (via `expect`), yielding the error code for each. - `for_each_require_declaration` - Iterates through each `require` declaration of the compiled `Program`, yielding the module name, public/private flag, and source `LineInfo`. - `serialize_program` - Serializes program to serializer object. diff --git a/src/builtin/module_builtin_ast_serialize.cpp b/src/builtin/module_builtin_ast_serialize.cpp index a94251135e..657afe8bae 100644 --- a/src/builtin/module_builtin_ast_serialize.cpp +++ b/src/builtin/module_builtin_ast_serialize.cpp @@ -4048,11 +4048,12 @@ namespace das { } void rtti_ast_serializer_deserialize_program_ex ( - AstSerializerState * state, smart_ptr access, + AstSerializerState * state, smart_ptr access, ModuleGroup * libGroup, const TBlock,const string> & block, Context * context, LineInfoArg * at ) { auto prog = make_smart(); prog->access = access; // the reader's: a stream carries none (src/ast/ARCHITECTURE.md#require-after-walk) + state->serializer->thisModuleGroup = libGroup; { gc_guard deserialize_gc_scope; // same-version streams can still be truncated/corrupt: the stream readers throw @@ -4096,10 +4097,10 @@ namespace das { } void rtti_ast_serializer_deserialize_program ( - AstSerializerState * state, + AstSerializerState * state, ModuleGroup * libGroup, const TBlock,const string> & block, Context * context, LineInfoArg * at ) { - rtti_ast_serializer_deserialize_program_ex(state, nullptr, block, context, at); + rtti_ast_serializer_deserialize_program_ex(state, nullptr, libGroup, block, context, at); } int64_t rtti_ast_serializer_finalize_usec ( AstSerializerState * state ) { diff --git a/src/builtin/module_builtin_rtti.cpp b/src/builtin/module_builtin_rtti.cpp index 0052a6a3b4..baf7218293 100644 --- a/src/builtin/module_builtin_rtti.cpp +++ b/src/builtin/module_builtin_rtti.cpp @@ -2040,10 +2040,10 @@ namespace das { ->args({"serializer","program"}); addExtern(*this, lib, "deserialize_program", SideEffects::modifyExternal, "rtti_ast_serializer_deserialize_program") - ->args({"serializer","block","context","line"}); + ->args({"serializer","libGroup","block","context","line"}); addExtern(*this, lib, "deserialize_program", SideEffects::modifyExternal, "rtti_ast_serializer_deserialize_program_ex") - ->args({"serializer","access","block","context","line"}); + ->args({"serializer","access","libGroup","block","context","line"}); addExtern(*this, lib, "ast_serializer_get_data", SideEffects::modifyExternal, "rtti_ast_serializer_get_data") ->args({"serializer","block","context","line"}); diff --git a/tests/module_cache/test_rtti_serializer.das b/tests/module_cache/test_rtti_serializer.das index 4e3e76eba6..8aeae89cab 100644 --- a/tests/module_cache/test_rtti_serializer.das +++ b/tests/module_cache/test_rtti_serializer.das @@ -34,7 +34,7 @@ def test_rtti_serializer_round_trip(t : T?) { var restored = false let t0 = ref_time_ticks() var deser = create_ast_deserializer(bytes) - deserialize_program(deser) $(dok, _prog, err) { + deserialize_program(deser, unsafe(addr(mg))) $(dok, _prog, err) { restored = dok if (!dok) { t |> failure("deserialize_program: {err}") From cfbe84cdbad32bf5098b6ce9c741c085603bca76 Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Thu, 17 Sep 2026 01:06:16 +0300 Subject: [PATCH 09/12] tests: the IEEE expectations skip on a host built fast-math The fastmath lane builds the whole tree -ffast-math, and three tests assert guarantees that flag trades away: nan compare semantics, the sign of zero, and a division that stays finite across an inf. All three pass interpreted and fail under --use-aot, because the interpreter compares at run time while AOT emits daslang's const-folded inf and nan as literals for a C++ compiler that has been told neither exists. inf_and_nan already meant to skip such a host, but its probe compares values laundered through opaque(), which nothing folds - so the probe answers "this host is fine" while the asserts beside it are folded away. HOST_FAST_MATH is the exact answer and the tree's existing one; the probe stays for a host that passes only -ffinite-math-only. test_builder keys a spirv constant by bits and wants 0.0 and -0.0 to be two ids, which -fno-signed-zeros makes one value. fast_math_specials pins that a silu stays NaN-free - the JIT stamp is narrowed to reassoc|nsz|contract for exactly that reason, but a tree built -ffast-math hands the C++ tier the rcp-estimate lowering anyway, and the sweep comes back with 1104 NaNs. That guarantee is the host's to keep once it has asked for the flag. On every other host the three still run; nothing is skipped. --- tests/jit/fast_math_specials.das | 4 ++++ tests/math/inf_and_nan.das | 8 ++------ tests/spirv/test_builder.das | 4 ++++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/jit/fast_math_specials.das b/tests/jit/fast_math_specials.das index 48553f5fa4..29a34ec7ad 100644 --- a/tests/jit/fast_math_specials.das +++ b/tests/jit/fast_math_specials.das @@ -30,6 +30,10 @@ def silu_core(var x : float?; size : int64) { [test] def test_fast_math_inf_safe(t : T?) { + if (HOST_FAST_MATH) { + t |> skip("host runtime is built -ffast-math: the whole tree gets the rcp-estimate lowering this pins the stamp against, so the guarantee is the host's to keep") + return + } t |> run("silu stays finite across the exp-overflow range under fast_math") @(t : T?) { // sweeps -192..191 — exp(-v) overflows past |v| ~ 88 var x <- [for (i in range(4096)); float(i % 512 - 256) * 0.75] diff --git a/tests/math/inf_and_nan.das b/tests/math/inf_and_nan.das index ae9c2a1eed..4d4da0bc41 100644 --- a/tests/math/inf_and_nan.das +++ b/tests/math/inf_and_nan.das @@ -7,10 +7,6 @@ let neg_inf = -1.0 / 0.0 // nolint:LINT006 let neg_nan = inf / inf // nolint:LINT007 — inf/inf is how a nan is produced here let nan = -(inf / inf) // nolint:LINT007 -// A host may build the runtime with -ffinite-math-only (dagor does). That folds every nan -// comparison to a constant, so the compare semantics below are not the ones that host -// asked for - detect it and skip. is_nan / is_finite are exempt: they answer IEEE on every -// host (test_is_nan_and_is_finite_hold_on_every_host), so the probe is a compare, never is_nan. def private host_folds_nan_compares() : bool { let a = opaque(unsafe(reinterpret(0x7FF8000000000000ul))) let b = opaque(unsafe(reinterpret(0x7FF8000000000000ul))) @@ -79,8 +75,8 @@ def test_abs_clears_the_sign_of_zero(t : T?) { [test] def test_inf_and_nan(t : T?) { - if (host_folds_nan_compares()) { - t |> skip("host runtime is built -ffinite-math-only: nan compares fold") + if (HOST_FAST_MATH || host_folds_nan_compares()) { + t |> skip("host runtime is built -ffast-math/-ffinite-math-only: nan compares fold") return } t |> run("inf and neg inf") @@(t : T?) { diff --git a/tests/spirv/test_builder.das b/tests/spirv/test_builder.das index e1dc0229af..b68cb5e828 100644 --- a/tests/spirv/test_builder.das +++ b/tests/spirv/test_builder.das @@ -110,6 +110,10 @@ def test_builder_dedup_and_validate(t : T?) { // nolint:STYLE038 - linear hand-b // constants — a stringified key would alias them to one id. [test] def test_const_float_bitkey(t : T?) { + if (HOST_FAST_MATH) { + t |> skip("host runtime is built -ffast-math: -fno-signed-zeros folds -0.0 to 0.0, so the two keys are one value") + return + } t |> run("builder: const_float keys by bits (0.0 != -0.0), dedup intact") <| @(t : T?) { var m = make_module() let zero = 0.0f From bac0ae9269e0433dceede2b89f52c78b874b8ab9 Mon Sep 17 00:00:00 2001 From: Boris Batkin Date: Wed, 16 Sep 2026 18:46:46 -0700 Subject: [PATCH 10/12] jit: the in-memory engine's functions carry the host cpu and features The MCJIT the C API builds has no cpu and no feature string, so its subtarget is the generic one, while the emitter's gates read the host: on an aarch64 part with DotProd the idot family lowered to SDOT and instruction selection aborted with `Cannot select: AArch64ISD::SDOT` (tests/type_lattice/test_lattice_idot.das under test_llvm_aot, the rail this branch arms on every Release lane; a static daslang build always ends on this engine). The host cpu and feature string the DLL and exe rails build their machine from now land on every defined function of an in-memory module as target-cpu / target-features attributes, the route the fat-mode clones already ride, so the subtarget the function is selected under matches the gates that emitted it. host_machine_cpu_features carries the one host string both places read. The emitter pin follows the edit. --- .../dasLLVM/ARCHITECTURE_TARGET_FEATURES.md | 8 +++ modules/dasLLVM/daslib/llvm_jit_common.das | 64 +++++++++++++------ modules/dasLLVM/daslib/llvm_jit_run.das | 5 +- 3 files changed, 55 insertions(+), 22 deletions(-) diff --git a/modules/dasLLVM/ARCHITECTURE_TARGET_FEATURES.md b/modules/dasLLVM/ARCHITECTURE_TARGET_FEATURES.md index c52abade3e..c242e30214 100644 --- a/modules/dasLLVM/ARCHITECTURE_TARGET_FEATURES.md +++ b/modules/dasLLVM/ARCHITECTURE_TARGET_FEATURES.md @@ -24,6 +24,14 @@ ARMv8.0 baseline, which cannot select SDOT or SMMLA, so the DotProd and i8mm gat (`g_target_arm64_dotprod`, `g_target_arm64_i8mm`) stay off there and every `aarch64_neon` call that needs either compiles its daslang fallback body. The gates and the machine string are one truth on both rails: a force-env feature raises the gate AND is appended to the generic machine. +The string reaches the code on three routes, one per engine: the DLL and exe rails build their +target machine from it (`create_default_target_machine`); the in-memory MCJIT - the engine every +run without a DLL cache ends on, a static daslang build always - is created through the C API +with no cpu and no feature string, so its subtarget is the generic one, and `stamp_host_target_attrs` +puts the same cpu and string on every defined function as `target-cpu` / `target-features` +attributes, which the per-function subtarget lookup honors (the route the fat-mode clones of +sec.11 already ride). A module the gates emitted SDOT into and the generic subtarget selects +aborts codegen with `Cannot select`; the attributes are what let the two agree. The two ways a feature reaches the target machine's string license different things. A detection-derived append - `+dotprod` always, `+i8mm` when `cpu_supports` confirms it - is diff --git a/modules/dasLLVM/daslib/llvm_jit_common.das b/modules/dasLLVM/daslib/llvm_jit_common.das index 8605c05d50..9ca2e3ab1e 100644 --- a/modules/dasLLVM/daslib/llvm_jit_common.das +++ b/modules/dasLLVM/daslib/llvm_jit_common.das @@ -969,44 +969,66 @@ def public create_default_target_machine(opt_level : uint; use_host_cpu : bool) } else { triple_msg = host_triple } - let cpu_msg = use_host_cpu ? LLVMGetHostCPUName() : "" - let features_msg = use_host_cpu ? LLVMGetHostCPUFeatures() : "" - var targetMachine : LLVMTargetMachineRef - if (use_host_cpu && g_target_is_aarch64) { - var feats = empty(features_msg) ? "+dotprod" : "{features_msg},+dotprod" - if (cpu_supports("i8mm")) { - feats = "{feats},+i8mm" - } - // a forced feature's artifact cache-hits on the target box without a linker there - let forced_arm = arm64_forced_plus_features() - if (!empty(forced_arm)) { - feats = "{feats},{forced_arm}" - } - targetMachine = create_target_machine(triple_msg, cpu_msg, feats, opt_level) + if (use_host_cpu) { + let host = host_machine_cpu_features() + targetMachine = create_target_machine(triple_msg, host.cpu, host.features, opt_level) } else { - let forced = g_target_is_x64 ? x64_forced_plus_features() : (g_target_is_aarch64 ? arm64_forced_plus_features() : "") - let feats = empty(forced) ? features_msg : (empty(features_msg) ? forced : "{features_msg},{forced}") + let feats = g_target_is_x64 ? x64_forced_plus_features() : (g_target_is_aarch64 ? arm64_forced_plus_features() : "") let env_forced = g_target_is_x64 ? g_env_jit.jit_x64_force_features : (g_target_is_aarch64 ? g_env_jit.jit_arm64_force_features : "") // the baseline class names the machine's cpu; the generic rail otherwise leaves it to LLVM's default let baseline = jit_baseline_class() - let cpu = (use_host_cpu || empty(baseline)) ? cpu_msg : jit_cpu_class_row(baseline).cpu + let cpu = empty(baseline) ? "" : jit_cpu_class_row(baseline).cpu if (!empty(env_forced)) { to_log(LOG_INFO, "LLVM JIT: {g_target_is_x64 ? "DAS_JIT_X64_FORCE_FEATURES" : "DAS_JIT_ARM64_FORCE_FEATURES"} appends {env_forced} to the machine {cpu}\n") } targetMachine = create_target_machine(triple_msg, cpu, feats, opt_level) } - if (use_host_cpu) { - LLVMDisposeMessage(cpu_msg) - LLVMDisposeMessage(features_msg) - } if (triple_owned_by_llvm) { LLVMDisposeMessage(triple_msg) } return targetMachine } +//! The host machine's cpu name and feature string as the host-cpu target machine is built from +//! them: LLVM's detection, plus dotprod / i8mm on aarch64 and the forced features of the arch. +def public host_machine_cpu_features() : tuple { + let cpu_msg = LLVMGetHostCPUName() + let features_msg = LLVMGetHostCPUFeatures() + var feats = "{features_msg}" + if (g_target_is_aarch64) { + feats = empty(feats) ? "+dotprod" : "{feats},+dotprod" + if (cpu_supports("i8mm")) { + feats = "{feats},+i8mm" + } + } + // a forced feature's artifact cache-hits on the target box without a linker there + let forced = g_target_is_x64 ? x64_forced_plus_features() : (g_target_is_aarch64 ? arm64_forced_plus_features() : "") + if (!empty(forced)) { + feats = empty(feats) ? forced : "{feats},{forced}" + } + let cpu = "{cpu_msg}" + LLVMDisposeMessage(cpu_msg) + LLVMDisposeMessage(features_msg) + return (cpu = cpu, features = feats) +} + +//! The in-memory MCJIT is built through the C API with no cpu and no feature string, so its +//! subtarget is the generic one and cannot select a host intrinsic; a defined function carries +//! the host's as attributes instead, which the subtarget lookup honors per function. +def public stamp_host_target_attrs(m : LLVMOpaqueModule?) { + let host = host_machine_cpu_features() + var fn = LLVMGetFirstFunction(m) + while (fn != null) { + if (LLVMIsDeclaration(fn) == 0) { + LLVMAddTargetDependentFunctionAttr(fn, "target-cpu", host.cpu) + LLVMAddTargetDependentFunctionAttr(fn, "target-features", host.features) + } + fn = LLVMGetNextFunction(fn) + } +} + [macro_function] def public with_default_target_machine(opt_level : uint; use_host_cpu : bool; blk : block<(LLVMTargetMachineRef) : void>) { diff --git a/modules/dasLLVM/daslib/llvm_jit_run.das b/modules/dasLLVM/daslib/llvm_jit_run.das index 4868644070..c616519bd3 100644 --- a/modules/dasLLVM/daslib/llvm_jit_run.das +++ b/modules/dasLLVM/daslib/llvm_jit_run.das @@ -37,7 +37,7 @@ var LINK_WHOLE_LIB = false // when true, standalone exe links against the whole // Read by tests-cpp/small/test_jit_emitter_pin.cpp: FNV-1a64 of the emitter sources // (normalized to LF; file list in the test) -let LLVM_JIT_EMITTER_HASH : uint64 = 0x6eeb529c1bd2a8ful +let LLVM_JIT_EMITTER_HASH : uint64 = 0x9ab4a9480d46b45aul def private apply_fast_math_to_module(m : LLVMOpaqueModule?) { var fn = LLVMGetFirstFunction(m) @@ -658,6 +658,9 @@ def public run_jit(prog : Program?; var ctx : Context?) : bool { // nolint:STYL if (g_jit_fast_math) { apply_fast_math_to_module(g_mod) // EXPERIMENT: stamp all FP ops fast (non-bit-exact ceiling) } + if (use_host_cpu && !(compile_only || emit_aot_object || gen_lib || gen_wasm || gen_exe || use_dll)) { + stamp_host_target_attrs(g_mod) // the module runs on the in-memory engine, which carries no cpu or features of its own + } t_irgen = get_time_usec(phase_tm) phase_tm = ref_time_ticks() optimize_and_verify_module(opt_level, size_level, use_host_cpu, dump_ir, funcs) From 690d8335a850890e82f4f0af307fbe264159b4fb Mon Sep 17 00:00:00 2001 From: Boris Batkin Date: Wed, 16 Sep 2026 20:45:07 -0700 Subject: [PATCH 11/12] modules: the fusion hooks and the deferred loader are set once, and read atomically tests-cpp/big/concurrent_init drives NEED_ALL_DEFAULT_MODULES + Module::Initialize + Shutdown from 128 threads, and the tsan lane reported what it found: every thread's register_fusion() wrote g_fusionContextFn and g_resetFusionEngineFn, and every thread's shutdownInternal() wrote g_deferredModuleLoader - plain globals, no ordering. The hooks are now set under a once_flag, which also orders every later reader after the one write; the deferred loader is an atomic the accessors load and store. The nightly's tsan lane was red on this before the branch and is the fifth cause the branch closes. --- src/ast/ast_module.cpp | 9 +++++---- src/simulate/simulate_fusion.cpp | 9 +++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/ast/ast_module.cpp b/src/ast/ast_module.cpp index 702829e04d..5ae6d4fcee 100644 --- a/src/ast/ast_module.cpp +++ b/src/ast/ast_module.cpp @@ -178,19 +178,20 @@ namespace das { return false; } - static DeferredModuleLoader g_deferredModuleLoader = nullptr; + static std::atomic g_deferredModuleLoader { nullptr }; void setDeferredModuleLoader ( DeferredModuleLoader loader ) { - g_deferredModuleLoader = loader; + g_deferredModuleLoader.store(loader); } DeferredModuleLoader getDeferredModuleLoader () { - return g_deferredModuleLoader; + return g_deferredModuleLoader.load(); } bool guardModuleAvailable ( const string & name ) { if ( Module::requireEx(name, false) ) return true; - return g_deferredModuleLoader && g_deferredModuleLoader(name) && Module::requireEx(name, false); + auto loader = g_deferredModuleLoader.load(); + return loader && loader(name) && Module::requireEx(name, false); } // src/ast/ARCHITECTURE.md#module-scan-manifest - process-wide, like the native paths: a descriptor registers once per process diff --git a/src/simulate/simulate_fusion.cpp b/src/simulate/simulate_fusion.cpp index 3c78207683..83236833c6 100644 --- a/src/simulate/simulate_fusion.cpp +++ b/src/simulate/simulate_fusion.cpp @@ -9,6 +9,8 @@ #include "daScript/simulate/sim_policy.h" #include "daScript/simulate/simulate_visit_op.h" +#include + namespace das { bool FusionPoint::is ( const SimNodeInfoLookup & info, SimNode * node, const char * name ) { @@ -256,8 +258,11 @@ namespace das { } DAS_CC_API void register_fusion () { - das::g_fusionContextFn = &das::fusionContext; - das::g_resetFusionEngineFn = &das::resetFusionEngine; + static std::once_flag fusionHooksOnce; + std::call_once(fusionHooksOnce, [] { + das::g_fusionContextFn = &das::fusionContext; + das::g_resetFusionEngineFn = &das::resetFusionEngine; + }); } extern "C" DAS_CC_API void jit_register_fusion () { From 8f0a48924df5ddb52cc65d09d7df6304c6d1a226 Mon Sep 17 00:00:00 2001 From: Churkin Aleksey Date: Thu, 17 Sep 2026 10:33:34 +0300 Subject: [PATCH 12/12] jit: a standalone library's module registration hands its nodes to the modules jit_lib_run_once registers every module the library links, and registering a handled type mints TypeDecl gc_nodes, which link to the thread root. Nothing then claimed them, so a host that loaded such a library ended execution with the thread root non-empty and daslang reported it - 68 of the standalone sweep's libraries built and then failed to run, each on the handled types its modules carry. Every other rail that registers modules already settles this: das_program_simulate opens a gc_guard and lets each module collect from it, and the dynamic module loader parks the thread root, collects onto the module roots and sweeps the rest. The lib rail now does the same - the guard takes the registration's nodes, each module claims its own onto module_gc_root, and the guard sweeps what nobody claimed. The leak predates the branch: a daslang built from master leaks the same nodes on the same generated host. The sweep only started reporting it because this branch arms the nightly backend sweeps on the PR. --- src/builtin/jit_runtime.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/builtin/jit_runtime.cpp b/src/builtin/jit_runtime.cpp index ed3d57ae6a..494be92de5 100644 --- a/src/builtin/jit_runtime.cpp +++ b/src/builtin/jit_runtime.cpp @@ -1231,7 +1231,14 @@ DAS_API int32_t jit_lib_run_once ( int32_t * guard, void ** env, void (*fn)() ) das::daScriptEnvironment::ensure(); *env = das::daScriptEnvironment::getBound(); *guard = das::daScriptEnvironment::getBound()->modules ? 2 : 1; - fn(); + { + das::gc_guard registration_gc_scope; + fn(); + das::Module::foreach([&](das::Module * m) { + m->gc_collect(®istration_gc_scope.guard_root); + return true; + }); + } return 1; }