X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Floader%2FInterpreter.cpp;fp=src%2Floader%2FInterpreter.cpp;h=8f9e9dc6eff141aa69a1d5d13ad4662293b4b329;hb=dc275497c592669dda75645604a9b35d32f63e90;hp=cb15a035185512b8127d6a1206850a46b0a6fe01;hpb=0b11a24a8b08c49d6e4301573602fb6d01e7a8c8;p=l2e.git diff --git a/src/loader/Interpreter.cpp b/src/loader/Interpreter.cpp index cb15a03..8f9e9dc 100644 --- a/src/loader/Interpreter.cpp +++ b/src/loader/Interpreter.cpp @@ -286,28 +286,45 @@ void Interpreter::ReadObject(int typeId, int id, char *object, const PropertyLis char *dest(object + fd.Offset()); if (fd.IsAggregate()) { int arraySize(i->second->GetLiteral().ArraySize()); - char *aggregate; + size_t memberSize = fd.IsReferenced() ? sizeof(char *) : fieldType.Size(); + char *aggregate = alloc.Alloc(arraySize * memberSize); + char *iter = aggregate; if (i->second->GetLiteral().GetType() == Literal::ARRAY_PROPS) { - aggregate = alloc.Alloc(fieldType.Size() * arraySize); - char *iter = aggregate; const vector &list(i->second->GetLiteral().GetPropertyLists()); - for (vector::const_iterator j(list.begin()), end(list.end()); j != end; ++j, iter += fieldType.Size()) { - fieldType.Construct(iter); - ReadObject(fieldType.TypeId(), -1, iter, **j); + for (vector::const_iterator j(list.begin()), end(list.end()); + j != end; ++j, iter += memberSize) { + char *member; + if (fd.IsReferenced()) { + member = alloc.Alloc(fieldType.Size()); + *reinterpret_cast(iter) = member; + } else { + member = iter; + } + fieldType.Construct(member); + ReadObject(fieldType.TypeId(), -1, member, **j); } } else if (i->second->GetLiteral().GetType() == Literal::ARRAY_VALUES) { - aggregate = alloc.Alloc(fieldType.Size() * arraySize); - char *iter = aggregate; const vector &list(i->second->GetLiteral().GetValues()); - for (vector::const_iterator j(list.begin()), end(list.end()); j != end; ++j, iter += fieldType.Size()) { - fieldType.Construct(iter); - ReadLiteral(fieldType.TypeId(), -1, iter, (*j)->GetLiteral()); + for (vector::const_iterator j(list.begin()), end(list.end()); + j != end; ++j, iter += memberSize) { + char *member; + if (fd.IsReferenced()) { + member = alloc.Alloc(fieldType.Size()); + *reinterpret_cast(iter) = member; + } else { + member = iter; + } + fieldType.Construct(member); + ReadLiteral(fieldType.TypeId(), -1, member, (*j)->GetLiteral()); } } else { - aggregate = alloc.Alloc(sizeof(char *) * arraySize); - char *iter = aggregate; + if (!fd.IsReferenced()) { + // TODO: implement inline identifier arrays + throw std::runtime_error("inline identifier arrays not implemented (yet)"); + } const vector &list(i->second->GetLiteral().GetIdentifiers()); - for (vector::const_iterator j(list.begin()), end(list.end()); j != end; ++j, iter += sizeof(void *)) { + for (vector::const_iterator j(list.begin()), end(list.end()); + j != end; ++j, iter += memberSize) { if (source.IsDefined(*j)) { *reinterpret_cast(iter) = GetObject(fd.TypeId(), *j); @@ -316,13 +333,9 @@ void Interpreter::ReadObject(int typeId, int id, char *object, const PropertyLis } } } - if (fd.IsReferenced()) { - std::memcpy(dest, &aggregate, sizeof(char *)); - dest += sizeof(char *); - std::memcpy(dest, &arraySize, sizeof(int)); - } else { - throw Error("aggregate type fields must be referenced"); - } + std::memcpy(dest, &aggregate, sizeof(char *)); + dest += sizeof(char *); + std::memcpy(dest, &arraySize, sizeof(int)); } else if (i->second->IsLiteral() && !fd.IsReferenced()) { // inline literals if (i->second->GetLiteral().IsObject()) {