1 // Copyright 2014 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/code-stubs.h"
6 #include "src/compiler.h"
7 #include "src/parsing/parser.h"
8 #include "src/zone.h"
9
10 #include "src/code-factory.h"
11 #include "src/compiler/common-operator.h"
12 #include "src/compiler/graph.h"
13 #include "src/compiler/linkage.h"
14 #include "src/compiler/machine-operator.h"
15 #include "src/compiler/node.h"
16 #include "src/compiler/operator.h"
17 #include "src/compiler/pipeline.h"
18 #include "src/compiler/schedule.h"
19 #include "test/cctest/cctest.h"
20
21 namespace v8 {
22 namespace internal {
23 namespace compiler {
24
25 static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
26 "dummy", 0, 0, 0, 0, 0, 0);
27
28 // So we can get a real JS function.
Compile(const char * source)29 static Handle<JSFunction> Compile(const char* source) {
30 Isolate* isolate = CcTest::i_isolate();
31 Handle<String> source_code = isolate->factory()
32 ->NewStringFromUtf8(CStrVector(source))
33 .ToHandleChecked();
34 Handle<SharedFunctionInfo> shared = Compiler::GetSharedFunctionInfoForScript(
35 source_code, Handle<String>(), 0, 0, v8::ScriptOriginOptions(),
36 Handle<Object>(), Handle<Context>(isolate->native_context()), NULL, NULL,
37 v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE, false);
38 return isolate->factory()->NewFunctionFromSharedFunctionInfo(
39 shared, isolate->native_context());
40 }
41
42
TEST(TestLinkageCreate)43 TEST(TestLinkageCreate) {
44 HandleAndZoneScope handles;
45 Handle<JSFunction> function = Compile("a + b");
46 ParseInfo parse_info(handles.main_zone(), function);
47 CompilationInfo info(&parse_info, function);
48 CallDescriptor* descriptor = Linkage::ComputeIncoming(info.zone(), &info);
49 CHECK(descriptor);
50 }
51
52
TEST(TestLinkageJSFunctionIncoming)53 TEST(TestLinkageJSFunctionIncoming) {
54 const char* sources[] = {"(function() { })", "(function(a) { })",
55 "(function(a,b) { })", "(function(a,b,c) { })"};
56
57 for (int i = 0; i < 3; i++) {
58 HandleAndZoneScope handles;
59 Handle<JSFunction> function =
60 Handle<JSFunction>::cast(v8::Utils::OpenHandle(
61 *v8::Local<v8::Function>::Cast(CompileRun(sources[i]))));
62 ParseInfo parse_info(handles.main_zone(), function);
63 CompilationInfo info(&parse_info, function);
64 CallDescriptor* descriptor = Linkage::ComputeIncoming(info.zone(), &info);
65 CHECK(descriptor);
66
67 CHECK_EQ(1 + i, static_cast<int>(descriptor->JSParameterCount()));
68 CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount()));
69 CHECK_EQ(Operator::kNoProperties, descriptor->properties());
70 CHECK_EQ(true, descriptor->IsJSFunctionCall());
71 }
72 }
73
74
TEST(TestLinkageJSCall)75 TEST(TestLinkageJSCall) {
76 HandleAndZoneScope handles;
77 Handle<JSFunction> function = Compile("a + c");
78 ParseInfo parse_info(handles.main_zone(), function);
79 CompilationInfo info(&parse_info, function);
80
81 for (int i = 0; i < 32; i++) {
82 CallDescriptor* descriptor = Linkage::GetJSCallDescriptor(
83 info.zone(), false, i, CallDescriptor::kNoFlags);
84 CHECK(descriptor);
85 CHECK_EQ(i, static_cast<int>(descriptor->JSParameterCount()));
86 CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount()));
87 CHECK_EQ(Operator::kNoProperties, descriptor->properties());
88 CHECK_EQ(true, descriptor->IsJSFunctionCall());
89 }
90 }
91
92
TEST(TestLinkageRuntimeCall)93 TEST(TestLinkageRuntimeCall) {
94 // TODO(titzer): test linkage creation for outgoing runtime calls.
95 }
96
97
TEST(TestLinkageStubCall)98 TEST(TestLinkageStubCall) {
99 Isolate* isolate = CcTest::InitIsolateOnce();
100 Zone zone(isolate->allocator());
101 Callable callable = CodeFactory::ToNumber(isolate);
102 CompilationInfo info(ArrayVector("test"), isolate, &zone,
103 Code::ComputeFlags(Code::STUB));
104 CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
105 isolate, &zone, callable.descriptor(), 0, CallDescriptor::kNoFlags,
106 Operator::kNoProperties);
107 CHECK(descriptor);
108 CHECK_EQ(0, static_cast<int>(descriptor->StackParameterCount()));
109 CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount()));
110 CHECK_EQ(Operator::kNoProperties, descriptor->properties());
111 CHECK_EQ(false, descriptor->IsJSFunctionCall());
112 // TODO(titzer): test linkage creation for outgoing stub calls.
113 }
114
115 } // namespace compiler
116 } // namespace internal
117 } // namespace v8
118