5.2.9. C Integration: AOT

This tutorial demonstrates Ahead-of-Time compilation via the C API. AOT translates daslang functions into C++ source code at build time. When linked into the host executable and enabled via policies, simulate() replaces interpreter nodes with direct native calls — near-C++ performance.

5.2.9.1. AOT workflow

  1. Generate C++ from the script: daslang.exe utils/aot/main.das -- -aot script.das script.das.cpp

  2. Compile the generated .cpp into the host executable (CMake handles this)

  3. Set policies: DAS_POLICY_AOT = 1 before compilation

  4. Simulate: the runtime links AOT functions automatically

  5. Verify: das_function_is_aot(fn) returns 1

5.2.9.2. Using policies from C

The das_policies API lets you control CodeOfPolicies from C:

das_policies * pol = das_policies_make();
das_policies_set_bool(pol, DAS_POLICY_AOT, 1);
das_policies_set_bool(pol, DAS_POLICY_FAIL_ON_NO_AOT, 1);

das_program * program = das_program_compile_policies(
    script, fa, tout, libgrp, pol);
das_policies_release(pol);

Two enum types ensure type safety:

  • das_bool_policy — boolean flags (DAS_POLICY_AOT, DAS_POLICY_NO_UNSAFE, DAS_POLICY_NO_GLOBAL_VARIABLES, etc.)

  • das_int_policy — integer fields (DAS_POLICY_STACK, DAS_POLICY_MAX_HEAP_ALLOCATED, etc.)

Using the wrong enum type will produce a compiler warning.

5.2.9.3. Checking AOT status

After simulation, check whether a function was AOT-linked:

das_function * fn = das_context_find_function(ctx, "test");
printf("test() is AOT: %s\n", das_function_is_aot(fn) ? "yes" : "no");

5.2.9.4. Available boolean policies

Enum value

CodeOfPolicies field

DAS_POLICY_AOT

aot — enable AOT linking

DAS_POLICY_NO_UNSAFE

no_unsafe — forbid unsafe blocks

DAS_POLICY_NO_GLOBAL_VARIABLES

no_global_variables — forbid module-level var

DAS_POLICY_NO_GLOBAL_HEAP

no_global_heap — forbid heap globals

DAS_POLICY_NO_INIT

no_init — forbid [init] functions

DAS_POLICY_FAIL_ON_NO_AOT

fail_on_no_aot — missing AOT is error

DAS_POLICY_THREADLOCK_CONTEXT

threadlock_context — context mutex

DAS_POLICY_INTERN_STRINGS

intern_strings — string interning

DAS_POLICY_PERSISTENT_HEAP

persistent_heap — no GC between calls

DAS_POLICY_MULTIPLE_CONTEXTS

multiple_contexts — context safety

DAS_POLICY_STRICT_SMART_POINTERS

strict_smart_pointers — var inscope rules

DAS_POLICY_RTTI

rtti — extended RTTI

DAS_POLICY_NO_OPTIMIZATIONS

no_optimizations — disable all optimizations

5.2.9.5. Available integer policies

Enum value

CodeOfPolicies field

DAS_POLICY_STACK

stack — context stack size (bytes)

DAS_POLICY_MAX_HEAP_ALLOCATED

max_heap_allocated — max heap (0 = unlimited)

DAS_POLICY_MAX_STRING_HEAP_ALLOCATED

max_string_heap_allocated

DAS_POLICY_HEAP_SIZE_HINT

heap_size_hint — initial heap size

DAS_POLICY_STRING_HEAP_SIZE_HINT

string_heap_size_hint

5.2.9.6. Build & run

Build:

cmake --build build --config Release --target integration_c_09

Run:

bin/Release/integration_c_09

Expected output:

=== Interpreter mode ===
  test() is AOT: no
=== AOT Tutorial ===
fib(0) = 0
fib(1) = 1
...
fib(9) = 34
sin(pi/4) = 0.70710677
cos(pi/4) = 0.70710677
sqrt(2)   = 1.4142135

=== AOT mode (policies.aot = true) ===
  test() is AOT: yes
=== AOT Tutorial ===
fib(0) = 0
...
fib(9) = 34

See also

Full source: 09_aot.c

This tutorial reuses the script from the C++ AOT tutorial: 13_aot.das

Previous tutorial: tutorial_integration_c_serialization

Next tutorial: tutorial_integration_c_threading

C++ equivalent: tutorial_integration_cpp_aot

daScriptC.h API header: include/daScript/daScriptC.h