In XPConnect, native values are passed around within nsXPTCMiniVariant objects.
an [nsXPTCMiniVariant] contains 64-bits of data in a union type.
nsXPTCMiniVariant values are created by the platform-specific glue code and
passed into XPConnect proper when calling from C++ into JS.
When calling from JS into C++, we instead create nsXPTCVariant objects and pass
them into the glue code. These objects have extra information in addition to the
nsXPTCMiniVariant: namely they also have a `type` field with the type stored in
the variant, space for flags, and a `ptr` field which is passed over IPC instead
of the inner nsXPTCMiniVariant when a flag (`PTR_IS_DATA`) is set.
The JSValue type in XPConnect is always passed as a pointer to a JSValue object,
both for in parameters and out parameters. This is handled by making the JSValue
type be unconditionally flagged as [`IsIndirect()`] This flag is also used for
all types of outparameters.
When the `IsIndirect()` flag is set, it means that the actual data is stored in
the nsXPTCVariant's val field, and it sets the flag to tell the glue code to
instead pass the `ptr` field (which is always pointing to the `val` field for
[legacy reasons]) into the C++ code.
In contrast "dipper" is a different and super weird flag. Currently only the
string class types (nsACString & nsAString) are marked as "dipper". A "dipper"
type is always passed as an "in" type (and thus always passed "directly"), even
when it's actually an out parameter.
XPConnect treats these types as though they are pointer types (nsAString*). This
means that there is no space in the nsXPTCVariant to store the actual nsAString
types when passing from JS into C++, so these values have to be allocated by a
different mechanism (in the current code, there is a size 2 buffer for each
string type in the context and once that buffer is exceeded, we heap allocate
the nsString values).
In effect, the current state looks something like this:
+------------+---------------------+---------------------+
| type | out (xpt/native) | in (xpt/native) |
+------------+---------------------+---------------------+
| TD_INT32 | indirect (int32_t*) | direct (int32_t) |
+------------+---------------------+---------------------+
| TD_JSVAL | indirect (JSValue*) | indirect (JSValue*) |
+------------+---------------------+---------------------+
| TD_ASTRING | direct (nsAString*) | direct (nsAString*) |
+------------+---------------------+---------------------+
This patch ensures there is enough space in the nsXPTCVariant to fit the
nsString value, and switches string class types to being unconditionally
indirect instead of using the dipper system. This allows us to delete a ton of
dipper-specific code, and unify the indirect and string class codepaths.
This only affects the size of nsXPTCVariant objects, and does not affect
nsXPTCMiniVariant objects. nsXPTCVariant objects are never allocated by the
platform-specific binding code, rather, they are allocated in an AutoTArray on
the stack as part of the CallMethodHelper object.
The size increase is a total of 1 word, so 4 bytes in 32-bit builds, and 8 bytes
in 64-bit builds, which is ignorable for stack allocated objects.
[nsXPTCMiniVariant]: https://searchfox.org/mozilla-central/rev/eb6c5214a63e20a3fff455e92c876287a8d2e188/xpcom/reflect/xptcall/xptcall.h#20-47
[`IsIndirect()`]: https://searchfox.org/mozilla-central/rev/c0d81882c7941c4ff13a50603e37095cdab0d1ea/xpcom/reflect/xptinfo/xptinfo.h#371
[legacy reasons]: https://searchfox.org/mozilla-central/rev/eb6c5214a63e20a3fff455e92c876287a8d2e188/xpcom/reflect/xptcall/xptcall.h#66-79
This type is fairly simple on the idl parsing side of things. I handle it in the
same way that special types such as ns[C]String, nsid, and jsval are handled, by
using a special native type.
The logic for converting the value between C++ and JS follows the existing logic
from the nsISupports <=> JS Promise conversions.
This patch goes through the XPConnect conversion methods, and adds cases for
T_DOMOBJECT which call the Wrap, Unwrap, and Cleanup methods from the
nsXPTDOMObjectInfo objects created in the last part.
For consistency with normal interface pointers, and because it wasn't too
complex, I also added support for including T_DOMOBJECTs in XPCOM arrays.
Due to the decision to keep the old API on nsXPTInterfaceInfo in part 4, this is
a fairly straightforward patch.
1. I had to change a couple of consumers of `IsRetval()` due to the movement of
that flag.
2. I changed all code which held a nsIInterfaceInfo to hold an `const
nsXPTInterfaceInfo*` instead.
3. I changed code which used the nsIInterfaceInfoManager to instead call the
static methods on nsXPTInterfaceInfo.
Unfortunately, I wasn't able to figure out a way to make firefox build & run in
the intermediate stages of these commits. Because of this, I am going to just
delete most of the code which I am deleting in the first patch, as I figure that
those are somewhat uninteresting changes, and then make the other changes in the
following patches.
In total, the following things are deleted:
1. All of xpcom/typelib, except for `xpt/tools` - this directory is being
subsumed entirely into xpcom/reflect/xptinfo.
2. Most of the code in xpcom/reflect/xptinfo, it is being rewritten to avoid
allocating and contain all of the necessary data structures.
3. idl-parser's typelib.py XPT generator, as it will be replaced.
4. Most includes of files which have been deleted.
NOTE: xpcom/typelib/xpt/tools/xpt.py was not removed, as it is used by bundling
code & bundling tests, which we don't want to remove yet.
nsXPTMethodInfo is a nicer structure to use, and this paves the way
for making the two types different, which will be needed if I make
XPTMethodDescriptor statically allocated.
Also, use the higher level accessor methods.
MozReview-Commit-ID: JbRdLU5Wwyt
--HG--
extra : rebase_source : 48f6c4e98e43c75006ceeb02bd727b59d3726681
The clang-cl-specific code is hitting https://bugs.llvm.org/show_bug.cgi?id=35482 on 32-bit ThinLTO builds. As far as I can tell, this workaround is no longer needed in clang-cl anyway; it should be able to support declspec(naked) etc nowadays.
Drive-by MSVC warnings fix.
--HG--
extra : rebase_source : a8b585c554674daca6d75bae66c1a1d892ed6e57
This Makefile.in contains a bunch of cruft for Tier-3 platforms. If
someone is still supporting any of them they can make the necessary
fixes to moz.build files themselves.
MozReview-Commit-ID: HxbbCv395Y5
--HG--
extra : rebase_source : 94f04128d2b3dd1285dfeafbfeb320b2f0d0bb19
extra : histedit_source : 2353127161ae58e54b6296e98b6b4b972ae439fe
Add breakpoint support for AArch64, and fix a scanf format specifier
warning. Also fix an #if line in xptcinvoke_arm.cpp to work as intended.
MozReview-Commit-ID: BSjYVD8Zq0t
In the 32-bit parisc runtime, the first four non floating-point
arguments are passed in registers (%r26, %r25, %r24 and %r23).
The remaining arguments are passed on the stack. There are four
reserved slots on the stack that the callee can use to save the
first four argument registers if the callee desires.
The StubN functions are special in that arguments are not explicitly
declared. %r26 is used for the "self" pointer. The call to SharedStub(n)
loads n into %r26 and clobbers the "self" pointer in %r26. The hppa
SharedStub implementation expects to find the "self" pointer on the
stack in the slot reserved for StubN. However, gcc doesn't copy any
arguments to the stack as no arguments are declared for StubN. Even
if it did, there's no guarantee that we could force gcc to save the
argument on the stack as that's more expensive than copying to a
free register. Thus, we need to copy %r26 to the stack slot manually.
The invoke_copy_to_stack() function passes incorrect "stack_args" and
"end" arguments to the alloc_word() utility function, for parameter types
T_I8..T_I64, T_U8..T_U64, T_BOOL, T_CHAR and T_WCHAR.
Namely, the "end" input parameter of invoke_copy_to_stack(), which is
currently incorrectly passed as "end" to alloc_word(), points to the very
end of the entire exchange area between _NS_InvokeByIndex() and
invoke_copy_to_stack(). However, alloc_word()'s "end" parameter should
point to the end of the "ireg" (integer registers) sub-area of the
exchange area. That is, "ireg_end" should be passed to alloc_word() as
"end".
Because invoke_copy_to_stack()'s "end" input parameter is strictly greater
than "ireg_end", alloc_word() will happily trample over the "freg"
(floating point registers) area, on the above-mentioned type branches,
given a large enough "paramCount".
Similarly, as second argument, "stack_args" should be passed to
alloc_word(), pointing to the next available stack slot, for spilled-over
arguments. Passing "stk", which initially points to the base of the entire
exchange area (and hence the base of the "ireg" area) makes no sense.
The two other alloc_word() calls in the function are correct. So
centralize all calls to alloc_word() to a single location -- thereby
ending up with a sole call site per alloc_XXX() function --, and compute
only the last argument, "word", conditionally.
This fixes an obscure SIGSEGV in AARCH64 Firefox. Triggering the bug
requires a target function with seven integer-like parameters (not
counting the implicit "this" -- aka "that" -- parameter), followed by at
least one parameter of the above buggy types. nsIOService::NewChannel2()
is such a target function, for example.
DONTBUILD because NPTOB
This removes the unnecessary setting of c-basic-offset from all
python-mode files.
This was automatically generated using
perl -pi -e 's/; *c-basic-offset: *[0-9]+//'
... on the affected files.
The bulk of these files are moz.build files but there a few others as
well.
MozReview-Commit-ID: 2pPf3DEiZqx
--HG--
extra : rebase_source : 0a7dcac80b924174a2c429b093791148ea6ac204
On win32, NS_InvokeByIndex is implemented with inline assembly. This
inline assembly assumes that it is wrapped by the compiler with the
standard x86 prologue and epilogue:
push ebp
mov ebp, esp
[inline assembly that manipulates the stack pointer]
pop ebp
ret
In particular, the last instruction of the inline assembly is:
mov esp, ebp
which cancels out the effects of the stack manipulation performed by all
the inline assembly that proceeds the instruction.
When compiling with clang-cl, however, the above assumption does not
hold, as clang-cl inserts a more complex prologue and epilogue,
something like:
push ebp
mov ebp, esp
sub esp, frame_size
[save registers into stack frame]
[inline assembly that manipulates the stack pointer]
[restore registers from stack frame]
add esp, frame_size
mov esp, ebp
pop ebp
ret
Combining this more extensive prologue and epilogue with the assumptions
of the inline assembly leads to interesting crashes when
NS_InvokeByIndex is called: the inline assembly effectively deallocates
the stack allocated by the inline assembly *and* the stack frame
allocated by the compiler itself. The compiler-generated code then
attemptes to deallocate the stack frame, leading to the crash, as the
code now returns to an unspecified address.
To avoid these sorts of problems in clang-cl and make the code more
robust generally, let's move the NS_InvokeByIndex implementation to a
separate assembly file. We can then write exactly what we need to have
happen, safe from any manipulations of the compiler.
Since we don't compile much (any?) code in Gecko with MASM, we need to
add the /SAFESEH flag to the assembler invocation so that the object
file with be appropriately marked as not containing exception handlers;
the linker (which is invoked with the /SAFESEH flag itself) will then
consent to link it into libxul.
xptcstubs_arm mostly works on iOS but Apple's assembler is ridiculous so
the inline assembly for the SharedStub and the stub methods needs judicious
preprocessor use.
--HG--
extra : commitid : ChAcktTzVX0
extra : rebase_source : 11fbaa4940fd9aaeba51e2477d4c8b1a7851791e
The patch removes 455 occurrences of FAIL_ON_WARNINGS from moz.build files, and
adds 78 instances of ALLOW_COMPILER_WARNINGS. About half of those 78 are in
code we control and which should be removable with a little effort.
--HG--
extra : rebase_source : 82e3387abfbd5f1471e953961d301d3d97ed2973