~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/nsprpub/pr/src/md/mac/mdmac.c

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* 
 
3
 * The contents of this file are subject to the Mozilla Public
 
4
 * License Version 1.1 (the "License"); you may not use this file
 
5
 * except in compliance with the License. You may obtain a copy of
 
6
 * the License at http://www.mozilla.org/MPL/
 
7
 * 
 
8
 * Software distributed under the License is distributed on an "AS
 
9
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
10
 * implied. See the License for the specific language governing
 
11
 * rights and limitations under the License.
 
12
 * 
 
13
 * The Original Code is the Netscape Portable Runtime (NSPR).
 
14
 * 
 
15
 * The Initial Developer of the Original Code is Netscape
 
16
 * Communications Corporation.  Portions created by Netscape are 
 
17
 * Copyright (C) 1998-2000 Netscape Communications Corporation.  All
 
18
 * Rights Reserved.
 
19
 * 
 
20
 * Contributor(s):
 
21
 * 
 
22
 * Alternatively, the contents of this file may be used under the
 
23
 * terms of the GNU General Public License Version 2 or later (the
 
24
 * "GPL"), in which case the provisions of the GPL are applicable 
 
25
 * instead of those above.  If you wish to allow use of your 
 
26
 * version of this file only under the terms of the GPL and not to
 
27
 * allow others to use your version of this file under the MPL,
 
28
 * indicate your decision by deleting the provisions above and
 
29
 * replace them with the notice and other provisions required by
 
30
 * the GPL.  If you do not delete the provisions above, a recipient
 
31
 * may use your version of this file under either the MPL or the
 
32
 * GPL.
 
33
 */
 
34
 
 
35
#include <Types.h>
 
36
#include <Timer.h>
 
37
#include <Files.h>
 
38
#include <Errors.h>
 
39
#include <Folders.h>
 
40
#include <Gestalt.h>
 
41
#include <Events.h>
 
42
#include <Processes.h>
 
43
#include <TextUtils.h>
 
44
#include <MixedMode.h>
 
45
#include <LowMem.h>
 
46
 
 
47
#include <fcntl.h>
 
48
#include <string.h>
 
49
#include <stdio.h>
 
50
#include <stdlib.h>
 
51
#include <stat.h>
 
52
#include <stdarg.h>
 
53
#include <unix.h>
 
54
 
 
55
#include "MacErrorHandling.h"
 
56
 
 
57
#include "primpl.h"
 
58
#include "prgc.h"
 
59
 
 
60
#include "mactime.h"
 
61
 
 
62
#include "mdmac.h"
 
63
 
 
64
// undefine getenv, so that _MD_GetEnv can call the version in NSStdLib::nsEnvironment.cpp.
 
65
#undef getenv
 
66
 
 
67
//
 
68
// Local routines
 
69
//
 
70
unsigned char GarbageCollectorCacheFlusher(PRUint32 size);
 
71
 
 
72
extern PRThread *gPrimaryThread;
 
73
extern ProcessSerialNumber gApplicationProcess;     // in macthr.c
 
74
 
 
75
 
 
76
//##############################################################################
 
77
//##############################################################################
 
78
#pragma mark -
 
79
#pragma mark CREATING MACINTOSH THREAD STACKS
 
80
 
 
81
 
 
82
enum {
 
83
        uppExitToShellProcInfo                          = kPascalStackBased,
 
84
        uppStackSpaceProcInfo                           = kRegisterBased 
 
85
                                                                                  | RESULT_SIZE(SIZE_CODE(sizeof(long)))
 
86
                                                                                  | REGISTER_RESULT_LOCATION(kRegisterD0)
 
87
                                                                                  | REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(sizeof(UInt16)))
 
88
};
 
89
 
 
90
typedef CALLBACK_API( long , StackSpacePatchPtr )(UInt16 trapNo);
 
91
typedef REGISTER_UPP_TYPE(StackSpacePatchPtr)   StackSpacePatchUPP;
 
92
 
 
93
StackSpacePatchUPP        gStackSpacePatchUPP = NULL;
 
94
UniversalProcPtr          gStackSpacePatchCallThru = NULL;
 
95
long                            (*gCallOSTrapUniversalProc)(UniversalProcPtr,ProcInfoType,...) = NULL;
 
96
 
 
97
 
 
98
pascal long StackSpacePatch(UInt16 trapNo)
 
99
{
 
100
        char            tos;
 
101
        PRThread        *thisThread;
 
102
        
 
103
        thisThread = PR_CurrentThread();
 
104
        
 
105
        //      If we are the primary thread, then call through to the
 
106
        //      good ol' fashion stack space implementation.  Otherwise,
 
107
        //      compute it by hand.
 
108
        if ((thisThread == gPrimaryThread) ||   
 
109
                (&tos < thisThread->stack->stackBottom) || 
 
110
                (&tos > thisThread->stack->stackTop)) {
 
111
                return gCallOSTrapUniversalProc(gStackSpacePatchCallThru, uppStackSpaceProcInfo, trapNo);
 
112
        }
 
113
        else {
 
114
                return &tos - thisThread->stack->stackBottom;
 
115
        }
 
116
}
 
117
 
 
118
 
 
119
static void InstallStackSpacePatch(void)
 
120
{
 
121
        long                            systemVersion;
 
122
        OSErr                           err;
 
123
        CFragConnectionID       connID;
 
124
        Str255                          errMessage;
 
125
        Ptr                                     interfaceLibAddr;
 
126
        CFragSymbolClass        symClass;
 
127
        UniversalProcPtr        (*getOSTrapAddressProc)(UInt16);
 
128
        void                            (*setOSTrapAddressProc)(StackSpacePatchUPP, UInt16);
 
129
        UniversalProcPtr        (*newRoutineDescriptorProc)(ProcPtr,ProcInfoType,ISAType);
 
130
        
 
131
 
 
132
        err = Gestalt(gestaltSystemVersion,&systemVersion);
 
133
        if (systemVersion >= 0x00000A00)        // we don't need to patch StackSpace()
 
134
                return;
 
135
 
 
136
        // open connection to "InterfaceLib"
 
137
        err = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch, kFindCFrag,
 
138
                                                                                        &connID, &interfaceLibAddr, errMessage);
 
139
        PR_ASSERT(err == noErr);
 
140
        if (err != noErr)
 
141
                return;
 
142
 
 
143
        // get symbol GetOSTrapAddress
 
144
        err = FindSymbol(connID, "\pGetOSTrapAddress", &(Ptr)getOSTrapAddressProc, &symClass);
 
145
        if (err != noErr)
 
146
                return;
 
147
 
 
148
        // get symbol SetOSTrapAddress
 
149
        err = FindSymbol(connID, "\pSetOSTrapAddress", &(Ptr)setOSTrapAddressProc, &symClass);
 
150
        if (err != noErr)
 
151
                return;
 
152
        
 
153
        // get symbol NewRoutineDescriptor
 
154
        err = FindSymbol(connID, "\pNewRoutineDescriptor", &(Ptr)newRoutineDescriptorProc, &symClass);
 
155
        if (err != noErr)
 
156
                return;
 
157
        
 
158
        // get symbol CallOSTrapUniversalProc
 
159
        err = FindSymbol(connID, "\pCallOSTrapUniversalProc", &(Ptr)gCallOSTrapUniversalProc, &symClass);
 
160
        if (err != noErr)
 
161
                return;
 
162
 
 
163
        // get and set trap address for StackSpace (A065)
 
164
        gStackSpacePatchCallThru = getOSTrapAddressProc(0x0065);
 
165
        if (gStackSpacePatchCallThru)
 
166
        {
 
167
                gStackSpacePatchUPP =
 
168
                        (StackSpacePatchUPP)newRoutineDescriptorProc((ProcPtr)(StackSpacePatch), uppStackSpaceProcInfo, GetCurrentArchitecture());
 
169
                setOSTrapAddressProc(gStackSpacePatchUPP, 0x0065);
 
170
        }
 
171
 
 
172
#if DEBUG
 
173
        StackSpace();
 
174
#endif
 
175
}
 
176
 
 
177
 
 
178
//##############################################################################
 
179
//##############################################################################
 
180
#pragma mark -
 
181
#pragma mark ENVIRONMENT VARIABLES
 
182
 
 
183
 
 
184
typedef struct EnvVariable EnvVariable;
 
185
 
 
186
struct EnvVariable {
 
187
        char                    *variable;
 
188
        char                    *value;
 
189
        EnvVariable             *next;
 
190
};
 
191
 
 
192
EnvVariable             *gEnvironmentVariables = NULL;
 
193
 
 
194
char *_MD_GetEnv(const char *name)
 
195
{
 
196
        EnvVariable     *currentVariable = gEnvironmentVariables;
 
197
 
 
198
        while (currentVariable) {
 
199
                if (!strcmp(currentVariable->variable, name))
 
200
                        return currentVariable->value;
 
201
                        
 
202
                currentVariable = currentVariable->next;
 
203
        }
 
204
 
 
205
        return getenv(name);
 
206
}
 
207
 
 
208
PR_IMPLEMENT(int) 
 
209
_MD_PutEnv(const char *string)
 
210
{
 
211
        EnvVariable     *currentVariable = gEnvironmentVariables;
 
212
        char                    *variableCopy,
 
213
                                    *value,
 
214
                                        *current;
 
215
                                        
 
216
        variableCopy = strdup(string);
 
217
        PR_ASSERT(variableCopy != NULL);
 
218
 
 
219
        current = variableCopy;
 
220
        while (*current != '=')
 
221
                current++;
 
222
 
 
223
        *current = 0;
 
224
        current++;
 
225
 
 
226
        value = current;
 
227
 
 
228
        while (currentVariable) {
 
229
                if (!strcmp(currentVariable->variable, variableCopy))
 
230
                        break;
 
231
                
 
232
                currentVariable = currentVariable->next;
 
233
        }
 
234
 
 
235
        if (currentVariable == NULL) {
 
236
                currentVariable = PR_NEW(EnvVariable);
 
237
                
 
238
                if (currentVariable == NULL) {
 
239
                        PR_DELETE(variableCopy);
 
240
                        return -1;
 
241
                }
 
242
                
 
243
                currentVariable->variable = strdup(variableCopy);
 
244
                currentVariable->value = strdup(value);
 
245
                currentVariable->next = gEnvironmentVariables;
 
246
                gEnvironmentVariables = currentVariable;
 
247
        }
 
248
        
 
249
        else {
 
250
                PR_DELETE(currentVariable->value);
 
251
                currentVariable->value = strdup(current);
 
252
 
 
253
                /* This is a temporary hack.  Working on a real fix, remove this when done. */
 
254
                /* OK, there are two ways to access the  */
 
255
                /* library path, getenv() and PR_GetLibraryPath().  Take a look at PR_GetLibraryPath(). */
 
256
                /* You'll see that we keep the path in a global which is intialized at startup from */
 
257
                /* a call to getenv().  From then on, they have nothing in common. */
 
258
                /* We need to keep them in synch.  */
 
259
                if (strcmp(currentVariable->variable, "LD_LIBRARY_PATH") == 0)
 
260
                        PR_SetLibraryPath(currentVariable->value);
 
261
        }
 
262
        
 
263
        PR_DELETE(variableCopy);
 
264
        return 0;
 
265
}
 
266
 
 
267
 
 
268
 
 
269
//##############################################################################
 
270
//##############################################################################
 
271
#pragma mark -
 
272
#pragma mark MISCELLANEOUS
 
273
 
 
274
PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
 
275
{
 
276
    if (isCurrent) {
 
277
        (void) setjmp(t->md.jb);
 
278
    }
 
279
    *np = sizeof(t->md.jb) / sizeof(PRUint32);
 
280
    return (PRWord*) (t->md.jb);
 
281
}
 
282
 
 
283
void _MD_GetRegisters(PRUint32 *to)
 
284
{
 
285
  (void) setjmp((void*) to);
 
286
}
 
287
 
 
288
void _MD_EarlyInit()
 
289
{
 
290
        Handle                          environmentVariables;
 
291
 
 
292
        GetCurrentProcess(&gApplicationProcess);
 
293
 
 
294
        INIT_CRITICAL_REGION();
 
295
        InitIdleSemaphore();
 
296
 
 
297
#if !defined(MAC_NSPR_STANDALONE)
 
298
        // MacintoshInitializeMemory();  Moved to mdmacmem.c: AllocateRawMemory(Size blockSize)
 
299
#else
 
300
        MacintoshInitializeMemory();
 
301
#endif
 
302
        MacintoshInitializeTime();
 
303
        
 
304
        //      Install resource-controlled environment variables.
 
305
        
 
306
        environmentVariables = GetResource('Envi', 128);
 
307
        if (environmentVariables != NULL) {
 
308
        
 
309
                Size    resourceSize;
 
310
                char    *currentPutEnvString = (char *)*environmentVariables,
 
311
                                *currentScanChar = currentPutEnvString;
 
312
                                
 
313
                resourceSize = GetHandleSize(environmentVariables);                     
 
314
                DetachResource(environmentVariables);
 
315
                HLock(environmentVariables);
 
316
                
 
317
                while (resourceSize--) {
 
318
                
 
319
                        if ((*currentScanChar == '\n') || (*currentScanChar == '\r')) {
 
320
                                *currentScanChar = 0;
 
321
                                _MD_PutEnv (currentPutEnvString);
 
322
                                currentPutEnvString = currentScanChar + 1;
 
323
                        }
 
324
                
 
325
                        currentScanChar++;
 
326
                
 
327
                }
 
328
                
 
329
                DisposeHandle(environmentVariables);
 
330
 
 
331
        }
 
332
 
 
333
#ifdef PR_INTERNAL_LOGGING
 
334
        _MD_PutEnv ("NSPR_LOG_MODULES=clock:6,cmon:6,io:6,mon:6,linker:6,cvar:6,sched:6,thread:6");
 
335
#endif
 
336
 
 
337
        InstallStackSpacePatch();
 
338
}
 
339
 
 
340
void _MD_FinalInit()
 
341
{
 
342
        _MD_InitNetAccess();
 
343
}
 
344
 
 
345
void PR_InitMemory(void) {
 
346
#ifndef NSPR_AS_SHARED_LIB
 
347
        //      Needed for Mac browsers without Java.  We don't want them calling PR_INIT, since it
 
348
        //      brings in all of the thread support.  But we do need to allow them to initialize
 
349
        //      the NSPR memory package.
 
350
        //      This should go away when all clients of the NSPR want threads AND memory.
 
351
        MacintoshInitializeMemory();
 
352
#endif
 
353
}
 
354
 
 
355
//##############################################################################
 
356
//##############################################################################
 
357
#pragma mark -
 
358
#pragma mark TERMINATION
 
359
 
 
360
 
 
361
//      THIS IS *** VERY *** IMPORTANT... our CFM Termination proc.
 
362
//      This allows us to deactivate our Time Mananger task even
 
363
//      if we are not totally gracefully exited.  If this is not
 
364
//      done then we will randomly crash at later times when the
 
365
//      task is called after the app heap is gone.
 
366
 
 
367
#if TARGET_CARBON
 
368
extern OTClientContextPtr       clientContext;
 
369
#define CLOSE_OPEN_TRANSPORT()  CloseOpenTransportInContext(clientContext)
 
370
 
 
371
#else
 
372
 
 
373
#define CLOSE_OPEN_TRANSPORT()  CloseOpenTransport()
 
374
#endif /* TARGET_CARBON */
 
375
 
 
376
extern pascal void __NSTerminate(void);
 
377
 
 
378
void CleanupTermProc(void)
 
379
{
 
380
        _MD_StopInterrupts();   // deactive Time Manager task
 
381
 
 
382
        CLOSE_OPEN_TRANSPORT();
 
383
        TermIdleSemaphore();
 
384
        TERM_CRITICAL_REGION();
 
385
        
 
386
        __NSTerminate();
 
387
}
 
388
 
 
389
 
 
390
 
 
391
//##############################################################################
 
392
//##############################################################################
 
393
#pragma mark -
 
394
#pragma mark STRING OPERATIONS
 
395
 
 
396
#if !defined(MAC_NSPR_STANDALONE)
 
397
 
 
398
//      PStrFromCStr converts the source C string to a destination
 
399
//      pascal string as it copies. The dest string will
 
400
//      be truncated to fit into an Str255 if necessary.
 
401
//  If the C String pointer is NULL, the pascal string's length is set to zero
 
402
//
 
403
void 
 
404
PStrFromCStr(const char* src, Str255 dst)
 
405
{
 
406
        short   length  = 0;
 
407
        
 
408
        // handle case of overlapping strings
 
409
        if ( (void*)src == (void*)dst )
 
410
        {
 
411
                unsigned char*          curdst = &dst[1];
 
412
                unsigned char           thisChar;
 
413
                                
 
414
                thisChar = *(const unsigned char*)src++;
 
415
                while ( thisChar != '\0' ) 
 
416
                {
 
417
                        unsigned char   nextChar;
 
418
                        
 
419
                        // use nextChar so we don't overwrite what we are about to read
 
420
                        nextChar = *(const unsigned char*)src++;
 
421
                        *curdst++ = thisChar;
 
422
                        thisChar = nextChar;
 
423
                        
 
424
                        if ( ++length >= 255 )
 
425
                                break;
 
426
                }
 
427
        }
 
428
        else if ( src != NULL )
 
429
        {
 
430
                unsigned char*          curdst = &dst[1];
 
431
                short                           overflow = 255;         // count down so test it loop is faster
 
432
                register char           temp;
 
433
        
 
434
                // Can't do the K&R C thing of "while (*s++ = *t++)" because it will copy trailing zero
 
435
                // which might overrun pascal buffer.  Instead we use a temp variable.
 
436
                while ( (temp = *src++) != 0 ) 
 
437
                {
 
438
                        *(char*)curdst++ = temp;
 
439
                                
 
440
                        if ( --overflow <= 0 )
 
441
                                break;
 
442
                }
 
443
                length = 255 - overflow;
 
444
        }
 
445
        dst[0] = length;
 
446
}
 
447
 
 
448
 
 
449
void CStrFromPStr(ConstStr255Param pString, char **cString)
 
450
{
 
451
        // Allocates a cString and copies a Pascal string into it.
 
452
        unsigned int    len;
 
453
        
 
454
        len = pString[0];
 
455
        *cString = malloc(len+1);
 
456
        
 
457
        if (*cString != NULL) {
 
458
                strncpy(*cString, (char *)&pString[1], len);
 
459
                (*cString)[len] = NULL;
 
460
        }
 
461
}
 
462
 
 
463
 
 
464
void dprintf(const char *format, ...)
 
465
{
 
466
#if DEBUG
 
467
    va_list ap;
 
468
        Str255 buffer;
 
469
        
 
470
        va_start(ap, format);
 
471
        buffer[0] = PR_vsnprintf((char *)buffer + 1, sizeof(buffer) - 1, format, ap);
 
472
        va_end(ap);
 
473
        
 
474
        DebugStr(buffer);
 
475
#endif /* DEBUG */
 
476
}
 
477
 
 
478
#else
 
479
 
 
480
void debugstr(const char *debuggerMsg)
 
481
{
 
482
        Str255          pStr;
 
483
        
 
484
        PStrFromCStr(debuggerMsg, pStr);
 
485
        DebugStr(pStr);
 
486
}
 
487
 
 
488
 
 
489
char *strdup(const char *source)
 
490
{
 
491
        char    *newAllocation;
 
492
        size_t  stringLength;
 
493
 
 
494
        PR_ASSERT(source);
 
495
        
 
496
        stringLength = strlen(source) + 1;
 
497
        
 
498
        newAllocation = (char *)PR_MALLOC(stringLength);
 
499
        if (newAllocation == NULL)
 
500
                return NULL;
 
501
        BlockMoveData(source, newAllocation, stringLength);
 
502
        return newAllocation;
 
503
}
 
504
 
 
505
//      PStrFromCStr converts the source C string to a destination
 
506
//      pascal string as it copies. The dest string will
 
507
//      be truncated to fit into an Str255 if necessary.
 
508
//  If the C String pointer is NULL, the pascal string's length is set to zero
 
509
//
 
510
void PStrFromCStr(const char* src, Str255 dst)
 
511
{
 
512
        short   length  = 0;
 
513
        
 
514
        // handle case of overlapping strings
 
515
        if ( (void*)src == (void*)dst )
 
516
        {
 
517
                unsigned char*          curdst = &dst[1];
 
518
                unsigned char           thisChar;
 
519
                                
 
520
                thisChar = *(const unsigned char*)src++;
 
521
                while ( thisChar != '\0' ) 
 
522
                {
 
523
                        unsigned char   nextChar;
 
524
                        
 
525
                        // use nextChar so we don't overwrite what we are about to read
 
526
                        nextChar = *(const unsigned char*)src++;
 
527
                        *curdst++ = thisChar;
 
528
                        thisChar = nextChar;
 
529
                        
 
530
                        if ( ++length >= 255 )
 
531
                                break;
 
532
                }
 
533
        }
 
534
        else if ( src != NULL )
 
535
        {
 
536
                unsigned char*          curdst = &dst[1];
 
537
                short                           overflow = 255;         // count down so test it loop is faster
 
538
                register char           temp;
 
539
        
 
540
                // Can't do the K&R C thing of "while (*s++ = *t++)" because it will copy trailing zero
 
541
                // which might overrun pascal buffer.  Instead we use a temp variable.
 
542
                while ( (temp = *src++) != 0 ) 
 
543
                {
 
544
                        *(char*)curdst++ = temp;
 
545
                                
 
546
                        if ( --overflow <= 0 )
 
547
                                break;
 
548
                }
 
549
                length = 255 - overflow;
 
550
        }
 
551
        dst[0] = length;
 
552
}
 
553
 
 
554
 
 
555
void CStrFromPStr(ConstStr255Param pString, char **cString)
 
556
{
 
557
        // Allocates a cString and copies a Pascal string into it.
 
558
        unsigned int    len;
 
559
        
 
560
        len = pString[0];
 
561
        *cString = PR_MALLOC(len+1);
 
562
        
 
563
        if (*cString != NULL) {
 
564
                strncpy(*cString, (char *)&pString[1], len);
 
565
                (*cString)[len] = NULL;
 
566
        }
 
567
}
 
568
 
 
569
 
 
570
size_t strlen(const char *source)
 
571
{
 
572
        size_t currentLength = 0;
 
573
        
 
574
        if (source == NULL)
 
575
                return currentLength;
 
576
                        
 
577
        while (*source++ != '\0')
 
578
                currentLength++;
 
579
                
 
580
        return currentLength;
 
581
}
 
582
 
 
583
int strcmpcore(const char *str1, const char *str2, int caseSensitive)
 
584
{
 
585
        char    currentChar1, currentChar2;
 
586
 
 
587
        while (1) {
 
588
        
 
589
                currentChar1 = *str1;
 
590
                currentChar2 = *str2;
 
591
                
 
592
                if (!caseSensitive) {
 
593
                        
 
594
                        if ((currentChar1 >= 'a') && (currentChar1 <= 'z'))
 
595
                                currentChar1 += ('A' - 'a');
 
596
                
 
597
                        if ((currentChar2 >= 'a') && (currentChar2 <= 'z'))
 
598
                                currentChar2 += ('A' - 'a');
 
599
                
 
600
                }
 
601
        
 
602
                if (currentChar1 == '\0')
 
603
                        break;
 
604
        
 
605
                if (currentChar1 != currentChar2)
 
606
                        return currentChar1 - currentChar2;
 
607
                        
 
608
                str1++;
 
609
                str2++;
 
610
        
 
611
        }
 
612
        
 
613
        return currentChar1 - currentChar2;
 
614
}
 
615
 
 
616
int strcmp(const char *str1, const char *str2)
 
617
{
 
618
        return strcmpcore(str1, str2, true);
 
619
}
 
620
 
 
621
int strcasecmp(const char *str1, const char *str2)
 
622
{
 
623
        return strcmpcore(str1, str2, false);
 
624
}
 
625
 
 
626
 
 
627
void *memcpy(void *to, const void *from, size_t size)
 
628
{
 
629
        if (size != 0) {
 
630
#if DEBUG
 
631
                if ((UInt32)to < 0x1000)
 
632
                        DebugStr("\pmemcpy has illegal to argument");
 
633
                if ((UInt32)from < 0x1000)
 
634
                        DebugStr("\pmemcpy has illegal from argument");
 
635
#endif
 
636
                BlockMoveData(from, to, size);
 
637
        }
 
638
        return to;
 
639
}
 
640
 
 
641
void dprintf(const char *format, ...)
 
642
{
 
643
    va_list ap;
 
644
        char    *buffer;
 
645
        
 
646
        va_start(ap, format);
 
647
        buffer = (char *)PR_vsmprintf(format, ap);
 
648
        va_end(ap);
 
649
        
 
650
        debugstr(buffer);
 
651
        PR_DELETE(buffer);
 
652
}
 
653
 
 
654
void
 
655
exit(int result)
 
656
{
 
657
#pragma unused (result)
 
658
 
 
659
                ExitToShell();
 
660
}
 
661
 
 
662
void abort(void)
 
663
{
 
664
        exit(-1);
 
665
}
 
666
 
 
667
#endif
 
668
 
 
669
//##############################################################################
 
670
//##############################################################################
 
671
#pragma mark -
 
672
#pragma mark FLUSHING THE GARBAGE COLLECTOR
 
673
 
 
674
#if !defined(MAC_NSPR_STANDALONE)
 
675
 
 
676
unsigned char GarbageCollectorCacheFlusher(PRUint32)
 
677
{
 
678
 
 
679
    PRIntn is;
 
680
 
 
681
        UInt32          oldPriority;
 
682
 
 
683
        //      If java wasn't completely initialized, then bail 
 
684
        //      harmlessly.
 
685
        
 
686
        if (PR_GetGCInfo()->lock == NULL)
 
687
                return false;
 
688
 
 
689
#if DEBUG
 
690
        if (_MD_GET_INTSOFF() == 1)
 
691
                DebugStr("\pGarbageCollectorCacheFlusher at interrupt time!");
 
692
#endif
 
693
 
 
694
        //      The synchronization here is very tricky.  We really
 
695
        //      don't want any other threads to run while we are 
 
696
        //      cleaning up the gc heap... they could call malloc,
 
697
        //      and then we would be in trouble in a big way.  So,
 
698
        //      we jack up our priority and that of the finalizer
 
699
        //      so that we won't yield to other threads.
 
700
        //      dkc 5/17/96
 
701
 
 
702
        oldPriority = PR_GetThreadPriority(PR_GetCurrentThread());
 
703
        _PR_INTSOFF(is);
 
704
        _PR_SetThreadPriority(PR_GetCurrentThread(), (PRThreadPriority)30);
 
705
        _PR_INTSON(is);
 
706
 
 
707
        //      Garbage collect twice.  This will finalize any
 
708
        //      dangling AWT resources (images, components), and
 
709
        //      then free up their GC space, too.
 
710
        //      dkc 2/15/96
 
711
        //  interrupts must be on during PR_GC
 
712
        
 
713
        PR_GC();
 
714
        
 
715
        //      By setting the finalizer priority to 31, then we 
 
716
        //      ensure it will run before us.  When it finishes
 
717
        //      its list of finalizations, it returns to us
 
718
        //      for the second garbage collection.
 
719
        
 
720
        PR_Yield();
 
721
 
 
722
        PR_GC();
 
723
        
 
724
        //      Restore our old priorities.
 
725
        
 
726
        _PR_INTSOFF(is);
 
727
        _PR_SetThreadPriority(PR_GetCurrentThread(), (PRThreadPriority)oldPriority);
 
728
        _PR_INTSON(is);
 
729
 
 
730
        return false;
 
731
}
 
732
 
 
733
#endif
 
734
 
 
735
//##############################################################################
 
736
//##############################################################################
 
737
#pragma mark -
 
738
#pragma mark MISCELLANEOUS-HACKS
 
739
 
 
740
 
 
741
//
 
742
//              ***** HACK  FIX THESE ****
 
743
//
 
744
extern long _MD_GetOSName(char *buf, long count)
 
745
{
 
746
        long    len;
 
747
        
 
748
        len = PR_snprintf(buf, count, "Mac OS");
 
749
        
 
750
        return 0;
 
751
}
 
752
 
 
753
extern long _MD_GetOSVersion(char *buf, long count)
 
754
{
 
755
        long    len;
 
756
        
 
757
        len = PR_snprintf(buf, count, "7.5");
 
758
 
 
759
        return 0;
 
760
}
 
761
 
 
762
extern long _MD_GetArchitecture(char *buf, long count)
 
763
{
 
764
        long    len;
 
765
        
 
766
#if defined(TARGET_CPU_PPC) && TARGET_CPU_PPC   
 
767
        len = PR_snprintf(buf, count, "PowerPC");
 
768
#else
 
769
        len = PR_snprintf(buf, count, "Motorola68k");
 
770
#endif
 
771
 
 
772
        return 0;
 
773
}