LCOV - code coverage report
Current view: top level - libreoffice/bridges/source/cpp_uno/gcc3_linux_intel - callvirtualmethod.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 18 18 100.0 %
Date: 2012-12-27 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "sal/config.h"
      21             : 
      22             : #include <cassert>
      23             : 
      24             : #include "cppu/macros.hxx"
      25             : #include "sal/types.h"
      26             : #include "typelib/typeclass.h"
      27             : #include "typelib/typedescription.h"
      28             : 
      29             : #include "callvirtualmethod.hxx"
      30             : #include "share.hxx"
      31             : 
      32             : // The call instruction within the asm block of callVirtualMethod may throw
      33             : // exceptions.  At least GCC 4.7.0 with -O0 would create (unnecessary)
      34             : // .gcc_exception_table call-site table entries around all other calls in this
      35             : // function that can throw, leading to std::terminate if the asm call throws an
      36             : // exception and the unwinding C++ personality routine finds the unexpected hole
      37             : // in the .gcc_exception_table.  Therefore, make sure this function explicitly
      38             : // only calls nothrow-functions (so GCC 4.7.0 with -O0 happens to not create a
      39             : // .gcc_exception_table section at all for this function).  For some reason,
      40             : // this also needs to be in a source file of its own.
      41             : //
      42             : // Also, this file should be compiled with -fnon-call-exceptions, and ideally
      43             : // there would be a way to tell the compiler that the asm block contains calls
      44             : // to functions that can potentially throw; see the mail thread starting at
      45             : // <http://gcc.gnu.org/ml/gcc/2012-03/msg00454.html> "C++: Letting compiler know
      46             : // asm block can call function that can throw?"
      47             : 
      48         436 : void CPPU_CURRENT_NAMESPACE::callVirtualMethod(
      49             :     void * pAdjustedThisPtr, sal_Int32 nVtableIndex, void * pRegisterReturn,
      50             :     typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
      51             :     sal_Int32 * pStackLongs, sal_Int32 nStackLongs)
      52             : {
      53             :     // parameter list is mixed list of * and values
      54             :     // reference parameters are pointers
      55             : 
      56             :     assert(pStackLongs && pAdjustedThisPtr);
      57             :     assert(sizeof (void *) == 4 && sizeof (sal_Int32) == 4);
      58             :         // unexpected size of int
      59             :     assert(nStackLongs && pStackLongs); // no stack
      60             : 
      61             : #if defined __clang__ || __GNUC__ == 4 && __GNUC_MINOR__ <= 6
      62             :     if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
      63             : #endif
      64             : 
      65         436 :     volatile long edx = 0, eax = 0; // for register returns
      66             :     void * stackptr;
      67             :     asm volatile (
      68             :         "mov   %%esp, %6\n\t"
      69             :         // preserve potential 128bit stack alignment
      70             :         "and   $0xfffffff0, %%esp\n\t"
      71             :         "mov   %0, %%eax\n\t"
      72             :         "lea   -4(,%%eax,4), %%eax\n\t"
      73             :         "and   $0xf, %%eax\n\t"
      74             :         "sub   $0xc, %%eax\n\t"
      75             :         "add   %%eax, %%esp\n\t"
      76             :         // copy values
      77             :         "mov   %0, %%eax\n\t"
      78             :         "mov   %%eax, %%edx\n\t"
      79             :         "dec   %%edx\n\t"
      80             :         "shl   $2, %%edx\n\t"
      81             :         "add   %1, %%edx\n"
      82             :         "Lcopy:\n\t"
      83             :         "pushl 0(%%edx)\n\t"
      84             :         "sub   $4, %%edx\n\t"
      85             :         "dec   %%eax\n\t"
      86             :         "jne   Lcopy\n\t"
      87             :         // do the actual call
      88             :         "mov   %2, %%edx\n\t"
      89             :         "mov   0(%%edx), %%edx\n\t"
      90             :         "mov   %3, %%eax\n\t"
      91             :         "shl   $2, %%eax\n\t"
      92             :         "add   %%eax, %%edx\n\t"
      93             :         "mov   0(%%edx), %%edx\n\t"
      94             :         "call  *%%edx\n\t"
      95             :         // save return registers
      96             :          "mov   %%eax, %4\n\t"
      97             :          "mov   %%edx, %5\n\t"
      98             :         // cleanup stack
      99             :         "mov   %6, %%esp\n\t"
     100             :         :
     101             :         : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr),
     102             :           "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr)
     103         436 :         : "eax", "ecx", "edx" );
     104         353 :     switch( pReturnTypeDescr->eTypeClass )
     105             :     {
     106             :         case typelib_TypeClass_VOID:
     107         139 :             break;
     108             :         case typelib_TypeClass_HYPER:
     109             :         case typelib_TypeClass_UNSIGNED_HYPER:
     110           2 :             ((long*)pRegisterReturn)[1] = edx;
     111             :         case typelib_TypeClass_LONG:
     112             :         case typelib_TypeClass_UNSIGNED_LONG:
     113             :         case typelib_TypeClass_CHAR:
     114             :         case typelib_TypeClass_ENUM:
     115          39 :             ((long*)pRegisterReturn)[0] = eax;
     116          39 :             break;
     117             :         case typelib_TypeClass_SHORT:
     118             :         case typelib_TypeClass_UNSIGNED_SHORT:
     119           2 :             *(unsigned short*)pRegisterReturn = eax;
     120           2 :             break;
     121             :         case typelib_TypeClass_BOOLEAN:
     122             :         case typelib_TypeClass_BYTE:
     123          11 :             *(unsigned char*)pRegisterReturn = eax;
     124          11 :             break;
     125             :         case typelib_TypeClass_FLOAT:
     126           1 :             asm ( "fstps %0" : : "m"(*(char *)pRegisterReturn) );
     127           1 :             break;
     128             :         case typelib_TypeClass_DOUBLE:
     129          34 :             asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) );
     130          34 :             break;
     131             :         default:
     132             :         {
     133             : #if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX) || \
     134             :     defined(DRAGONFLY)
     135             :             sal_Int32 const nRetSize = pReturnTypeDescr->nSize;
     136             :             if (bSimpleReturn && nRetSize <= 8 && nRetSize > 0)
     137             :             {
     138             :                 if (nRetSize > 4)
     139             :                     static_cast<long *>(pRegisterReturn)[1] = edx;
     140             :                 static_cast<long *>(pRegisterReturn)[0] = eax;
     141             :             }
     142             : #else
     143             :             (void)bSimpleReturn;
     144             : #endif
     145         127 :             break;
     146             :         }
     147             :     }
     148         353 : }
     149             : 
     150             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10