1 /*---------------------------------------------------------------------------*
2 Project: How to set up new/delete operators for C++
3 File: cppsetupdemo.cpp
4
5 Copyright 1998, 1999 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Log: cppsetupdemo.cpp,v $
14 Revision 1.3 2007/07/12 10:17:52 hiratsu
15 delete[] was missing. Fixed.
16
17 Revision 1.2 2006/02/20 04:13:11 mitu
18 changed include path from dolphin/ to revolution/.
19
20 Revision 1.1 2006/01/13 11:24:13 hiratsu
21 Initial check in.
22
23
24 4 6/11/01 7:55p Tian
25 Integrated SN changes
26
27 3 3/16/01 12:04p Tian
28 Comments fix
29
30 2 9/29/00 5:27p Tian
31 OS now supports pre-main new.
32
33 1 6/22/00 7:24p Tian
34 Initial checkin.
35 $NoKeywords: $
36 *---------------------------------------------------------------------------*/
37
38 /*---------------------------------------------------------------------------*
39 This demo shows how to override the standard new/delete operators with the
40 Dolphin OS memory allocator. Note the following important caveats:
41
42 - the standard Metrowerks new/delete operators are NOT supported,
43 and will cause a DSI exception if you attempt to use them.
44
45 - this demo works because our new/delete operators occur earlier in
46 the link order than the Metrowerks Standard Libraries. If the MSL
47 libraries occur earlier in the link order than your definition of
48 new/delete, then the MSL new/delete will be used throughout your
49 code.
50
51 This demo does show how to use static global constructors. The trick is
52 to initialize the heap in the first invocation of new(). The flag
53 /IsHeapInitialized/ is used in this example to indicate whether or not
54 the heap has been initialized.
55 *---------------------------------------------------------------------------*/
56
57 #include <revolution.h>
58 #include <stddef.h>
59 /*---------------------------------------------------------------------------*
60 Override new and delete
61 *---------------------------------------------------------------------------*/
62
63 #define HEAP_ID 0
64
65 static BOOL IsHeapInitialized = FALSE;
66
67
68 /*---------------------------------------------------------------------------*
69 Name: CPPInit
70
71 Description: Initializes the Dolphin OS memory allocator and ensures that
72 new and delete will work properly.
73
74 Arguments: None.
75
76 Returns: None.
77 *---------------------------------------------------------------------------*/
CPPInit()78 static void CPPInit()
79 {
80 void* arenaLo;
81 void* arenaHi;
82
83 if (IsHeapInitialized)
84 {
85 return;
86 }
87
88
89 arenaLo = OSGetArenaLo();
90 arenaHi = OSGetArenaHi();
91
92 // Create a heap
93 // OSInitAlloc should only ever be invoked once.
94 arenaLo = OSInitAlloc(arenaLo, arenaHi, 1); // 1 heap
95 OSSetArenaLo(arenaLo);
96
97 // Ensure boundaries are 32B aligned
98 arenaLo = (void*)OSRoundUp32B(arenaLo);
99 arenaHi = (void*)OSRoundDown32B(arenaHi);
100
101 // The boundaries given to OSCreateHeap should be 32B aligned
102 OSSetCurrentHeap(OSCreateHeap(arenaLo, arenaHi));
103 // From here on out, OSAlloc and OSFree behave like malloc and free
104 // respectively
105 OSSetArenaLo(arenaLo=arenaHi);
106 IsHeapInitialized = TRUE;
107
108 }
109
operator new(size_t blocksize)110 inline void* operator new ( size_t blocksize )
111 {
112 if (!IsHeapInitialized)
113 {
114 CPPInit();
115 }
116 return OSAllocFromHeap(HEAP_ID, blocksize);
117 }
118
operator new[](size_t blocksize)119 inline void* operator new[] ( size_t blocksize )
120 {
121 if (!IsHeapInitialized)
122 {
123 CPPInit();
124 }
125 return OSAllocFromHeap(HEAP_ID, blocksize);
126 }
127
operator delete(void * block)128 inline void operator delete ( void* block )
129 {
130 OSFreeToHeap(HEAP_ID, block);
131 }
132
operator delete[](void * block)133 inline void operator delete[] ( void* block )
134 {
135 OSFreeToHeap(HEAP_ID, block);
136 }
137
138
139
140 /*---------------------------------------------------------------------------*
141 Trivial C++ code to test new and delete
142 *---------------------------------------------------------------------------*/
143
144
145 class Foo
146 {
147 private:
148 u32 a;
149 u32 b;
150 char* array;
151
152 public:
153 Foo();
154 ~Foo();
155
printA(void)156 void printA(void)
157 {
158 OSReport("a = %d\n", a);
159 }
160 void printB(void);
161 };
162
163
164 /*---------------------------------------------------------------------------*
165 Name: Foo::Foo
166
167 Description: Constructor for class Foo. Simply initialize private
168 members.
169
170 Arguments:
171
172 Returns:
173 *---------------------------------------------------------------------------*/
Foo()174 Foo::Foo()
175 {
176 a = 42;
177 b = 24;
178
179 array = new char[32];
180 }
181
182
183 /*---------------------------------------------------------------------------*
184 Name: Foo::~Foo
185
186 Description: Destructor for class Foo. Performs an OSReport so we know
187 it got called properly.
188
189 Arguments:
190
191 Returns:
192 *---------------------------------------------------------------------------*/
~Foo()193 Foo::~Foo()
194 {
195 OSReport("Foo destructor\n");
196 delete [] array;
197 }
198
199
200
201 /*---------------------------------------------------------------------------*
202 Name: Foo::printB
203
204 Description: function to print out b member
205
206 Arguments:
207
208 Returns:
209 *---------------------------------------------------------------------------*/
printB()210 void Foo::printB()
211 {
212 OSReport("b = %d\n", b);
213 }
214 static Foo StaticFoo;
215
216
main()217 int main()
218 {
219 Foo * foo;
220
221 OSInit();
222 CPPInit();
223
224 foo = new Foo;
225
226 foo->printA();
227 foo->printB();
228 StaticFoo.printA();
229
230 delete foo;
231 return 0;
232 }
233