Skip to content

Commit

Permalink
Made weak pointers strong while RE2 is running. Fixes #214.
Browse files Browse the repository at this point in the history
  • Loading branch information
uhop committed Aug 22, 2024
1 parent 7530962 commit 0e3b06f
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 9 deletions.
18 changes: 15 additions & 3 deletions lib/addon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ const StrVal &WrappedRE2::prepareArgument(const v8::Local<v8::Value> &arg, bool
if (lastString == arg && !node::Buffer::HasInstance(arg) && !lastCache.IsEmpty())
{
// we have a properly cached string
lastString.ClearWeak();
lastCache.ClearWeak();
lastStringValue.setIndex(startFrom);
return lastStringValue;
}
Expand All @@ -130,7 +132,6 @@ const StrVal &WrappedRE2::prepareArgument(const v8::Local<v8::Value> &arg, bool
// no need to cache buffers

lastString.Reset(arg);
static_cast<v8::PersistentBase<v8::Value> &>(lastString).SetWeak();

auto argSize = node::Buffer::Length(arg);
lastStringValue.reset(arg, argSize, argSize, startFrom, true);
Expand All @@ -149,21 +150,32 @@ const StrVal &WrappedRE2::prepareArgument(const v8::Local<v8::Value> &arg, bool
}

lastString.Reset(arg);
static_cast<v8::PersistentBase<v8::Value> &>(lastString).SetWeak();

auto s = t.ToLocalChecked();
auto argLength = Nan::DecodeBytes(s);

auto buffer = node::Buffer::New(v8::Isolate::GetCurrent(), s).ToLocalChecked();
lastCache.Reset(buffer);
static_cast<v8::PersistentBase<v8::Object> &>(lastCache).SetWeak();

auto argSize = node::Buffer::Length(buffer);
lastStringValue.reset(buffer, argSize, argLength, startFrom);

return lastStringValue;
};

void WrappedRE2::doneWithLastString()
{
if (!lastString.IsEmpty())
{
static_cast<v8::PersistentBase<v8::Value> &>(lastString).SetWeak();
}

if (!lastCache.IsEmpty())
{
static_cast<v8::PersistentBase<v8::Object> &>(lastCache).SetWeak();
}
}

// StrVal

void StrVal::setIndex(size_t newIndex)
Expand Down
3 changes: 2 additions & 1 deletion lib/exec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ NAN_METHOD(WrappedRE2::Exec)
return;
}

auto str = re2->prepareArgument(info[0]);
PrepareLastString prep(re2, info[0]);
StrVal& str = prep;
if (str.isBad) return; // throws an exception

if (re2->global || re2->sticky)
Expand Down
3 changes: 2 additions & 1 deletion lib/match.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ NAN_METHOD(WrappedRE2::Match)
return;
}

auto str = re2->prepareArgument(info[0], re2->global);
PrepareLastString prep(re2, info[0]);
StrVal& str = prep;
if (str.isBad) return; // throws an exception

if (!str.isValidIndex)
Expand Down
3 changes: 2 additions & 1 deletion lib/replace.cc
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,8 @@ NAN_METHOD(WrappedRE2::Replace)
return;
}

auto replacee = re2->prepareArgument(info[0]);
PrepareLastString prep(re2, info[0]);
StrVal& replacee = prep;
if (replacee.isBad) return; // throws an exception

if (!replacee.isValidIndex)
Expand Down
3 changes: 2 additions & 1 deletion lib/search.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ NAN_METHOD(WrappedRE2::Search)
return;
}

auto str = re2->prepareArgument(info[0], true);
PrepareLastString prep(re2, info[0]);
StrVal& str = prep;
if (str.isBad) return; // throws an exception

if (!str.data)
Expand Down
3 changes: 2 additions & 1 deletion lib/split.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ NAN_METHOD(WrappedRE2::Split)
return;
}

auto str = re2->prepareArgument(info[0], true);
PrepareLastString prep(re2, info[0]);
StrVal& str = prep;
if (str.isBad) return; // throws an exception

size_t limit = std::numeric_limits<size_t>::max();
Expand Down
3 changes: 2 additions & 1 deletion lib/test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ NAN_METHOD(WrappedRE2::Test)
return;
}

auto str = re2->prepareArgument(info[0]);
PrepareLastString prep(re2, info[0]);
StrVal& str = prep;
if (str.isBad) return; // throws an exception

if (!re2->global && !re2->sticky)
Expand Down
24 changes: 24 additions & 0 deletions lib/wrapped_re2.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,30 @@ class WrappedRE2 : public Nan::ObjectWrap

void dropCache();
const StrVal &prepareArgument(const v8::Local<v8::Value> &arg, bool ignoreLastIndex = false);
void doneWithLastString();

friend class PrepareLastString;
};

struct PrepareLastString
{
PrepareLastString(WrappedRE2 *re2, const v8::Local<v8::Value> &arg, bool ignoreLastIndex = false) : re2(re2) {
re2->prepareArgument(arg, ignoreLastIndex);
}

~PrepareLastString() {
re2->doneWithLastString();
}

operator const StrVal&() const {
return re2->lastStringValue;
}

operator StrVal&() {
return re2->lastStringValue;
}

WrappedRE2 *re2;
};

// utilities
Expand Down

0 comments on commit 0e3b06f

Please sign in to comment.