mirror of
https://github.com/ChaiScript/ChaiScript.git
synced 2026-07-31 00:37:02 +08:00
Two bugs combined to cause the crash: 1. The optimized for loop (chaiscript_optimizer.hpp) stored the loop counter as a stack-local `int` and exposed it to ChaiScript via `var(&i)`, creating a reference-type Boxed_Value pointing to the stack frame. 2. The `:=` operator's `Data::operator=` performed a shallow clone of the Any (copying the reference_wrapper, not the value), so `ret := i` made `ret` alias the stack-local `int`. When the optimized loop's frame unwound, `ret` held a dangling pointer. Fix 1: The optimizer now heap-allocates the loop counter via `Boxed_Value(start_int)` and obtains a reference to the heap-allocated int for the native C++ loop. The Boxed_Value's shared_ptr ensures the storage outlives any copies. Fix 2: The `:=` operator now deep-copies arithmetic values via `Boxed_Number::clone` instead of the shallow `assign()`, ensuring value semantics. This also fixes a pre-existing aliasing bug where `a := b; ++b` would incorrectly mutate `a`. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
14 lines
212 B
ChaiScript
14 lines
212 B
ChaiScript
var func = fun(){
|
|
var ret = 0;
|
|
for (var i = 0; i < 1000; ++i) {
|
|
ret := i;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
var&fut1 = async(func);
|
|
var fut2 = async(func);
|
|
|
|
assert_equal(999, fut1.get())
|
|
assert_equal(999, fut2.get())
|