xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_s390.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  *
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 /* Platform specific code to invoke XPCOM methods on native objects */
     9 #include "xptcprivate.h"
    12 static uint32_t
    13 invoke_count_words(uint32_t paramCount, nsXPTCVariant* s)
    14 {
    15     uint32_t overflow = 0, gpr = 1 /*this*/, fpr = 0;
    16     for(uint32_t i = 0; i < paramCount; i++, s++)
    17     {
    18         if(s->IsPtrData())
    19         {
    20             if (gpr < 5) gpr++; else overflow++;
    21             continue;
    22         }
    23         switch(s->type)
    24         {
    25         case nsXPTType::T_I8     :
    26         case nsXPTType::T_I16    :
    27         case nsXPTType::T_I32    :
    28             if (gpr < 5) gpr++; else overflow++;
    29             break;
    30         case nsXPTType::T_I64    :
    31             if (gpr < 4) gpr+=2; else gpr=5, overflow+=2;
    32             break;
    33         case nsXPTType::T_U8     :
    34         case nsXPTType::T_U16    :
    35         case nsXPTType::T_U32    :
    36             if (gpr < 5) gpr++; else overflow++;
    37             break;
    38         case nsXPTType::T_U64    :
    39             if (gpr < 4) gpr+=2; else gpr=5, overflow+=2;
    40             break;
    41         case nsXPTType::T_FLOAT  :
    42             if (fpr < 2) fpr++; else overflow++;
    43             break;
    44         case nsXPTType::T_DOUBLE :
    45             if (fpr < 2) fpr++; else overflow+=2;
    46             break;
    47         case nsXPTType::T_BOOL   :
    48         case nsXPTType::T_CHAR   :
    49         case nsXPTType::T_WCHAR  :
    50             if (gpr < 5) gpr++; else overflow++;
    51             break;
    52         default:
    53             // all the others are plain pointer types
    54             if (gpr < 5) gpr++; else overflow++;
    55             break;
    56         }
    57     }
    58     /* Round up number of overflow words to ensure stack
    59        stays aligned to 8 bytes.  */
    60     return (overflow + 1) & ~1;
    61 }
    63 static void
    64 invoke_copy_to_stack(uint32_t paramCount, nsXPTCVariant* s, uint32_t* d_ov, uint32_t overflow)
    65 {
    66     uint32_t *d_gpr = d_ov + overflow; 
    67     uint64_t *d_fpr = (uint64_t *)(d_gpr + 4);
    68     uint32_t gpr = 1 /*this*/, fpr = 0;
    70     for(uint32_t i = 0; i < paramCount; i++, s++)
    71     {
    72         if(s->IsPtrData())
    73         {
    74             if (gpr < 5) 
    75                 *((void**)d_gpr) = s->ptr, d_gpr++, gpr++;
    76             else
    77                 *((void**)d_ov ) = s->ptr, d_ov++;
    78             continue;
    79         }
    80         switch(s->type)
    81         {
    82         case nsXPTType::T_I8     : 
    83             if (gpr < 5)
    84                 *((int32_t*) d_gpr) = s->val.i8, d_gpr++, gpr++;
    85             else
    86                 *((int32_t*) d_ov ) = s->val.i8, d_ov++;
    87             break;
    88         case nsXPTType::T_I16    : 
    89             if (gpr < 5)
    90                 *((int32_t*) d_gpr) = s->val.i16, d_gpr++, gpr++;
    91             else
    92                 *((int32_t*) d_ov ) = s->val.i16, d_ov++;
    93             break;
    94         case nsXPTType::T_I32    : 
    95             if (gpr < 5)
    96                 *((int32_t*) d_gpr) = s->val.i32, d_gpr++, gpr++;
    97             else
    98                 *((int32_t*) d_ov ) = s->val.i32, d_ov++;
    99             break;
   100         case nsXPTType::T_I64    : 
   101             if (gpr < 4)
   102                 *((int64_t*) d_gpr) = s->val.i64, d_gpr+=2, gpr+=2;
   103             else
   104                 *((int64_t*) d_ov ) = s->val.i64, d_ov+=2, gpr=5;
   105             break;
   106         case nsXPTType::T_U8     : 
   107             if (gpr < 5)
   108                 *((uint32_t*) d_gpr) = s->val.u8, d_gpr++, gpr++;
   109             else
   110                 *((uint32_t*) d_ov ) = s->val.u8, d_ov++;
   111             break;
   112         case nsXPTType::T_U16    : 
   113             if (gpr < 5)
   114                 *((uint32_t*)d_gpr) = s->val.u16, d_gpr++, gpr++;
   115             else
   116                 *((uint32_t*)d_ov ) = s->val.u16, d_ov++;
   117             break;
   118         case nsXPTType::T_U32    : 
   119             if (gpr < 5)
   120                 *((uint32_t*)d_gpr) = s->val.u32, d_gpr++, gpr++;
   121             else
   122                 *((uint32_t*)d_ov ) = s->val.u32, d_ov++;
   123             break;
   124         case nsXPTType::T_U64    : 
   125             if (gpr < 4)
   126                 *((uint64_t*)d_gpr) = s->val.u64, d_gpr+=2, gpr+=2;
   127             else
   128                 *((uint64_t*)d_ov ) = s->val.u64, d_ov+=2, gpr=5;
   129             break;
   130         case nsXPTType::T_FLOAT  : 
   131             if (fpr < 2)
   132                 *((float*)   d_fpr) = s->val.f, d_fpr++, fpr++;
   133             else
   134                 *((float*)   d_ov ) = s->val.f, d_ov++;
   135             break;
   136         case nsXPTType::T_DOUBLE : 
   137             if (fpr < 2)
   138                 *((double*)  d_fpr) = s->val.d, d_fpr++, fpr++;
   139             else
   140                 *((double*)  d_ov ) = s->val.d, d_ov+=2;
   141             break;
   142         case nsXPTType::T_BOOL   : 
   143             if (gpr < 5)
   144                 *((uint32_t*)d_gpr) = s->val.b, d_gpr++, gpr++;
   145             else
   146                 *((uint32_t*)d_ov ) = s->val.b, d_ov++;
   147             break;
   148         case nsXPTType::T_CHAR   : 
   149             if (gpr < 5)
   150                 *((uint32_t*)d_gpr) = s->val.c, d_gpr++, gpr++;
   151             else
   152                 *((uint32_t*)d_ov ) = s->val.c, d_ov++;
   153             break;
   154         case nsXPTType::T_WCHAR  : 
   155             if (gpr < 5)
   156                 *((uint32_t*)d_gpr) = s->val.wc, d_gpr++, gpr++;
   157             else
   158                 *((uint32_t*)d_ov ) = s->val.wc, d_ov++;
   159             break;
   160         default:
   161             // all the others are plain pointer types
   162             if (gpr < 5) 
   163                 *((void**)   d_gpr) = s->val.p, d_gpr++, gpr++;
   164             else
   165                 *((void**)   d_ov ) = s->val.p, d_ov++;
   166             break;
   167         }
   168     }
   169 }
   171 typedef nsresult (*vtable_func)(nsISupports *, uint32_t, uint32_t, uint32_t, uint32_t, double, double);
   173 EXPORT_XPCOM_API(nsresult)
   174 NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
   175                  uint32_t paramCount, nsXPTCVariant* params)
   176 {
   177     vtable_func *vtable = *reinterpret_cast<vtable_func **>(that);
   178     vtable_func method = vtable[methodIndex];
   179     uint32_t overflow = invoke_count_words (paramCount, params);
   180     uint32_t *stack_space = reinterpret_cast<uint32_t *>(__builtin_alloca((overflow + 8 /* 4 32-bits gpr + 2 64-bits fpr */) * 4));
   182     invoke_copy_to_stack(paramCount, params, stack_space, overflow);
   184     uint32_t *d_gpr = stack_space + overflow;
   185     double *d_fpr = reinterpret_cast<double *>(d_gpr + 4);
   187     return method(that, d_gpr[0], d_gpr[1], d_gpr[2], d_gpr[3],  d_fpr[0], d_fpr[1]);
   188 }

mercurial