| // Copyright 2014 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/api.h" |
| #include "src/code-factory.h" |
| #include "src/code-stubs.h" |
| #include "src/compilation-info.h" |
| #include "src/compiler.h" |
| #include "src/compiler/common-operator.h" |
| #include "src/compiler/graph.h" |
| #include "src/compiler/linkage.h" |
| #include "src/compiler/machine-operator.h" |
| #include "src/compiler/node.h" |
| #include "src/compiler/operator.h" |
| #include "src/compiler/pipeline.h" |
| #include "src/compiler/schedule.h" |
| #include "src/objects-inl.h" |
| #include "src/parsing/parse-info.h" |
| #include "src/zone/zone.h" |
| #include "test/cctest/cctest.h" |
| |
| namespace v8 { |
| namespace internal { |
| namespace compiler { |
| |
| static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite, |
| "dummy", 0, 0, 0, 0, 0, 0); |
| |
| // So we can get a real JS function. |
| static Handle<JSFunction> Compile(const char* source) { |
| Isolate* isolate = CcTest::i_isolate(); |
| Handle<String> source_code = isolate->factory() |
| ->NewStringFromUtf8(CStrVector(source)) |
| .ToHandleChecked(); |
| Handle<SharedFunctionInfo> shared = |
| Compiler::GetSharedFunctionInfoForScript( |
| source_code, MaybeHandle<String>(), 0, 0, v8::ScriptOriginOptions(), |
| MaybeHandle<Object>(), Handle<Context>(isolate->native_context()), |
| nullptr, nullptr, v8::ScriptCompiler::kNoCompileOptions, |
| ScriptCompiler::kNoCacheNoReason, NOT_NATIVES_CODE, |
| MaybeHandle<FixedArray>()) |
| .ToHandleChecked(); |
| return isolate->factory()->NewFunctionFromSharedFunctionInfo( |
| shared, isolate->native_context()); |
| } |
| |
| |
| TEST(TestLinkageCreate) { |
| HandleAndZoneScope handles; |
| Handle<JSFunction> function = Compile("a + b"); |
| Handle<SharedFunctionInfo> shared(function->shared()); |
| CompilationInfo info(handles.main_zone(), function->GetIsolate(), shared, |
| function); |
| CallDescriptor* descriptor = Linkage::ComputeIncoming(info.zone(), &info); |
| CHECK(descriptor); |
| } |
| |
| |
| TEST(TestLinkageJSFunctionIncoming) { |
| const char* sources[] = {"(function() { })", "(function(a) { })", |
| "(function(a,b) { })", "(function(a,b,c) { })"}; |
| |
| for (int i = 0; i < 3; i++) { |
| HandleAndZoneScope handles; |
| Handle<JSFunction> function = |
| Handle<JSFunction>::cast(v8::Utils::OpenHandle( |
| *v8::Local<v8::Function>::Cast(CompileRun(sources[i])))); |
| Handle<SharedFunctionInfo> shared(function->shared()); |
| CompilationInfo info(handles.main_zone(), function->GetIsolate(), shared, |
| function); |
| CallDescriptor* descriptor = Linkage::ComputeIncoming(info.zone(), &info); |
| CHECK(descriptor); |
| |
| CHECK_EQ(1 + i, static_cast<int>(descriptor->JSParameterCount())); |
| CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount())); |
| CHECK_EQ(Operator::kNoProperties, descriptor->properties()); |
| CHECK_EQ(true, descriptor->IsJSFunctionCall()); |
| } |
| } |
| |
| |
| TEST(TestLinkageJSCall) { |
| HandleAndZoneScope handles; |
| Handle<JSFunction> function = Compile("a + c"); |
| Handle<SharedFunctionInfo> shared(function->shared()); |
| CompilationInfo info(handles.main_zone(), function->GetIsolate(), shared, |
| function); |
| |
| for (int i = 0; i < 32; i++) { |
| CallDescriptor* descriptor = Linkage::GetJSCallDescriptor( |
| info.zone(), false, i, CallDescriptor::kNoFlags); |
| CHECK(descriptor); |
| CHECK_EQ(i, static_cast<int>(descriptor->JSParameterCount())); |
| CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount())); |
| CHECK_EQ(Operator::kNoProperties, descriptor->properties()); |
| CHECK_EQ(true, descriptor->IsJSFunctionCall()); |
| } |
| } |
| |
| |
| TEST(TestLinkageRuntimeCall) { |
| // TODO(titzer): test linkage creation for outgoing runtime calls. |
| } |
| |
| |
| TEST(TestLinkageStubCall) { |
| Isolate* isolate = CcTest::InitIsolateOnce(); |
| Zone zone(isolate->allocator(), ZONE_NAME); |
| Callable callable = Builtins::CallableFor(isolate, Builtins::kToNumber); |
| CompilationInfo info(ArrayVector("test"), &zone, Code::STUB); |
| CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( |
| isolate, &zone, callable.descriptor(), 0, CallDescriptor::kNoFlags, |
| Operator::kNoProperties); |
| CHECK(descriptor); |
| CHECK_EQ(0, static_cast<int>(descriptor->StackParameterCount())); |
| CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount())); |
| CHECK_EQ(Operator::kNoProperties, descriptor->properties()); |
| CHECK_EQ(false, descriptor->IsJSFunctionCall()); |
| // TODO(titzer): test linkage creation for outgoing stub calls. |
| } |
| |
| } // namespace compiler |
| } // namespace internal |
| } // namespace v8 |