Skip to content

Conversation

@ohhmm
Copy link
Owner

@ohhmm ohhmm commented Mar 25, 2025

No description provided.

Comment on lines +290 to +297
}
else if (impl->getTypeSize() <= getAllocSize())
{
Replace(std::move(*impl));
}
else {
IMPLEMENT
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple unimplemented code sections with IMPLEMENT macros:

else if (impl->getTypeSize() <= getAllocSize())
{
    Replace(std::move(*impl));
}
else {
    IMPLEMENT
}

There are numerous unimplemented code sections marked with IMPLEMENT macros throughout the codebase, including in the new Become(encapsulated_instance&&) method. These macros throw exceptions when reached, which could lead to unexpected runtime failures.

Recommendation: Implement these sections properly before merging, or add detailed TODO comments explaining the expected behavior and when implementation will be completed.

Comment on lines 112 to 119
if (newRadicand.IsPrincipalSurd())
break;
else {
update1(newRadicand);
update2(_2.shr());
// FIXME : update1(newRadicand); // should work too (Exponentiation_test)
// FIXME : update2(_2.shr());
update1(std::move(newRadicand));
update2(std::move(_2.shr()));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code optimization concerns in multiple files:

  1. In PrincipalSurd.cpp, there are commented out FIXME sections with alternative implementations:
// FIXME : update1(newRadicand);  // should work too (Exponentiation_test)
// FIXME : update2(_2.shr());
update1(std::move(newRadicand));
update2(std::move(_2.shr()));
  1. In Sum.cpp, complex expressions were broken down into multiple statements:
Become((e.getBase() ^ f.getNumerator()) - ((-(*this - member)) ^ f.getDenominator()));

Changed to:

auto baseExpNum = e.getBase() ^ f.getNumerator();
auto memMinThis = member - *this;
auto balancedNewValue = baseExpNum - (memMinThis ^ f.getDenominator());
Become(std::move(balancedNewValue));

While breaking down complex expressions improves readability, the commented FIXME sections and lack of documentation explaining the optimization rationale make it difficult to understand the intended behavior and verify correctness.

Recommendation: Add clear documentation explaining the optimization changes and remove or address the FIXME comments before merging.

Comment on lines 199 to +221
LOG_AND_IMPLEMENT("New for " << *this)
}

void Valuable::Replace(Valuable&& obj) {
clone_on_write();
auto sizeWas = getAllocSize();
auto newSize = obj.getTypeSize();
auto hashWas = obj.Hash();
auto newWasView = this->GetView();
assert(sizeWas >= newSize);
assert(DefaultAllocSize >= newSize && "Increase DefaultAllocSize");
char buf[DefaultAllocSize];
obj.New(buf, std::move(obj));
Valuable& bufv = *reinterpret_cast<Valuable*>(buf);
this->~Valuable();
bufv.New(this, std::move(bufv));
setAllocSize(sizeWas);
if (Hash() != hashWas) {
LOG_AND_IMPLEMENT("Hash mismatch in Become for " << *this)
}
SetView(newWasView);
optimize();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Memory Safety Concerns in Valuable::Replace Method

The new Replace method implementation has potential memory safety issues:

void Valuable::Replace(Valuable&& obj) {
    clone_on_write();
    auto sizeWas = getAllocSize();
    auto newSize = obj.getTypeSize();
    auto hashWas = obj.Hash();
    auto newWasView = this->GetView();
    assert(sizeWas >= newSize);
    assert(DefaultAllocSize >= newSize && "Increase DefaultAllocSize");
    char buf[DefaultAllocSize];
    obj.New(buf, std::move(obj));
    Valuable& bufv = *reinterpret_cast<Valuable*>(buf);
    this->~Valuable();
    bufv.New(this, std::move(bufv));
    setAllocSize(sizeWas);
    if (Hash() != hashWas) {
        LOG_AND_IMPLEMENT("Hash mismatch in Become for " << *this)
    }
    SetView(newWasView);
    optimize();
}

This pattern of using a fixed-size buffer (DefaultAllocSize) for temporary storage during object replacement relies on runtime assertions rather than compile-time guarantees. While there are assertion checks, these are only active in debug builds and don't prevent potential buffer overflows in release builds if object sizes exceed DefaultAllocSize.

Recommendations:

  1. Consider using dynamic memory allocation for the temporary buffer
  2. Add compile-time size checks where possible
  3. Document the size constraints and assumptions clearly
  4. Consider adding a size parameter to the New method to enable safer buffer management

Comment on lines 258 to +297
#endif
}

Valuable& Valuable::Become(int integer) {
Become(std::static_pointer_cast<Valuable>(std::make_shared<Integer>(integer)));
return *this;
}

void Valuable::Become(encapsulated_instance&& impl) {
while (impl->exp) {
impl = std::move(impl->exp);
}
auto h = impl->Hash();
clone_on_write();
auto isEncapsulatedInstance = Is<Valuable>();
if (exp
|| isEncapsulatedInstance
|| impl->getTypeSize() > getAllocSize()
)
{
if (isEncapsulatedInstance) {
DispatchDispose(std::move(exp));
exp = std::move(impl);
} else {
auto allocSize = getAllocSize();
this->~Valuable();
new (this) Valuable(std::move(impl));
setAllocSize(allocSize);
}
if (Hash() != h) {
LOG_AND_IMPLEMENT("Hash mismatch in Become for " << *this)
}
}
else if (impl->getTypeSize() <= getAllocSize())
{
Replace(std::move(*impl));
}
else {
IMPLEMENT
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unimplemented Code Sections with IMPLEMENT Macros

There are numerous unimplemented code sections marked with IMPLEMENT macros throughout the codebase, including in the new Become(encapsulated_instance&&) method:

void Valuable::Become(encapsulated_instance&& impl) {
    while (impl->exp) {
        impl = std::move(impl->exp);
    }
    auto h = impl->Hash();
    clone_on_write();
    auto isEncapsulatedInstance = Is<Valuable>();
    if (exp
        || isEncapsulatedInstance
        || impl->getTypeSize() > getAllocSize()
        )
    {
        if (isEncapsulatedInstance) {
            DispatchDispose(std::move(exp));
            exp = std::move(impl);
        } else {
            auto allocSize = getAllocSize();
            this->~Valuable();
            new (this) Valuable(std::move(impl));
            setAllocSize(allocSize);
        }
        if (Hash() != h) {
            LOG_AND_IMPLEMENT("Hash mismatch in Become for " << *this)
        }
    }
    else if (impl->getTypeSize() <= getAllocSize())
    {
        Replace(std::move(*impl));
    }
    else {
        IMPLEMENT
    }
}

The IMPLEMENT macro throws exceptions when reached, which could lead to unexpected runtime failures. This is particularly concerning in a method that handles memory management and object state transitions.

Recommendations:

  1. Implement the missing code sections before merging
  2. If implementation is deferred, add detailed TODO comments explaining the expected behavior and when implementation will be completed
  3. Consider adding fallback behavior for unimplemented sections rather than throwing exceptions
  4. Add tests that verify the implemented paths work correctly

Comment on lines 112 to +117
if (newRadicand.IsPrincipalSurd())
break;
else {
update1(newRadicand);
update2(_2.shr());
// FIXME : update1(newRadicand); // should work too (Exponentiation_test)
// FIXME : update2(_2.shr());
update1(std::move(newRadicand));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Optimization Concerns in Multiple Files

There are several optimization-related issues across the changed files:

  1. In PrincipalSurd.cpp, there are commented out FIXME sections with alternative implementations:
// FIXME : update1(newRadicand);  // should work too (Exponentiation_test)
// FIXME : update2(_2.shr());
update1(std::move(newRadicand));
update2(std::move(_2.shr()));

The commented FIXME sections suggest uncertainty about the correctness of the implementation. The change from direct parameter passing to using std::move could have performance implications, but it's unclear if this has been thoroughly tested.

  1. In Sum.cpp, complex expressions were broken down into multiple statements:
// Original:
Become((e.getBase() ^ f.getNumerator()) - ((-(*this - member)) ^ f.getDenominator()));

// Changed to:
auto baseExpNum = e.getBase() ^ f.getNumerator();
auto memMinThis = member - *this;
auto balancedNewValue = baseExpNum - (memMinThis ^ f.getDenominator());
Become(std::move(balancedNewValue));

While breaking down complex expressions improves readability, the lack of documentation explaining the optimization rationale makes it difficult to understand the intended behavior and verify correctness.

Recommendations:

  1. Remove or address the FIXME comments before merging
  2. Add clear documentation explaining the optimization changes and their rationale
  3. Include test cases that verify the optimized code paths work correctly
  4. Consider adding performance benchmarks to validate optimization improvements

@ohhmm ohhmm force-pushed the become branch 2 times, most recently from 5a2d548 to aad5dc1 Compare March 29, 2025 20:21
Comment on lines 199 to +221
LOG_AND_IMPLEMENT("New for " << *this)
}

void Valuable::Replace(Valuable&& obj) {
clone_on_write();
auto sizeWas = getAllocSize();
auto newSize = obj.getTypeSize();
auto hashWas = obj.Hash();
auto newWasView = this->GetView();
assert(sizeWas >= newSize);
assert(DefaultAllocSize >= newSize && "Increase DefaultAllocSize");
char buf[DefaultAllocSize];
obj.New(buf, std::move(obj));
Valuable& bufv = *reinterpret_cast<Valuable*>(buf);
this->~Valuable();
bufv.New(this, std::move(bufv));
setAllocSize(sizeWas);
if (Hash() != hashWas) {
LOG_AND_IMPLEMENT("Hash mismatch in Become for " << *this)
}
SetView(newWasView);
optimize();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Memory Safety Concerns in Valuable::Replace Method

The new Replace method implementation has potential memory safety issues:

void Valuable::Replace(Valuable&& obj) {
    clone_on_write();
    auto sizeWas = getAllocSize();
    auto newSize = obj.getTypeSize();
    auto hashWas = obj.Hash();
    auto newWasView = this->GetView();
    assert(sizeWas >= newSize);
    assert(DefaultAllocSize >= newSize && "Increase DefaultAllocSize");
    char buf[DefaultAllocSize];
    obj.New(buf, std::move(obj));
    Valuable& bufv = *reinterpret_cast<Valuable*>(buf);
    this->~Valuable();
    bufv.New(this, std::move(bufv));
    setAllocSize(sizeWas);
    // ...
}

This pattern of using a fixed-size buffer (DefaultAllocSize) for temporary storage during object replacement relies on runtime assertions rather than compile-time guarantees. While there are assertion checks, these are only active in debug builds and don't prevent potential buffer overflows in release builds if object sizes exceed DefaultAllocSize.

Recommendations:

  1. Consider using dynamic memory allocation for the temporary buffer
  2. Add compile-time size checks where possible
  3. Document the size constraints and assumptions clearly
  4. Consider adding a size parameter to the New method to enable safer buffer management

Comment on lines 258 to +296
#endif
}

Valuable& Valuable::Become(int integer) {
Become(std::static_pointer_cast<Valuable>(std::make_shared<Integer>(integer)));
return *this;
}

void Valuable::Become(encapsulated_instance&& impl) {
while (impl->exp) {
impl = std::move(impl->exp);
}
auto h = impl->Hash();
clone_on_write();
auto isEncapsulatedInstance = Is<Valuable>();
if (exp
|| isEncapsulatedInstance
|| impl->getTypeSize() > getAllocSize()
)
{
if (isEncapsulatedInstance) {
DispatchDispose(std::move(exp));
exp = std::move(impl);
} else {
auto allocSize = getAllocSize();
this->~Valuable();
new (this) Valuable(std::move(impl));
setAllocSize(allocSize);
}
if (Hash() != h) {
LOG_AND_IMPLEMENT("Hash mismatch in Become for " << *this)
}
}
else if (impl->getTypeSize() <= getAllocSize())
{
Replace(std::move(*impl));
}
else {
IMPLEMENT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unimplemented Code Sections with IMPLEMENT Macros

There are unimplemented code sections marked with IMPLEMENT macros in the new Become(encapsulated_instance&&) method:

void Valuable::Become(encapsulated_instance&& impl) {
    // ...
    else if (impl->getTypeSize() <= getAllocSize())
    {
        Replace(std::move(*impl));
    }
    else {
        IMPLEMENT
    }
}

The IMPLEMENT macro throws exceptions when reached, which could lead to unexpected runtime failures. This is particularly concerning in a method that handles memory management and object state transitions.

Recommendations:

  1. Implement the missing code sections before merging
  2. If implementation is deferred, add detailed TODO comments explaining the expected behavior and when implementation will be completed
  3. Consider adding fallback behavior for unimplemented sections rather than throwing exceptions
  4. Add tests that verify the implemented paths work correctly

Comment on lines 112 to 119
if (newRadicand.IsPrincipalSurd())
break;
else {
update1(newRadicand);
update2(_2.shr());
// FIXME : update1(newRadicand); // should work too (Exponentiation_test)
// FIXME : update2(_2.shr());
update1(std::move(newRadicand));
update2(std::move(_2.shr()));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Optimization Concerns in Multiple Files

There are several optimization-related issues across the changed files:

  1. In PrincipalSurd.cpp, there are commented out FIXME sections with alternative implementations:
// FIXME : update1(newRadicand);  // should work too (Exponentiation_test)
// FIXME : update2(_2.shr());
update1(std::move(newRadicand));
update2(std::move(_2.shr()));

The commented FIXME sections suggest uncertainty about the correctness of the implementation. The change from direct parameter passing to using std::move could have performance implications, but it's unclear if this has been thoroughly tested.

  1. In Sum.cpp, complex expressions were broken down into multiple statements without clear documentation:
// Original:
Become((e.getBase() ^ f.getNumerator()) - ((-(*this - member)) ^ f.getDenominator()));

// Changed to:
auto baseExpNum = e.getBase() ^ f.getNumerator();
auto memMinThis = member - *this;
auto balancedNewValue = baseExpNum - (memMinThis ^ f.getDenominator());
Become(std::move(balancedNewValue));

Recommendations:

  1. Remove or address the FIXME comments before merging
  2. Add clear documentation explaining the optimization changes and their rationale
  3. Include test cases that verify the optimized code paths work correctly
  4. Consider adding performance benchmarks to validate optimization improvements

Repository owner deleted a comment from devin-ai-integration bot Mar 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants