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/bootstrapper.h"
6 : #include "src/callable.h"
7 : #include "src/code-stubs.h"
8 : #include "src/compilation-info.h"
9 : #include "src/compiler/common-operator.h"
10 : #include "src/compiler/graph.h"
11 : #include "src/compiler/js-graph.h"
12 : #include "src/compiler/js-operator.h"
13 : #include "src/compiler/linkage.h"
14 : #include "src/compiler/machine-operator.h"
15 : #include "src/compiler/pipeline.h"
16 : #include "src/objects-inl.h"
17 : #include "test/cctest/compiler/function-tester.h"
18 :
19 : namespace v8 {
20 : namespace internal {
21 : namespace compiler {
22 :
23 6 : class StubTester {
24 : public:
25 : StubTester(Isolate* isolate, Zone* zone, CodeStub* stub)
26 : : zone_(zone),
27 : info_(ArrayVector("test"), isolate, zone, Code::STUB),
28 : interface_descriptor_(stub->GetCallInterfaceDescriptor()),
29 : descriptor_(Linkage::GetStubCallDescriptor(
30 : isolate, zone, interface_descriptor_,
31 : stub->GetStackParameterCount(), CallDescriptor::kNoFlags,
32 : Operator::kNoProperties)),
33 : graph_(zone_),
34 : common_(zone_),
35 : tester_(InitializeFunctionTester(stub->GetCode()),
36 : GetParameterCountWithContext()) {}
37 :
38 6 : StubTester(Isolate* isolate, Zone* zone, Builtins::Name name)
39 : : zone_(zone),
40 : info_(ArrayVector("test"), isolate, zone, Code::STUB),
41 : interface_descriptor_(
42 : Builtins::CallableFor(isolate, name).descriptor()),
43 : descriptor_(Linkage::GetStubCallDescriptor(
44 : isolate, zone, interface_descriptor_,
45 : interface_descriptor_.GetStackParameterCount(),
46 12 : CallDescriptor::kNoFlags, Operator::kNoProperties)),
47 : graph_(zone_),
48 : common_(zone_),
49 : tester_(InitializeFunctionTester(
50 : Handle<Code>(isolate->builtins()->builtin(name))),
51 30 : GetParameterCountWithContext()) {}
52 :
53 : template <typename... Args>
54 6 : Handle<Object> Call(Args... args) {
55 : DCHECK_EQ(interface_descriptor_.GetParameterCount(), sizeof...(args));
56 : MaybeHandle<Object> result =
57 : tester_.Call(args..., Handle<HeapObject>(tester_.function->context()))
58 12 : .ToHandleChecked();
59 6 : return result.ToHandleChecked();
60 : }
61 :
62 : FunctionTester& ft() { return tester_; }
63 :
64 : private:
65 6 : Graph* InitializeFunctionTester(Handle<Code> stub) {
66 : // Add target, effect and control.
67 6 : int node_count = GetParameterCountWithContext() + 3;
68 : // Add extra inputs for the JSFunction parameter and the receiver (which for
69 : // the tester is always undefined) to the start node.
70 : Node* start =
71 6 : graph_.NewNode(common_.Start(GetParameterCountWithContext() + 2));
72 6 : Node** node_array = zone_->NewArray<Node*>(node_count);
73 12 : node_array[0] = graph_.NewNode(common_.HeapConstant(stub));
74 42 : for (int i = 0; i < GetParameterCountWithContext(); ++i) {
75 60 : CHECK(IsAnyTagged(descriptor_->GetParameterType(i).representation()));
76 60 : node_array[i + 1] = graph_.NewNode(common_.Parameter(i + 1), start);
77 : }
78 6 : node_array[node_count - 2] = start;
79 6 : node_array[node_count - 1] = start;
80 : Node* call =
81 6 : graph_.NewNode(common_.Call(descriptor_), node_count, &node_array[0]);
82 :
83 6 : Node* zero = graph_.NewNode(common_.Int32Constant(0));
84 6 : Node* ret = graph_.NewNode(common_.Return(), zero, call, call, start);
85 6 : Node* end = graph_.NewNode(common_.End(1), ret);
86 : graph_.SetStart(start);
87 : graph_.SetEnd(end);
88 6 : return &graph_;
89 : }
90 :
91 : int GetParameterCountWithContext() {
92 12 : return interface_descriptor_.GetParameterCount() + 1;
93 : }
94 :
95 : Zone* zone_;
96 : CompilationInfo info_;
97 : CallInterfaceDescriptor interface_descriptor_;
98 : CallDescriptor* descriptor_;
99 : Graph graph_;
100 : CommonOperatorBuilder common_;
101 : FunctionTester tester_;
102 : };
103 :
104 23724 : TEST(RunStringLengthStub) {
105 6 : HandleAndZoneScope scope;
106 6 : Isolate* isolate = scope.main_isolate();
107 : Zone* zone = scope.main_zone();
108 :
109 6 : StubTester tester(isolate, zone, Builtins::kLoadIC_StringLength);
110 :
111 : // Actuall call through to the stub, verifying its result.
112 : const char* testString = "Und das Lamm schrie HURZ!";
113 : Handle<Object> receiverArg =
114 18 : Object::ToObject(isolate, tester.ft().Val(testString)).ToHandleChecked();
115 6 : Handle<Object> nameArg = tester.ft().Val("length");
116 6 : Handle<Object> slot = tester.ft().Val(0.0);
117 6 : Handle<Object> vector = tester.ft().Val(0.0);
118 6 : Handle<Object> result = tester.Call(receiverArg, nameArg, slot, vector);
119 12 : CHECK_EQ(static_cast<int>(strlen(testString)), Smi::ToInt(*result));
120 6 : }
121 :
122 :
123 : } // namespace compiler
124 : } // namespace internal
125 71154 : } // namespace v8
|