xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_rhapsody.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

michael@0 1 /* -*- Mode: C -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "xptcprivate.h"
michael@0 7 #include "xptiprivate.h"
michael@0 8
michael@0 9 /* Under the Mac OS X PowerPC ABI, the first 8 integer and 13 floating point
michael@0 10 * parameters are delivered in registers and are not on the stack, although
michael@0 11 * stack space is allocated for them. The integer parameters are delivered
michael@0 12 * in GPRs r3 through r10. The first 8 words of the parameter area on the
michael@0 13 * stack shadow these registers. A word will either be in a register or on
michael@0 14 * the stack, but not in both. Although the first floating point parameters
michael@0 15 * are passed in floating point registers, GPR space and stack space is
michael@0 16 * reserved for them as well.
michael@0 17 *
michael@0 18 * SharedStub has passed pointers to the parameter section of the stack
michael@0 19 * and saved copies of the GPRs and FPRs used for parameter passing. We
michael@0 20 * don't care about the first parameter (which is delivered here as the self
michael@0 21 * pointer), so SharedStub pointed us past that. argsGPR thus points to GPR
michael@0 22 * r4 (corresponding to the first argument after the self pointer) and
michael@0 23 * argsStack points to the parameter section of the caller's stack frame
michael@0 24 * reserved for the same argument. This way, it is possible to reference
michael@0 25 * either argsGPR or argsStack with the same index.
michael@0 26 *
michael@0 27 * Contrary to the assumption made by the previous implementation, the
michael@0 28 * Mac OS X PowerPC ABI doesn't impose any special alignment restrictions on
michael@0 29 * parameter sections of stacks. Values that are 64 bits wide appear on the
michael@0 30 * stack without any special padding.
michael@0 31 *
michael@0 32 * See also xptcstubs_asm_ppc_darwin.s.m4:_SharedStub.
michael@0 33 *
michael@0 34 * ABI reference:
michael@0 35 * http://developer.apple.com/documentation/DeveloperTools/Conceptual/
michael@0 36 * MachORuntime/PowerPCConventions/chapter_3_section_1.html */
michael@0 37
michael@0 38 extern "C" nsresult ATTRIBUTE_USED
michael@0 39 PrepareAndDispatch(
michael@0 40 nsXPTCStubBase *self,
michael@0 41 uint32_t methodIndex,
michael@0 42 uint32_t *argsStack,
michael@0 43 uint32_t *argsGPR,
michael@0 44 double *argsFPR) {
michael@0 45 #define PARAM_BUFFER_COUNT 16
michael@0 46 #define PARAM_FPR_COUNT 13
michael@0 47 #define PARAM_GPR_COUNT 7
michael@0 48
michael@0 49 nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
michael@0 50 nsXPTCMiniVariant *dispatchParams = nullptr;
michael@0 51 const nsXPTMethodInfo *methodInfo;
michael@0 52 uint8_t paramCount;
michael@0 53 uint8_t i;
michael@0 54 nsresult result = NS_ERROR_FAILURE;
michael@0 55 uint32_t argIndex = 0;
michael@0 56 uint32_t fprIndex = 0;
michael@0 57
michael@0 58 typedef struct {
michael@0 59 uint32_t hi;
michael@0 60 uint32_t lo;
michael@0 61 } DU;
michael@0 62
michael@0 63 NS_ASSERTION(self, "no self");
michael@0 64
michael@0 65 self->mEntry->GetMethodInfo(uint16_t(methodIndex), &methodInfo);
michael@0 66 NS_ASSERTION(methodInfo, "no method info");
michael@0 67
michael@0 68 paramCount = methodInfo->GetParamCount();
michael@0 69
michael@0 70 if(paramCount > PARAM_BUFFER_COUNT) {
michael@0 71 dispatchParams = new nsXPTCMiniVariant[paramCount];
michael@0 72 }
michael@0 73 else {
michael@0 74 dispatchParams = paramBuffer;
michael@0 75 }
michael@0 76 NS_ASSERTION(dispatchParams,"no place for params");
michael@0 77
michael@0 78 for(i = 0; i < paramCount; i++, argIndex++) {
michael@0 79 const nsXPTParamInfo &param = methodInfo->GetParam(i);
michael@0 80 const nsXPTType &type = param.GetType();
michael@0 81 nsXPTCMiniVariant *dp = &dispatchParams[i];
michael@0 82 uint32_t theParam;
michael@0 83
michael@0 84 if(argIndex < PARAM_GPR_COUNT)
michael@0 85 theParam = argsGPR[argIndex];
michael@0 86 else
michael@0 87 theParam = argsStack[argIndex];
michael@0 88
michael@0 89 if(param.IsOut() || !type.IsArithmetic())
michael@0 90 dp->val.p = (void *) theParam;
michael@0 91 else {
michael@0 92 switch(type) {
michael@0 93 case nsXPTType::T_I8:
michael@0 94 dp->val.i8 = (int8_t) theParam;
michael@0 95 break;
michael@0 96 case nsXPTType::T_I16:
michael@0 97 dp->val.i16 = (int16_t) theParam;
michael@0 98 break;
michael@0 99 case nsXPTType::T_I32:
michael@0 100 dp->val.i32 = (int32_t) theParam;
michael@0 101 break;
michael@0 102 case nsXPTType::T_U8:
michael@0 103 dp->val.u8 = (uint8_t) theParam;
michael@0 104 break;
michael@0 105 case nsXPTType::T_U16:
michael@0 106 dp->val.u16 = (uint16_t) theParam;
michael@0 107 break;
michael@0 108 case nsXPTType::T_U32:
michael@0 109 dp->val.u32 = (uint32_t) theParam;
michael@0 110 break;
michael@0 111 case nsXPTType::T_I64:
michael@0 112 case nsXPTType::T_U64:
michael@0 113 ((DU *)dp)->hi = (uint32_t) theParam;
michael@0 114 if(++argIndex < PARAM_GPR_COUNT)
michael@0 115 ((DU *)dp)->lo = (uint32_t) argsGPR[argIndex];
michael@0 116 else
michael@0 117 ((DU *)dp)->lo = (uint32_t) argsStack[argIndex];
michael@0 118 break;
michael@0 119 case nsXPTType::T_BOOL:
michael@0 120 dp->val.b = (bool) theParam;
michael@0 121 break;
michael@0 122 case nsXPTType::T_CHAR:
michael@0 123 dp->val.c = (char) theParam;
michael@0 124 break;
michael@0 125 case nsXPTType::T_WCHAR:
michael@0 126 dp->val.wc = (wchar_t) theParam;
michael@0 127 break;
michael@0 128 case nsXPTType::T_FLOAT:
michael@0 129 if(fprIndex < PARAM_FPR_COUNT)
michael@0 130 dp->val.f = (float) argsFPR[fprIndex++];
michael@0 131 else
michael@0 132 dp->val.f = *(float *) &argsStack[argIndex];
michael@0 133 break;
michael@0 134 case nsXPTType::T_DOUBLE:
michael@0 135 if(fprIndex < PARAM_FPR_COUNT)
michael@0 136 dp->val.d = argsFPR[fprIndex++];
michael@0 137 else
michael@0 138 dp->val.d = *(double *) &argsStack[argIndex];
michael@0 139 argIndex++;
michael@0 140 break;
michael@0 141 default:
michael@0 142 NS_ERROR("bad type");
michael@0 143 break;
michael@0 144 }
michael@0 145 }
michael@0 146 }
michael@0 147
michael@0 148 result = self->mOuter->
michael@0 149 CallMethod((uint16_t)methodIndex, methodInfo, dispatchParams);
michael@0 150
michael@0 151 if(dispatchParams != paramBuffer)
michael@0 152 delete [] dispatchParams;
michael@0 153
michael@0 154 return result;
michael@0 155 }
michael@0 156
michael@0 157 #define STUB_ENTRY(n)
michael@0 158 #define SENTINEL_ENTRY(n) \
michael@0 159 nsresult nsXPTCStubBase::Sentinel##n() \
michael@0 160 { \
michael@0 161 NS_ERROR("nsXPTCStubBase::Sentinel called"); \
michael@0 162 return NS_ERROR_NOT_IMPLEMENTED; \
michael@0 163 }
michael@0 164
michael@0 165 #include "xptcstubsdef.inc"

mercurial