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