Skip to content

Commit

Permalink
FlexBuffers dumping can now support DAGs
Browse files Browse the repository at this point in the history
  • Loading branch information
aardappel committed Oct 31, 2024
1 parent 9be822e commit 6b6c2e7
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 10 deletions.
2 changes: 2 additions & 0 deletions dev/TODO.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
- mipmaps are darker than the orginal in both srgb and linear modes? see e.g. puzzlewindow.lobster

- Default ignoring return values is a really bad default, wonder if it is too late to change?
Ideally it would error on ignored return values unless the function explicitly marks a return
value as ignorable.
Expand Down
2 changes: 1 addition & 1 deletion dev/src/builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ nfr("tan", "angle", "F}", "F}",
[](StackPtr &sp, VM &) { VECTOROP(tan(f.fval() * RAD)); });

nfr("sincos", "angle", "F", "F}:2",
"the normalized vector indicated by angle (in degrees), same as xy { cos(angle), sin(angle) }",
"the normalized vector indicated by angle (in degrees), same as float2 { cos(angle), sin(angle) }",
[](StackPtr &sp, VM &) {
auto a = Pop(sp).fval();
PushVec(sp, double2(cos(a * RAD), sin(a * RAD)));
Expand Down
5 changes: 3 additions & 2 deletions dev/src/lobster/vmdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,15 +378,16 @@ struct ToFlexBufferContext {

bool ignore_unsupported_types = false;
bool cycle_detect = false;
set<LObject *> seen_objects;
map<LObject *, flexbuffers::Builder::Value> seen_objects;

iint max_depth = 100;
iint cur_depth = 0;

string max_depth_hit;
flexbuffers::Builder::Value max_depth_hit_value;
string cycle_hit;
flexbuffers::Builder::Value cycle_hit_value;

PrintPrefs pp = PrintPrefs(2, 50, true, -1);

ToFlexBufferContext(VM &vm, size_t initial_size, flexbuffers::BuilderFlag flags)
: vm(vm), builder(initial_size, flags) {}
Expand Down
29 changes: 22 additions & 7 deletions dev/src/vmdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,16 +614,28 @@ void ElemToFlexBuffer(ToFlexBufferContext &fbc, const TypeInfo &ti,
}

void LObject::ToFlexBuffer(ToFlexBufferContext &fbc) {
// Terrible C++: we need 2 variables to track this, because we can't init inserted_it
// with end() because it may get invalidated by the insert, and trying to test
// against the default constructed iterator is UB.
bool inserted = false;
map<LObject *, flexbuffers::Builder::Value>::iterator inserted_it;
if (fbc.cycle_detect) {
if (fbc.seen_objects.find(this) == fbc.seen_objects.end()) {
fbc.seen_objects.insert(this);
auto it = fbc.seen_objects.find(this);
if (it == fbc.seen_objects.end()) {
inserted = true;
inserted_it = fbc.seen_objects.insert({ this, flexbuffers::Builder::Value{} }).first;
} else {
fbc.cycle_hit = TypeName(fbc.vm);
if (fbc.cycle_hit_value.type_ == flexbuffers::FBT_NULL) {
fbc.builder.String("(dup_ref)");
fbc.cycle_hit_value = fbc.builder.LastValue();
if (it->second.type_ == flexbuffers::FBT_NULL) {
// A true cycle, object referred to while not finished.
fbc.cycle_hit = TypeName(fbc.vm);
string sd;
append(sd, "(cycle_ref: ", (size_t)this, ": ");
ToString(fbc.vm, sd, fbc.pp);
append(sd, ")");
fbc.builder.String(sd);
} else {
fbc.builder.ReuseValue(fbc.cycle_hit_value);
// Just a DAG ref, we just make the FlexBuffer a DAG as well!
fbc.builder.ReuseValue(it->second);
}
return;
}
Expand Down Expand Up @@ -655,6 +667,9 @@ void LObject::ToFlexBuffer(ToFlexBufferContext &fbc) {
ElemToFlexBuffer(fbc, eti, i, 1, Elems(), fname, stti.elemtypes[i].defval);
}
fbc.builder.EndMap(start);
if (inserted) {
inserted_it->second = fbc.builder.LastValue();
}
}

void LVector::ToFlexBuffer(ToFlexBufferContext &fbc) {
Expand Down

0 comments on commit 6b6c2e7

Please sign in to comment.