LCOV - code coverage report
Current view: top level - src/ffi - ffi-compiler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 51 54 94.4 %
Date: 2017-04-26 Functions: 7 7 100.0 %

          Line data    Source code
       1             : // Copyright 2017 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/ffi/ffi-compiler.h"
       6             : #include "src/api.h"
       7             : #include "src/code-factory.h"
       8             : #include "src/objects-inl.h"
       9             : 
      10             : namespace v8 {
      11             : namespace internal {
      12             : 
      13      105382 : void InstallFFIMap(Isolate* isolate) {
      14             :   Handle<Context> context(isolate->context());
      15             :   DCHECK(!context->get(Context::NATIVE_FUNCTION_MAP_INDEX)->IsMap());
      16             :   Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate);
      17             : 
      18             :   InstanceType instance_type = prev_map->instance_type();
      19      105383 :   int embedder_fields = JSObject::GetEmbedderFieldCount(*prev_map);
      20      105382 :   CHECK_EQ(0, embedder_fields);
      21             :   int pre_allocated =
      22      105382 :       prev_map->GetInObjectProperties() - prev_map->unused_property_fields();
      23             :   int instance_size;
      24             :   int in_object_properties;
      25             :   JSFunction::CalculateInstanceSizeHelper(
      26      105382 :       instance_type, embedder_fields, 0, &instance_size, &in_object_properties);
      27      105382 :   int unused_property_fields = in_object_properties - pre_allocated;
      28             :   Handle<Map> map = Map::CopyInitialMap(
      29      105382 :       prev_map, instance_size, in_object_properties, unused_property_fields);
      30             :   context->set_native_function_map(*map);
      31      105383 : }
      32             : 
      33             : namespace ffi {
      34             : 
      35             : class FFIAssembler : public CodeStubAssembler {
      36             :  public:
      37          21 :   explicit FFIAssembler(CodeAssemblerState* state) : CodeStubAssembler(state) {}
      38             : 
      39          14 :   Node* ToJS(Node* node, Node* context, FFIType type) {
      40          14 :     switch (type) {
      41             :       case FFIType::kInt32:
      42          14 :         return ChangeInt32ToTagged(node);
      43             :     }
      44           0 :     UNREACHABLE();
      45             :     return nullptr;
      46             :   }
      47             : 
      48          63 :   Node* FromJS(Node* node, Node* context, FFIType type) {
      49          63 :     switch (type) {
      50             :       case FFIType::kInt32:
      51          63 :         return TruncateTaggedToWord32(context, node);
      52             :     }
      53           0 :     UNREACHABLE();
      54             :     return nullptr;
      55             :   }
      56             : 
      57          77 :   MachineType FFIToMachineType(FFIType type) {
      58          77 :     switch (type) {
      59             :       case FFIType::kInt32:
      60             :         return MachineType::Int32();
      61             :     }
      62           0 :     UNREACHABLE();
      63             :     return MachineType::None();
      64             :   }
      65             : 
      66         217 :   Signature<MachineType>* FFIToMachineSignature(FFISignature* sig) {
      67             :     Signature<MachineType>::Builder sig_builder(zone(), sig->return_count(),
      68          21 :                                                 sig->parameter_count());
      69          70 :     for (size_t i = 0; i < sig->return_count(); i++) {
      70          14 :       sig_builder.AddReturn(FFIToMachineType(sig->GetReturn(i)));
      71             :     }
      72         147 :     for (size_t j = 0; j < sig->parameter_count(); j++) {
      73          63 :       sig_builder.AddParam(FFIToMachineType(sig->GetParam(j)));
      74             :     }
      75          21 :     return sig_builder.Build();
      76             :   }
      77             : 
      78          21 :   void GenerateJSToNativeWrapper(NativeFunction* func) {
      79          98 :     int params = static_cast<int>(func->sig->parameter_count());
      80          21 :     int returns = static_cast<int>(func->sig->return_count());
      81          21 :     ApiFunction api_func(func->start);
      82             :     ExternalReference ref(&api_func, ExternalReference::BUILTIN_CALL,
      83          21 :                           isolate());
      84             : 
      85          21 :     Node* context_param = GetJSContextParameter();
      86             : 
      87          21 :     Node** inputs = zone()->NewArray<Node*>(params + 1);
      88             :     int input_count = 0;
      89          21 :     inputs[input_count++] = ExternalConstant(ref);
      90          84 :     for (int i = 0; i < params; i++) {
      91          63 :       inputs[input_count++] =
      92         126 :           FromJS(Parameter(i), context_param, func->sig->GetParam(i));
      93             :     }
      94             : 
      95             :     Node* call =
      96          21 :         CallCFunctionN(FFIToMachineSignature(func->sig), input_count, inputs);
      97          21 :     Node* return_val = UndefinedConstant();
      98          21 :     if (returns == 1) {
      99          28 :       return_val = ToJS(call, context_param, func->sig->GetReturn());
     100             :     }
     101          21 :     Return(return_val);
     102          21 :   }
     103             : };
     104             : 
     105          42 : Handle<JSFunction> CompileJSToNativeWrapper(Isolate* isolate,
     106             :                                             Handle<String> name,
     107             :                                             NativeFunction func) {
     108          21 :   int params = static_cast<int>(func.sig->parameter_count());
     109          21 :   Zone zone(isolate->allocator(), ZONE_NAME);
     110             :   CodeAssemblerState state(isolate, &zone, params,
     111          42 :                            Code::ComputeFlags(Code::BUILTIN), "js-to-native");
     112             :   FFIAssembler assembler(&state);
     113          21 :   assembler.GenerateJSToNativeWrapper(&func);
     114          21 :   Handle<Code> code = assembler.GenerateCode(&state);
     115             : 
     116             :   Handle<SharedFunctionInfo> shared =
     117          21 :       isolate->factory()->NewSharedFunctionInfo(name, code, false);
     118             :   shared->set_length(params);
     119             :   shared->set_internal_formal_parameter_count(params);
     120             :   Handle<JSFunction> function = isolate->factory()->NewFunction(
     121          21 :       isolate->native_function_map(), name, code);
     122          21 :   function->set_shared(*shared);
     123          42 :   return function;
     124             : }
     125             : 
     126             : }  // namespace ffi
     127             : }  // namespace internal
     128             : }  // namespace v8

Generated by: LCOV version 1.10