Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/hx/cppia/CppiaVars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,12 @@ Dynamic CppiaVar::setValue(hx::Object *inThis, Dynamic inValue)
case fsInt: *(int *)(base) = inValue; return inValue;
case fsBool: *(bool *)(base) = inValue; return inValue;
case fsFloat: *(Float *)(base) = inValue; return inValue;
case fsString: *(String *)(base) = inValue; return inValue;
case fsString:
*(String *)(base) = inValue;
#ifdef HXCPP_GC_GENERATIONAL
HX_OBJ_WB_GET(inThis, hx::PointerOf(*(String *)(base)));
#endif
return inValue;
case fsObject:
switch(type->arrayType)
{
Expand Down Expand Up @@ -259,6 +264,10 @@ Dynamic CppiaVar::setValue(hx::Object *inThis, Dynamic inValue)
*(Array<Dynamic> *)(base) = inValue;
break;
}
// Every case above stores one object pointer at base.
#ifdef HXCPP_GC_GENERATIONAL
HX_OBJ_WB_GET(inThis, *(hx::Object **)(base));
#endif
return inValue;
case fsUnknown:
break;
Expand Down
7 changes: 7 additions & 0 deletions test/cppia/Client.hx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ class ClientFoo implements IFoo {
}
}

class ClientHolder {

public var values:Array<Int>;

public function new() {}
}

class Client
{
public static var clientBool0 = true;
Expand Down
23 changes: 23 additions & 0 deletions test/cppia/cases/TestCommon.hx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cases;

import cpp.cppia.Host;
import cpp.vm.Gc;
import cpp.vm.WeakRef;
import utest.Test;
import utest.Assert;

Expand Down Expand Up @@ -59,6 +61,27 @@ class TestCommon extends Test {
Assert.equals(2, Common.callbackSet, 'Bad cppia closure');
}

@:depends(testStatus)
function testSetFieldOfOldObject() {
final holder = Type.createInstance(Type.resolveClass('ClientHolder'), []);

// Full collections make the holder old: a generational collection no longer traverses it.
for (_ in 0...3) {
Gc.run(true);
}
final values = setValues(holder);
Gc.run(false);

Assert.notNull(values.get(), 'Freed a value set by name on an old object');
}

// Only a weak reference to the value leaves this frame, so that the stack does not keep it.
static function setValues(holder:Dynamic):WeakRef<Array<Int>> {
final values = [42];
Reflect.setField(holder, 'values', values);
return new WeakRef(values);
}

@:depends(testStatus)
function testInterfaceCalling() {
final obj : IFoo = Type.createInstance(Type.resolveClass('ClientFoo'), []);
Expand Down
1 change: 1 addition & 0 deletions test/cppia/compile-host.hxml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
-m CppiaHost
HostExtendedRoot
-D scriptable
-D HXCPP_GC_GENERATIONAL
-D dll_export=host_classes.info
-L utest
--dce no
Expand Down