1// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "platform/globals.h"
6
7#include "vm/isolate.h"
8#include "vm/object.h"
9#include "vm/regexp.h"
10#include "vm/regexp_assembler_ir.h"
11#include "vm/unit_test.h"
12
13namespace dart {
14
15static ArrayPtr Match(const String& pat, const String& str) {
16 Thread* thread = Thread::Current();
17 Zone* zone = thread->zone();
18 const RegExp& regexp =
19 RegExp::Handle(RegExpEngine::CreateRegExp(thread, pat, RegExpFlags()));
20 const Smi& idx = Object::smi_zero();
21 return IRRegExpMacroAssembler::Execute(regexp, str, idx, /*sticky=*/false,
22 zone);
23}
24
25ISOLATE_UNIT_TEST_CASE(RegExp_OneByteString) {
26 uint8_t chars[] = {'a', 'b', 'c', 'b', 'a'};
27 intptr_t len = ARRAY_SIZE(chars);
28 const String& str =
29 String::Handle(OneByteString::New(chars, len, Heap::kNew));
30
31 const String& pat = String::Handle(String::New("bc"));
32 const Array& res = Array::Handle(Match(pat, str));
33 EXPECT_EQ(2, res.Length());
34
35 const Object& res_1 = Object::Handle(res.At(0));
36 const Object& res_2 = Object::Handle(res.At(1));
37 EXPECT(res_1.IsSmi());
38 EXPECT(res_2.IsSmi());
39
40 const Smi& smi_1 = Smi::Cast(res_1);
41 const Smi& smi_2 = Smi::Cast(res_2);
42 EXPECT_EQ(1, smi_1.Value());
43 EXPECT_EQ(3, smi_2.Value());
44}
45
46ISOLATE_UNIT_TEST_CASE(RegExp_TwoByteString) {
47 uint16_t chars[] = {'a', 'b', 'c', 'b', 'a'};
48 intptr_t len = ARRAY_SIZE(chars);
49 const String& str =
50 String::Handle(TwoByteString::New(chars, len, Heap::kNew));
51
52 const String& pat = String::Handle(String::New("bc"));
53 const Array& res = Array::Handle(Match(pat, str));
54 EXPECT_EQ(2, res.Length());
55
56 const Object& res_1 = Object::Handle(res.At(0));
57 const Object& res_2 = Object::Handle(res.At(1));
58 EXPECT(res_1.IsSmi());
59 EXPECT(res_2.IsSmi());
60
61 const Smi& smi_1 = Smi::Cast(res_1);
62 const Smi& smi_2 = Smi::Cast(res_2);
63 EXPECT_EQ(1, smi_1.Value());
64 EXPECT_EQ(3, smi_2.Value());
65}
66
67static void NoopFinalizer(void* isolate_callback_data,
68 Dart_WeakPersistentHandle handle,
69 void* peer) {}
70
71ISOLATE_UNIT_TEST_CASE(RegExp_ExternalOneByteString) {
72 uint8_t chars[] = {'a', 'b', 'c', 'b', 'a'};
73 intptr_t len = ARRAY_SIZE(chars);
74 const String& str = String::Handle(ExternalOneByteString::New(
75 chars, len, NULL, 0, NoopFinalizer, Heap::kNew));
76
77 const String& pat = String::Handle(String::New("bc"));
78 const Array& res = Array::Handle(Match(pat, str));
79 EXPECT_EQ(2, res.Length());
80
81 const Object& res_1 = Object::Handle(res.At(0));
82 const Object& res_2 = Object::Handle(res.At(1));
83 EXPECT(res_1.IsSmi());
84 EXPECT(res_2.IsSmi());
85
86 const Smi& smi_1 = Smi::Cast(res_1);
87 const Smi& smi_2 = Smi::Cast(res_2);
88 EXPECT_EQ(1, smi_1.Value());
89 EXPECT_EQ(3, smi_2.Value());
90}
91
92ISOLATE_UNIT_TEST_CASE(RegExp_ExternalTwoByteString) {
93 uint16_t chars[] = {'a', 'b', 'c', 'b', 'a'};
94 intptr_t len = ARRAY_SIZE(chars);
95 const String& str = String::Handle(ExternalTwoByteString::New(
96 chars, len, NULL, 0, NoopFinalizer, Heap::kNew));
97
98 const String& pat = String::Handle(String::New("bc"));
99 const Array& res = Array::Handle(Match(pat, str));
100 EXPECT_EQ(2, res.Length());
101
102 const Object& res_1 = Object::Handle(res.At(0));
103 const Object& res_2 = Object::Handle(res.At(1));
104 EXPECT(res_1.IsSmi());
105 EXPECT(res_2.IsSmi());
106
107 const Smi& smi_1 = Smi::Cast(res_1);
108 const Smi& smi_2 = Smi::Cast(res_2);
109 EXPECT_EQ(1, smi_1.Value());
110 EXPECT_EQ(3, smi_2.Value());
111}
112
113} // namespace dart
114