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/api-inl.h"
8 : #include "src/interpreter/interpreter-intrinsics.h"
9 : #include "src/objects-inl.h"
10 : #include "test/cctest/interpreter/interpreter-tester.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 : namespace interpreter {
15 :
16 : namespace {
17 :
18 : class InvokeIntrinsicHelper {
19 : public:
20 : InvokeIntrinsicHelper(Isolate* isolate, Zone* zone,
21 : Runtime::FunctionId function_id)
22 : : isolate_(isolate),
23 : zone_(zone),
24 : factory_(isolate->factory()),
25 30 : function_id_(function_id) {}
26 :
27 : template <class... A>
28 230 : Handle<Object> Invoke(A... args) {
29 230 : CHECK(IntrinsicsHelper::IsSupported(function_id_));
30 230 : BytecodeArrayBuilder builder(zone_, sizeof...(args), 0, nullptr);
31 : RegisterList reg_list = InterpreterTester::NewRegisterList(
32 460 : builder.Receiver().index(), sizeof...(args));
33 230 : builder.CallRuntime(function_id_, reg_list).Return();
34 460 : InterpreterTester tester(isolate_, builder.ToBytecodeArray(isolate_));
35 : auto callable = tester.GetCallable<A...>();
36 230 : return callable(args...).ToHandleChecked();
37 : }
38 :
39 205 : Handle<Object> NewObject(const char* script) {
40 205 : return v8::Utils::OpenHandle(*CompileRun(script));
41 : }
42 :
43 : Handle<Object> Undefined() { return factory_->undefined_value(); }
44 : Handle<Object> Null() { return factory_->null_value(); }
45 :
46 : private:
47 : Isolate* isolate_;
48 : Zone* zone_;
49 : Factory* factory_;
50 : Runtime::FunctionId function_id_;
51 : };
52 :
53 : } // namespace
54 :
55 28342 : TEST(IsJSReceiver) {
56 5 : HandleAndZoneScope handles;
57 :
58 : InvokeIntrinsicHelper helper(handles.main_isolate(), handles.main_zone(),
59 5 : Runtime::kInlineIsJSReceiver);
60 : Factory* factory = handles.main_isolate()->factory();
61 :
62 20 : CHECK_EQ(*factory->true_value(),
63 : *helper.Invoke(helper.NewObject("new Date()")));
64 20 : CHECK_EQ(*factory->true_value(),
65 : *helper.Invoke(helper.NewObject("(function() {})")));
66 20 : CHECK_EQ(*factory->true_value(), *helper.Invoke(helper.NewObject("([1])")));
67 20 : CHECK_EQ(*factory->true_value(), *helper.Invoke(helper.NewObject("({})")));
68 20 : CHECK_EQ(*factory->true_value(), *helper.Invoke(helper.NewObject("(/x/)")));
69 25 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Undefined()));
70 25 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Null()));
71 20 : CHECK_EQ(*factory->false_value(),
72 : *helper.Invoke(helper.NewObject("'string'")));
73 20 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("42")));
74 5 : }
75 :
76 28342 : TEST(IsArray) {
77 5 : HandleAndZoneScope handles;
78 :
79 : InvokeIntrinsicHelper helper(handles.main_isolate(), handles.main_zone(),
80 5 : Runtime::kInlineIsArray);
81 : Factory* factory = handles.main_isolate()->factory();
82 :
83 20 : CHECK_EQ(*factory->false_value(),
84 : *helper.Invoke(helper.NewObject("new Date()")));
85 20 : CHECK_EQ(*factory->false_value(),
86 : *helper.Invoke(helper.NewObject("(function() {})")));
87 20 : CHECK_EQ(*factory->true_value(), *helper.Invoke(helper.NewObject("([1])")));
88 20 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("({})")));
89 20 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("(/x/)")));
90 25 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Undefined()));
91 25 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Null()));
92 20 : CHECK_EQ(*factory->false_value(),
93 : *helper.Invoke(helper.NewObject("'string'")));
94 20 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("42")));
95 5 : }
96 :
97 28342 : TEST(IsTypedArray) {
98 5 : HandleAndZoneScope handles;
99 :
100 : InvokeIntrinsicHelper helper(handles.main_isolate(), handles.main_zone(),
101 5 : Runtime::kInlineIsTypedArray);
102 : Factory* factory = handles.main_isolate()->factory();
103 :
104 20 : CHECK_EQ(*factory->false_value(),
105 : *helper.Invoke(helper.NewObject("new Date()")));
106 20 : CHECK_EQ(*factory->false_value(),
107 : *helper.Invoke(helper.NewObject("(function() {})")));
108 20 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("([1])")));
109 20 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("({})")));
110 20 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("(/x/)")));
111 25 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Undefined()));
112 25 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Null()));
113 20 : CHECK_EQ(*factory->false_value(),
114 : *helper.Invoke(helper.NewObject("'string'")));
115 20 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("42")));
116 :
117 20 : CHECK_EQ(
118 : *factory->true_value(),
119 : *helper.Invoke(helper.NewObject("new Uint8Array(new ArrayBuffer(1));")));
120 20 : CHECK_EQ(
121 : *factory->true_value(),
122 : *helper.Invoke(helper.NewObject("new Uint16Array(new ArrayBuffer(2));")));
123 20 : CHECK_EQ(
124 : *factory->true_value(),
125 5 : *helper.Invoke(helper.NewObject("new Int32Array(new ArrayBuffer(4));")));
126 5 : }
127 :
128 28342 : TEST(IsSmi) {
129 5 : HandleAndZoneScope handles;
130 :
131 : InvokeIntrinsicHelper helper(handles.main_isolate(), handles.main_zone(),
132 5 : Runtime::kInlineIsSmi);
133 : Factory* factory = handles.main_isolate()->factory();
134 :
135 20 : CHECK_EQ(*factory->false_value(),
136 : *helper.Invoke(helper.NewObject("new Date()")));
137 20 : CHECK_EQ(*factory->false_value(),
138 : *helper.Invoke(helper.NewObject("(function() {})")));
139 20 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("([1])")));
140 20 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("({})")));
141 20 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("(/x/)")));
142 25 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Undefined()));
143 25 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Null()));
144 20 : CHECK_EQ(*factory->false_value(),
145 : *helper.Invoke(helper.NewObject("'string'")));
146 20 : CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("42.2")));
147 20 : CHECK_EQ(*factory->false_value(),
148 : *helper.Invoke(helper.NewObject("4294967297")));
149 20 : CHECK_EQ(*factory->true_value(), *helper.Invoke(helper.NewObject("42")));
150 5 : }
151 :
152 28342 : TEST(Call) {
153 5 : HandleAndZoneScope handles;
154 5 : Isolate* isolate = handles.main_isolate();
155 : Factory* factory = isolate->factory();
156 : InvokeIntrinsicHelper helper(isolate, handles.main_zone(),
157 : Runtime::kInlineCall);
158 :
159 15 : CHECK_EQ(Smi::FromInt(20),
160 : *helper.Invoke(helper.NewObject("(function() { return this.x; })"),
161 : helper.NewObject("({ x: 20 })")));
162 15 : CHECK_EQ(Smi::FromInt(50),
163 : *helper.Invoke(helper.NewObject("(function(arg1) { return arg1; })"),
164 : factory->undefined_value(),
165 : handle(Smi::FromInt(50), isolate)));
166 15 : CHECK_EQ(
167 : Smi::FromInt(20),
168 : *helper.Invoke(
169 : helper.NewObject("(function(a, b, c) { return a + b + c; })"),
170 : factory->undefined_value(), handle(Smi::FromInt(10), isolate),
171 5 : handle(Smi::FromInt(7), isolate), handle(Smi::FromInt(3), isolate)));
172 5 : }
173 :
174 28342 : TEST(IntrinsicAsStubCall) {
175 5 : HandleAndZoneScope handles;
176 5 : Isolate* isolate = handles.main_isolate();
177 : Factory* factory = isolate->factory();
178 :
179 : InvokeIntrinsicHelper has_property_helper(isolate, handles.main_zone(),
180 : Runtime::kInlineHasProperty);
181 20 : CHECK_EQ(
182 : *factory->true_value(),
183 : *has_property_helper.Invoke(has_property_helper.NewObject("({ x: 20 })"),
184 : has_property_helper.NewObject("'x'")));
185 20 : CHECK_EQ(
186 : *factory->false_value(),
187 : *has_property_helper.Invoke(has_property_helper.NewObject("({ x: 20 })"),
188 5 : has_property_helper.NewObject("'y'")));
189 5 : }
190 :
191 : } // namespace interpreter
192 : } // namespace internal
193 85011 : } // namespace v8
|