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. 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 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 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 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 93 TEST(TestLinkageRuntimeCall) { 94 // TODO(titzer): test linkage creation for outgoing runtime calls. 95 } 96 97 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