Line data Source code
1 : // Copyright 2015 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/v8.h"
6 :
7 : #include "src/interpreter/interpreter-intrinsics.h"
8 : #include "src/objects-inl.h"
9 : #include "test/cctest/interpreter/interpreter-tester.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 : namespace interpreter {
14 :
15 : namespace {
16 :
17 : class InvokeIntrinsicHelper {
18 : public:
19 : InvokeIntrinsicHelper(Isolate* isolate, Zone* zone,
20 : Runtime::FunctionId function_id)
21 : : isolate_(isolate),
22 : zone_(zone),
23 : factory_(isolate->factory()),
24 60 : function_id_(function_id) {}
25 :
26 : template <class... A>
27 396 : Handle<Object> Invoke(A... args) {
28 396 : CHECK(IntrinsicsHelper::IsSupported(function_id_));
29 396 : BytecodeArrayBuilder builder(isolate_, zone_, sizeof...(args), 0, 0);
30 792 : RegisterList reg_list(builder.Receiver().index(), sizeof...(args));
31 396 : builder.CallRuntime(function_id_, reg_list).Return();
32 792 : InterpreterTester tester(isolate_, builder.ToBytecodeArray(isolate_));
33 : auto callable = tester.GetCallable<A...>();
34 396 : return callable(args...).ToHandleChecked();
35 : }
36 :
37 384 : Handle<Object> NewObject(const char* script) {
38 384 : return v8::Utils::OpenHandle(*CompileRun(script));
39 : }
40 :
41 : Handle<Object> Undefined() { return factory_->undefined_value(); }
42 : Handle<Object> Null() { return factory_->null_value(); }
43 :
44 : private:
45 : Isolate* isolate_;
46 : Zone* zone_;
47 : Factory* factory_;
48 : Runtime::FunctionId function_id_;
49 : };
50 :
51 : } // namespace
52 :
53 23724 : TEST(IsJSReceiver) {
54 6 : HandleAndZoneScope handles;
55 :
56 : InvokeIntrinsicHelper helper(handles.main_isolate(), handles.main_zone(),
57 6 : Runtime::kInlineIsJSReceiver);
58 : Factory* factory = handles.main_isolate()->factory();
59 :
60 12 : CHECK_EQ(*factory->true_value(),
61 : *helper.Invoke(helper.NewObject("new Date()")));
62 12 : CHECK_EQ(*factory->true_value(),
63 : *helper.Invoke(helper.NewObject("(function() {})")));
64 12 : CHECK_EQ(*factory->true_value(), *helper.Invoke(helper.NewObject("([1])")));
65 12 : CHECK_EQ(*factory->true_value(), *helper.Invoke(helper.NewObject("({})")));
66 12 : CHECK_EQ(*factory->true_value(), *helper.Invoke(helper.NewObject("(/x/)")));
67 18 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Undefined()));
68 18 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Null()));
69 12 : CHECK_EQ(*factory->false_value(),
70 : *helper.Invoke(helper.NewObject("'string'")));
71 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("42")));
72 6 : }
73 :
74 23724 : TEST(IsArray) {
75 6 : HandleAndZoneScope handles;
76 :
77 : InvokeIntrinsicHelper helper(handles.main_isolate(), handles.main_zone(),
78 6 : Runtime::kInlineIsArray);
79 : Factory* factory = handles.main_isolate()->factory();
80 :
81 12 : CHECK_EQ(*factory->false_value(),
82 : *helper.Invoke(helper.NewObject("new Date()")));
83 12 : CHECK_EQ(*factory->false_value(),
84 : *helper.Invoke(helper.NewObject("(function() {})")));
85 12 : CHECK_EQ(*factory->true_value(), *helper.Invoke(helper.NewObject("([1])")));
86 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("({})")));
87 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("(/x/)")));
88 18 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Undefined()));
89 18 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Null()));
90 12 : CHECK_EQ(*factory->false_value(),
91 : *helper.Invoke(helper.NewObject("'string'")));
92 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("42")));
93 6 : }
94 :
95 23724 : TEST(IsJSProxy) {
96 6 : HandleAndZoneScope handles;
97 :
98 : InvokeIntrinsicHelper helper(handles.main_isolate(), handles.main_zone(),
99 6 : Runtime::kInlineIsJSProxy);
100 : Factory* factory = handles.main_isolate()->factory();
101 :
102 12 : CHECK_EQ(*factory->false_value(),
103 : *helper.Invoke(helper.NewObject("new Date()")));
104 12 : CHECK_EQ(*factory->false_value(),
105 : *helper.Invoke(helper.NewObject("(function() {})")));
106 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("([1])")));
107 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("({})")));
108 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("(/x/)")));
109 18 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Undefined()));
110 18 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Null()));
111 12 : CHECK_EQ(*factory->false_value(),
112 : *helper.Invoke(helper.NewObject("'string'")));
113 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("42")));
114 12 : CHECK_EQ(*factory->true_value(),
115 6 : *helper.Invoke(helper.NewObject("new Proxy({},{})")));
116 6 : }
117 :
118 23724 : TEST(IsTypedArray) {
119 6 : HandleAndZoneScope handles;
120 :
121 : InvokeIntrinsicHelper helper(handles.main_isolate(), handles.main_zone(),
122 6 : Runtime::kInlineIsTypedArray);
123 : Factory* factory = handles.main_isolate()->factory();
124 :
125 12 : CHECK_EQ(*factory->false_value(),
126 : *helper.Invoke(helper.NewObject("new Date()")));
127 12 : CHECK_EQ(*factory->false_value(),
128 : *helper.Invoke(helper.NewObject("(function() {})")));
129 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("([1])")));
130 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("({})")));
131 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("(/x/)")));
132 18 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Undefined()));
133 18 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Null()));
134 12 : CHECK_EQ(*factory->false_value(),
135 : *helper.Invoke(helper.NewObject("'string'")));
136 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("42")));
137 :
138 12 : CHECK_EQ(
139 : *factory->true_value(),
140 : *helper.Invoke(helper.NewObject("new Uint8Array(new ArrayBuffer(1));")));
141 12 : CHECK_EQ(
142 : *factory->true_value(),
143 : *helper.Invoke(helper.NewObject("new Uint16Array(new ArrayBuffer(2));")));
144 12 : CHECK_EQ(
145 : *factory->true_value(),
146 6 : *helper.Invoke(helper.NewObject("new Int32Array(new ArrayBuffer(4));")));
147 6 : }
148 :
149 23724 : TEST(IsSmi) {
150 6 : HandleAndZoneScope handles;
151 :
152 : InvokeIntrinsicHelper helper(handles.main_isolate(), handles.main_zone(),
153 6 : Runtime::kInlineIsSmi);
154 : Factory* factory = handles.main_isolate()->factory();
155 :
156 12 : CHECK_EQ(*factory->false_value(),
157 : *helper.Invoke(helper.NewObject("new Date()")));
158 12 : CHECK_EQ(*factory->false_value(),
159 : *helper.Invoke(helper.NewObject("(function() {})")));
160 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("([1])")));
161 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("({})")));
162 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("(/x/)")));
163 18 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Undefined()));
164 18 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Null()));
165 12 : CHECK_EQ(*factory->false_value(),
166 : *helper.Invoke(helper.NewObject("'string'")));
167 12 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("42.2")));
168 12 : CHECK_EQ(*factory->false_value(),
169 : *helper.Invoke(helper.NewObject("4294967297")));
170 12 : CHECK_EQ(*factory->true_value(), *helper.Invoke(helper.NewObject("42")));
171 6 : }
172 :
173 23724 : TEST(Call) {
174 6 : HandleAndZoneScope handles;
175 6 : Isolate* isolate = handles.main_isolate();
176 : Factory* factory = isolate->factory();
177 : InvokeIntrinsicHelper helper(isolate, handles.main_zone(),
178 : Runtime::kInlineCall);
179 :
180 12 : CHECK_EQ(Smi::FromInt(20),
181 : *helper.Invoke(helper.NewObject("(function() { return this.x; })"),
182 : helper.NewObject("({ x: 20 })")));
183 12 : CHECK_EQ(Smi::FromInt(50),
184 : *helper.Invoke(helper.NewObject("(function(arg1) { return arg1; })"),
185 : factory->undefined_value(),
186 : handle(Smi::FromInt(50), isolate)));
187 12 : CHECK_EQ(
188 : Smi::FromInt(20),
189 : *helper.Invoke(
190 : helper.NewObject("(function(a, b, c) { return a + b + c; })"),
191 : factory->undefined_value(), handle(Smi::FromInt(10), isolate),
192 6 : handle(Smi::FromInt(7), isolate), handle(Smi::FromInt(3), isolate)));
193 6 : }
194 :
195 23724 : TEST(IntrinsicAsStubCall) {
196 6 : HandleAndZoneScope handles;
197 6 : Isolate* isolate = handles.main_isolate();
198 : Factory* factory = isolate->factory();
199 : InvokeIntrinsicHelper to_number_helper(isolate, handles.main_zone(),
200 : Runtime::kInlineToNumber);
201 12 : CHECK_EQ(Smi::FromInt(46),
202 : *to_number_helper.Invoke(to_number_helper.NewObject("'46'")));
203 :
204 : InvokeIntrinsicHelper to_integer_helper(isolate, handles.main_zone(),
205 : Runtime::kInlineToInteger);
206 12 : CHECK_EQ(Smi::FromInt(502),
207 : *to_integer_helper.Invoke(to_integer_helper.NewObject("502.67")));
208 :
209 : InvokeIntrinsicHelper has_property_helper(isolate, handles.main_zone(),
210 : Runtime::kInlineHasProperty);
211 12 : CHECK_EQ(*factory->true_value(),
212 : *has_property_helper.Invoke(
213 : has_property_helper.NewObject("'x'"),
214 : has_property_helper.NewObject("({ x: 20 })")));
215 12 : CHECK_EQ(*factory->false_value(),
216 : *has_property_helper.Invoke(
217 : has_property_helper.NewObject("'y'"),
218 6 : has_property_helper.NewObject("({ x: 20 })")));
219 6 : }
220 :
221 23724 : TEST(ClassOf) {
222 6 : HandleAndZoneScope handles;
223 6 : Isolate* isolate = handles.main_isolate();
224 : Factory* factory = isolate->factory();
225 : InvokeIntrinsicHelper helper(handles.main_isolate(), handles.main_zone(),
226 : Runtime::kInlineClassOf);
227 12 : CHECK_EQ(*helper.Invoke(helper.NewObject("123")), *factory->null_value());
228 12 : CHECK_EQ(*helper.Invoke(helper.NewObject("'true'")), *factory->null_value());
229 12 : CHECK_EQ(*helper.Invoke(helper.NewObject("'foo'")), *factory->null_value());
230 18 : CHECK(helper.Invoke(helper.NewObject("({a:1})"))
231 : ->SameValue(*helper.NewObject("'Object'")));
232 18 : CHECK(helper.Invoke(helper.NewObject("(function foo() {})"))
233 : ->SameValue(*helper.NewObject("'Function'")));
234 18 : CHECK(helper.Invoke(helper.NewObject("new Date()"))
235 : ->SameValue(*helper.NewObject("'Date'")));
236 18 : CHECK(helper.Invoke(helper.NewObject("new Set"))
237 : ->SameValue(*helper.NewObject("'Set'")));
238 18 : CHECK(helper.Invoke(helper.NewObject("/x/"))
239 6 : ->SameValue(*helper.NewObject("'RegExp'")));
240 6 : }
241 :
242 : } // namespace interpreter
243 : } // namespace internal
244 71154 : } // namespace v8
|