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/code-stubs.h" 7#include "src/compiler/common-operator.h" 8#include "src/compiler/graph.h" 9#include "src/compiler/js-graph.h" 10#include "src/compiler/js-operator.h" 11#include "src/compiler/linkage.h" 12#include "src/compiler/machine-operator.h" 13#include "src/compiler/pipeline.h" 14#include "src/parsing/parser.h" 15#include "test/cctest/compiler/function-tester.h" 16 17namespace v8 { 18namespace internal { 19namespace compiler { 20 21 22TEST(RunStringLengthStub) { 23 HandleAndZoneScope scope; 24 Isolate* isolate = scope.main_isolate(); 25 Zone* zone = scope.main_zone(); 26 27 // Create code and an accompanying descriptor. 28 StringLengthStub stub(isolate); 29 Handle<Code> code = stub.GenerateCode(); 30 CompilationInfo info(ArrayVector("test"), isolate, zone, 31 Code::ComputeFlags(Code::HANDLER)); 32 CallInterfaceDescriptor interface_descriptor = 33 stub.GetCallInterfaceDescriptor(); 34 CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( 35 isolate, zone, interface_descriptor, stub.GetStackParameterCount(), 36 CallDescriptor::kNoFlags, Operator::kNoProperties); 37 38 // Create a function to call the code using the descriptor. 39 Graph graph(zone); 40 CommonOperatorBuilder common(zone); 41 // FunctionTester (ab)uses a 4-argument function 42 Node* start = graph.NewNode(common.Start(6)); 43 // Parameter 0 is the receiver 44 Node* receiverParam = graph.NewNode(common.Parameter(1), start); 45 Node* nameParam = graph.NewNode(common.Parameter(2), start); 46 Node* slotParam = graph.NewNode(common.Parameter(3), start); 47 Node* vectorParam = graph.NewNode(common.Parameter(4), start); 48 Node* theCode = graph.NewNode(common.HeapConstant(code)); 49 Node* dummyContext = graph.NewNode(common.NumberConstant(0.0)); 50 Node* call = 51 graph.NewNode(common.Call(descriptor), theCode, receiverParam, nameParam, 52 slotParam, vectorParam, dummyContext, start, start); 53 Node* ret = graph.NewNode(common.Return(), call, call, start); 54 Node* end = graph.NewNode(common.End(1), ret); 55 graph.SetStart(start); 56 graph.SetEnd(end); 57 FunctionTester ft(&graph, 4); 58 59 // Actuall call through to the stub, verifying its result. 60 const char* testString = "Und das Lamm schrie HURZ!"; 61 Handle<JSReceiver> receiverArg = 62 Object::ToObject(isolate, ft.Val(testString)).ToHandleChecked(); 63 Handle<String> nameArg = ft.Val("length"); 64 Handle<Object> slot = ft.Val(0.0); 65 Handle<Object> vector = ft.Val(0.0); 66 Handle<Object> result = 67 ft.Call(receiverArg, nameArg, slot, vector).ToHandleChecked(); 68 CHECK_EQ(static_cast<int>(strlen(testString)), Smi::cast(*result)->value()); 69} 70 71 72} // namespace compiler 73} // namespace internal 74} // namespace v8 75