/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Specify explicitly a symbol for this function, don't try to guess the c++ mangled symbol. */ static nsresult PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args) asm("_PrepareAndDispatch")
DONT_DROP_OR_WARN;
uint32_t* ap = args; for(i = 0; i < paramCount; i++, ap++)
{ const nsXPTParamInfo& param = info->Param(i); const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = ¶mBuffer[i];
if (i == indexOfJSContext)
ap++;
if(param.IsOut() || !type.IsArithmetic())
{
dp->val.p = (void*) *ap; continue;
} // else switch(type)
{ case nsXPTType::T_I8 : dp->val.i8 = *((int8_t*) ap); break; case nsXPTType::T_I16 : dp->val.i16 = *((int16_t*) ap); break; case nsXPTType::T_I32 : dp->val.i32 = *((int32_t*) ap); break; case nsXPTType::T_I64 : dp->val.i64 = *((int64_t*) ap); ap++; break; case nsXPTType::T_U8 : dp->val.u8 = *((uint8_t*) ap); break; case nsXPTType::T_U16 : dp->val.u16 = *((uint16_t*)ap); break; case nsXPTType::T_U32 : dp->val.u32 = *((uint32_t*)ap); break; case nsXPTType::T_U64 : dp->val.u64 = *((uint64_t*)ap); ap++; break; case nsXPTType::T_FLOAT : dp->val.f = *((float*) ap); break; case nsXPTType::T_DOUBLE : dp->val.d = *((double*) ap); ap++; break; case nsXPTType::T_BOOL : dp->val.b = *((bool*) ap); break; case nsXPTType::T_CHAR : dp->val.c = *((char*) ap); break; case nsXPTType::T_WCHAR : dp->val.wc = *((wchar_t*) ap); break; default:
NS_ERROR("bad type"); break;
}
}
nsresult result = self->mOuter->CallMethod((uint16_t)methodIndex, info,
paramBuffer);
return result;
}
/* * This is our shared stub. * * r0 = Self. * * The Rules: * We pass an (undefined) number of arguments into this function. * The first 3 C++ arguments are in r1 - r3, the rest are built * by the calling function on the stack. * * We are allowed to corrupt r0 - r3, ip, and lr. * * Other Info: * We pass the stub number in using `ip'. * * Implementation: * - We save r1 to r3 inclusive onto the stack, which will be * immediately below the caller saved arguments. * - setup r2 (PrepareAndDispatch's args pointer) to point at * the base of all these arguments * - Save LR (for the return address) * - Set r1 (PrepareAndDispatch's methodindex argument) from ip * - r0 is passed through (self) * - Call PrepareAndDispatch * - When the call returns, we return by loading the PC off the * stack, and undoing the stack (one instruction)! *
*/
__asm__ ("\n\
.text \n\
.align 2 \n\
SharedStub: \n\
stmfd sp!, {r1, r2, r3} \n\
mov r2, sp \n\
str lr, [sp, #-4]! \n\
mov r1, ip \n\
bl _PrepareAndDispatch \n\
ldr pc, [sp], #16");
/* * Create sets of stubs to call the SharedStub. * We don't touch the stack here, nor any registers, other than IP. * IP is defined to be corruptable by a called function, so we are * safe to use it. * * This will work with or without optimisation.
*/
/* * Note : As G++3 ABI contains the length of the functionname in the * mangled name, it is difficult to get a generic assembler mechanism like * in the G++ 2.95 case. * Create names would be like : * _ZN14nsXPTCStubBase5Stub9Ev * _ZN14nsXPTCStubBase6Stub13Ev * _ZN14nsXPTCStubBase7Stub144Ev * Use the assembler directives to get the names right...
*/
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.