[vm/regexp] Ensure regex sent in a message can be used by the receiver.

Fixes https://github.com/dart-lang/sdk/issues/46294

TEST=reg_exp_receive_port_test.dart

Change-Id: Ic9ecde42224d44035ecb60347e11aae0bd92cd09
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/202861
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Alexander Aprelev 2021-06-09 02:50:50 +00:00 committed by commit-bot@chromium.org
parent 8d3ef92cb8
commit db17c490f8
9 changed files with 95 additions and 19 deletions

View file

@ -50,6 +50,7 @@
#include "vm/object_store.h"
#include "vm/parser.h"
#include "vm/profiler.h"
#include "vm/regexp.h"
#include "vm/resolver.h"
#include "vm/reusable_handles.h"
#include "vm/runtime_entry.h"
@ -25489,7 +25490,7 @@ void RegExp::set_capture_name_map(const Array& array) const {
untag()->set_capture_name_map(array.ptr());
}
RegExpPtr RegExp::New(Heap::Space space) {
RegExpPtr RegExp::New(Zone* zone, Heap::Space space) {
RegExp& result = RegExp::Handle();
{
ObjectPtr raw =
@ -25503,6 +25504,21 @@ RegExpPtr RegExp::New(Heap::Space space) {
result.set_num_registers(/*is_one_byte=*/false, -1);
result.set_num_registers(/*is_one_byte=*/true, -1);
}
if (!FLAG_interpret_irregexp) {
auto thread = Thread::Current();
const Library& lib = Library::Handle(zone, Library::CoreLibrary());
const Class& owner =
Class::Handle(zone, lib.LookupClass(Symbols::RegExp()));
for (intptr_t cid = kOneByteStringCid; cid <= kExternalTwoByteStringCid;
cid++) {
CreateSpecializedFunction(thread, zone, result, cid, /*sticky=*/false,
owner);
CreateSpecializedFunction(thread, zone, result, cid, /*sticky=*/true,
owner);
}
}
return result.ptr();
}

View file

@ -11427,7 +11427,7 @@ class RegExp : public Instance {
return RoundedAllocationSize(sizeof(UntaggedRegExp));
}
static RegExpPtr New(Heap::Space space = Heap::kNew);
static RegExpPtr New(Zone* zone, Heap::Space space = Heap::kNew);
private:
void set_type(RegExType type) const {

View file

@ -7,6 +7,7 @@
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/regexp.h"
#include "vm/snapshot.h"
#include "vm/stub_code.h"
#include "vm/symbols.h"
@ -1748,9 +1749,9 @@ RegExpPtr RegExp::ReadFrom(SnapshotReader* reader,
Snapshot::Kind kind,
bool as_reference) {
ASSERT(reader != NULL);
// Allocate RegExp object.
RegExp& regex = RegExp::ZoneHandle(reader->zone(), RegExp::New());
RegExp& regex =
RegExp::ZoneHandle(reader->zone(), RegExp::New(reader->zone()));
reader->AddBackRef(object_id, &regex, kIsDeserialized);
// Read and Set all the other fields.
@ -1766,14 +1767,6 @@ RegExpPtr RegExp::ReadFrom(SnapshotReader* reader,
regex.StoreNonPointer(&regex.untag()->num_two_byte_registers_,
reader->Read<int32_t>());
regex.StoreNonPointer(&regex.untag()->type_flags_, reader->Read<int8_t>());
const Function& no_function = Function::Handle(reader->zone());
for (intptr_t cid = kOneByteStringCid; cid <= kExternalTwoByteStringCid;
cid++) {
regex.set_function(cid, /*sticky=*/false, no_function);
regex.set_function(cid, /*sticky=*/true, no_function);
}
return regex.ptr();
}

View file

@ -5515,12 +5515,12 @@ RegExpEngine::CompilationResult RegExpEngine::CompileBytecode(
return result;
}
static void CreateSpecializedFunction(Thread* thread,
Zone* zone,
const RegExp& regexp,
intptr_t specialization_cid,
bool sticky,
const Object& owner) {
void CreateSpecializedFunction(Thread* thread,
Zone* zone,
const RegExp& regexp,
intptr_t specialization_cid,
bool sticky,
const Object& owner) {
const intptr_t kParamCount = RegExpMacroAssembler::kParamCount;
const FunctionType& signature =
@ -5569,7 +5569,7 @@ RegExpPtr RegExpEngine::CreateRegExp(Thread* thread,
const String& pattern,
RegExpFlags flags) {
Zone* zone = thread->zone();
const RegExp& regexp = RegExp::Handle(RegExp::New());
const RegExp& regexp = RegExp::Handle(RegExp::New(zone));
regexp.set_pattern(pattern);
regexp.set_flags(flags);

View file

@ -1517,6 +1517,13 @@ class RegExpEngine : public AllStatic {
static void DotPrint(const char* label, RegExpNode* node, bool ignore_case);
};
void CreateSpecializedFunction(Thread* thread,
Zone* zone,
const RegExp& regexp,
intptr_t specialization_cid,
bool sticky,
const Object& owner);
} // namespace dart
#endif // RUNTIME_VM_REGEXP_H_

View file

@ -56,6 +56,9 @@ bigint_test/15: SkipSlow # --no_intrinsify
regexp/global_test: Skip # Issue 21709
regexp/pcre_test: Slow, Pass
[ $runtime != vm ]
reg_exp_receive_port_test : Skip # uses SendPort/ReceivePort
[ $hot_reload || $hot_reload_rollback ]
bigint_parse_radix_test: Skip # Issue 31659. Issue 34361.
bigint_test: Skip # Issue 31659

View file

@ -0,0 +1,26 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// Checks that you can send and receive regex in a message.
import "dart:async";
import "dart:isolate";
import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
main(args) async {
asyncStart();
final rp = ReceivePort();
final r = RegExp('b');
Expect.equals(r.firstMatch('bb')!.start, 0);
rp.sendPort.send(r);
final si = StreamIterator(rp);
await si.moveNext();
final x = si.current as RegExp;
Expect.equals(x.firstMatch('bb')!.start, 0);
rp.close();
asyncEnd();
}

View file

@ -16,6 +16,9 @@ regexp/pcre_test: Slow, Pass # Issue 22008
[ $runtime != none ]
string_runes_test: Skip # See breaking change #40674
[ $runtime != vm ]
reg_exp_receive_port_test: Skip # uses SendPort/ReceivePort
[ $system == android ]
throw_half_surrogate_pair_test/*: Skip # Issue http://dartbug.com/42094

View file

@ -0,0 +1,28 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// Checks that you can send and receive regex in a message.
import "dart:async";
import "dart:isolate";
import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
main(args) async {
asyncStart();
final rp = ReceivePort();
final r = RegExp('b');
final match = r.firstMatch('bb');
Expect.equals(match != null ? match.start : null, 0);
rp.sendPort.send(r);
final si = StreamIterator(rp);
await si.moveNext();
final x = si.current as RegExp;
final matchX = x.firstMatch('bb');
Expect.equals(matchX != null ? matchX.start : null, 0);
rp.close();
asyncEnd();
}