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

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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"
    11 // 6 integral parameters are passed in registers
    12 const uint32_t GPR_COUNT = 6;
    14 // 8 floating point parameters are passed in SSE registers
    15 const uint32_t FPR_COUNT = 8;
    17 // Remember that these 'words' are 64-bit long
    18 static inline void
    19 invoke_count_words(uint32_t paramCount, nsXPTCVariant * s,
    20                    uint32_t & nr_gpr, uint32_t & nr_fpr, uint32_t & nr_stack)
    21 {
    22     nr_gpr = 1; // skip one GP register for 'that'
    23     nr_fpr = 0;
    24     nr_stack = 0;
    26     /* Compute number of eightbytes of class MEMORY.  */
    27     for (uint32_t i = 0; i < paramCount; i++, s++) {
    28         if (!s->IsPtrData()
    29             && (s->type == nsXPTType::T_FLOAT || s->type == nsXPTType::T_DOUBLE)) {
    30             if (nr_fpr < FPR_COUNT)
    31                 nr_fpr++;
    32             else
    33                 nr_stack++;
    34         }
    35         else {
    36             if (nr_gpr < GPR_COUNT)
    37                 nr_gpr++;
    38             else
    39                 nr_stack++;
    40         }
    41     }
    42 }
    44 static void
    45 invoke_copy_to_stack(uint64_t * d, uint32_t paramCount, nsXPTCVariant * s,
    46                      uint64_t * gpregs, double * fpregs)
    47 {
    48     uint32_t nr_gpr = 1; // skip one GP register for 'that'
    49     uint32_t nr_fpr = 0;
    50     uint64_t value;
    52     for (uint32_t i = 0; i < paramCount; i++, s++) {
    53         if (s->IsPtrData())
    54             value = (uint64_t) s->ptr;
    55         else {
    56             switch (s->type) {
    57             case nsXPTType::T_FLOAT:                                break;
    58             case nsXPTType::T_DOUBLE:                               break;
    59             case nsXPTType::T_I8:     value = s->val.i8;            break;
    60             case nsXPTType::T_I16:    value = s->val.i16;           break;
    61             case nsXPTType::T_I32:    value = s->val.i32;           break;
    62             case nsXPTType::T_I64:    value = s->val.i64;           break;
    63             case nsXPTType::T_U8:     value = s->val.u8;            break;
    64             case nsXPTType::T_U16:    value = s->val.u16;           break;
    65             case nsXPTType::T_U32:    value = s->val.u32;           break;
    66             case nsXPTType::T_U64:    value = s->val.u64;           break;
    67             case nsXPTType::T_BOOL:   value = s->val.b;             break;
    68             case nsXPTType::T_CHAR:   value = s->val.c;             break;
    69             case nsXPTType::T_WCHAR:  value = s->val.wc;            break;
    70             default:                  value = (uint64_t) s->val.p;  break;
    71             }
    72         }
    74         if (!s->IsPtrData() && s->type == nsXPTType::T_DOUBLE) {
    75             if (nr_fpr < FPR_COUNT)
    76                 fpregs[nr_fpr++] = s->val.d;
    77             else {
    78                 *((double *)d) = s->val.d;
    79                 d++;
    80             }
    81         }
    82         else if (!s->IsPtrData() && s->type == nsXPTType::T_FLOAT) {
    83             if (nr_fpr < FPR_COUNT)
    84                 // The value in %xmm register is already prepared to
    85                 // be retrieved as a float. Therefore, we pass the
    86                 // value verbatim, as a double without conversion.
    87                 fpregs[nr_fpr++] = s->val.d;
    88             else {
    89                 *((float *)d) = s->val.f;
    90                 d++;
    91             }
    92         }
    93         else {
    94             if (nr_gpr < GPR_COUNT)
    95                 gpregs[nr_gpr++] = value;
    96             else
    97                 *d++ = value;
    98         }
    99     }
   100 }
   102 EXPORT_XPCOM_API(nsresult)
   103 NS_InvokeByIndex(nsISupports * that, uint32_t methodIndex,
   104                  uint32_t paramCount, nsXPTCVariant * params)
   105 {
   106     uint32_t nr_gpr, nr_fpr, nr_stack;
   107     invoke_count_words(paramCount, params, nr_gpr, nr_fpr, nr_stack);
   109     // Stack, if used, must be 16-bytes aligned
   110     if (nr_stack)
   111         nr_stack = (nr_stack + 1) & ~1;
   113     // Load parameters to stack, if necessary
   114     uint64_t *stack = (uint64_t *) __builtin_alloca(nr_stack * 8);
   115     uint64_t gpregs[GPR_COUNT];
   116     double fpregs[FPR_COUNT];
   117     invoke_copy_to_stack(stack, paramCount, params, gpregs, fpregs);
   119     // Load FPR registers from fpregs[]
   120     register double d0 asm("xmm0");
   121     register double d1 asm("xmm1");
   122     register double d2 asm("xmm2");
   123     register double d3 asm("xmm3");
   124     register double d4 asm("xmm4");
   125     register double d5 asm("xmm5");
   126     register double d6 asm("xmm6");
   127     register double d7 asm("xmm7");
   129     switch (nr_fpr) {
   130 #define ARG_FPR(N) \
   131     case N+1: d##N = fpregs[N];
   132         ARG_FPR(7);
   133         ARG_FPR(6);
   134         ARG_FPR(5);
   135         ARG_FPR(4);
   136         ARG_FPR(3);
   137         ARG_FPR(2);
   138         ARG_FPR(1);
   139         ARG_FPR(0);
   140     case 0:;
   141 #undef ARG_FPR
   142     }
   144     // Load GPR registers from gpregs[]
   145     register uint64_t a0 asm("rdi");
   146     register uint64_t a1 asm("rsi");
   147     register uint64_t a2 asm("rdx");
   148     register uint64_t a3 asm("rcx");
   149     register uint64_t a4 asm("r8");
   150     register uint64_t a5 asm("r9");
   152     switch (nr_gpr) {
   153 #define ARG_GPR(N) \
   154     case N+1: a##N = gpregs[N];
   155         ARG_GPR(5);
   156         ARG_GPR(4);
   157         ARG_GPR(3);
   158         ARG_GPR(2);
   159         ARG_GPR(1);
   160     case 1: a0 = (uint64_t) that;
   161     case 0:;
   162 #undef ARG_GPR
   163     }
   165     // Ensure that assignments to SSE registers won't be optimized away
   166     asm("" ::
   167         "x" (d0), "x" (d1), "x" (d2), "x" (d3),
   168         "x" (d4), "x" (d5), "x" (d6), "x" (d7));
   170     // Get pointer to method
   171     uint64_t methodAddress = *((uint64_t *)that);
   172     methodAddress += 8 * methodIndex;
   173     methodAddress = *((uint64_t *)methodAddress);
   175     typedef nsresult (*Method)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
   176     nsresult result = ((Method)methodAddress)(a0, a1, a2, a3, a4, a5);
   177     return result;
   178 }

mercurial