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