Bug 1845715 - Check for failure when getting RegExp match result template r=iain
[gecko.git] / memory / build / mozmemory_wrap.cpp
blob3420fd96935a180754f7deeccc06bcf7b5b14dcd
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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 #include <string.h>
8 #include "mozmemory_wrap.h"
9 #include "mozilla/Types.h"
11 // Declare malloc implementation functions with the right return and
12 // argument types.
13 #define NOTHROW_MALLOC_DECL(name, return_type, ...) \
14 MOZ_MEMORY_API return_type name##_impl(__VA_ARGS__) noexcept(true);
15 #define MALLOC_DECL(name, return_type, ...) \
16 MOZ_MEMORY_API return_type name##_impl(__VA_ARGS__);
17 #define MALLOC_FUNCS MALLOC_FUNCS_MALLOC
18 #include "malloc_decls.h"
20 // strndup and strdup may be defined as macros in string.h, which would
21 // clash with the definitions below.
22 #undef strndup
23 #undef strdup
25 MOZ_MEMORY_API char* strndup_impl(const char* src, size_t len) {
26 char* dst = (char*)malloc_impl(len + 1);
27 if (dst) {
28 strncpy(dst, src, len);
29 dst[len] = '\0';
31 return dst;
34 MOZ_MEMORY_API char* strdup_impl(const char* src) {
35 size_t len = strlen(src);
36 return strndup_impl(src, len);
39 #ifdef ANDROID
40 # include <stdarg.h>
41 # include <stdio.h>
43 MOZ_MEMORY_API int vasprintf_impl(char** str, const char* fmt, va_list ap) {
44 char *ptr, *_ptr;
45 int ret;
47 if (str == NULL || fmt == NULL) {
48 return -1;
51 ptr = (char*)malloc_impl(128);
52 if (ptr == NULL) {
53 *str = NULL;
54 return -1;
57 ret = vsnprintf(ptr, 128, fmt, ap);
58 if (ret < 0) {
59 free_impl(ptr);
60 *str = NULL;
61 return -1;
64 _ptr = reinterpret_cast<char*>(realloc_impl(ptr, ret + 1));
65 if (_ptr == NULL) {
66 free_impl(ptr);
67 *str = NULL;
68 return -1;
71 *str = _ptr;
73 return ret;
76 MOZ_MEMORY_API int asprintf_impl(char** str, const char* fmt, ...) {
77 int ret;
78 va_list ap;
79 va_start(ap, fmt);
81 ret = vasprintf_impl(str, fmt, ap);
83 va_end(ap);
85 return ret;
87 #endif
89 #ifdef XP_WIN
90 # include <wchar.h>
92 // We also need to provide our own impl of wcsdup so that we don't ask
93 // the CRT for memory from its heap (which will then be unfreeable).
94 MOZ_MEMORY_API wchar_t* wcsdup_impl(const wchar_t* src) {
95 size_t len = wcslen(src);
96 wchar_t* dst = (wchar_t*)malloc_impl((len + 1) * sizeof(wchar_t));
97 if (dst) wcsncpy(dst, src, len + 1);
98 return dst;
101 MOZ_MEMORY_API void* _aligned_malloc_impl(size_t size, size_t alignment) {
102 return memalign_impl(alignment, size);
105 # ifdef __MINGW32__
106 MOZ_BEGIN_EXTERN_C
107 // As in mozjemalloc.cpp, we generate aliases for functions
108 // redirected in mozglue.def
109 void* _aligned_malloc(size_t size, size_t alignment)
110 __attribute__((alias(MOZ_STRINGIFY(_aligned_malloc_impl))));
111 void _aligned_free(void* aPtr) __attribute__((alias(MOZ_STRINGIFY(free_impl))));
113 char* strndup(const char* src, size_t len)
114 __attribute__((alias(MOZ_STRINGIFY(strdup_impl))));
115 char* strdup(const char* src)
116 __attribute__((alias(MOZ_STRINGIFY(strdup_impl))));
117 char* _strdup(const char* src)
118 __attribute__((alias(MOZ_STRINGIFY(strdup_impl))));
119 wchar_t* wcsdup(const wchar_t* src)
120 __attribute__((alias(MOZ_STRINGIFY(wcsdup_impl))));
121 wchar_t* _wcsdup(const wchar_t* src)
122 __attribute__((alias(MOZ_STRINGIFY(wcsdup_impl))));
124 // jemalloc has _aligned_malloc, and friends. libc++.a contains
125 // references to __imp__aligned_malloc (and friends) because it
126 // is declared dllimport in the headers.
128 // The linker sees jemalloc's _aligned_malloc symbol in our objects,
129 // but then libc++.a comes along and needs __imp__aligned_malloc, which
130 // pulls in those parts of libucrt.a (or libmsvcrt.a in practice),
131 // which define both __imp__aligned_malloc and _aligned_malloc, and
132 // this causes a conflict. (And repeat for each of the symbols defined
133 // here.)
135 // The fix is to define not only an _aligned_malloc symbol (via an
136 // alias), but also define the __imp__aligned_malloc pointer to it.
137 // This prevents those parts of libucrt from being pulled in and causing
138 // conflicts.
139 // This is done with __MINGW_IMP_SYMBOL to handle x86/x64 differences.
140 void (*__MINGW_IMP_SYMBOL(_aligned_free))(void*) = _aligned_free;
141 void* (*__MINGW_IMP_SYMBOL(_aligned_malloc))(size_t, size_t) = _aligned_malloc;
142 char* (*__MINGW_IMP_SYMBOL(_strdup))(const char* src) = _strdup;
143 MOZ_END_EXTERN_C
144 # endif
145 #endif // XP_WIN