Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
OOJSEngineNativeWrappers.h
Go to the documentation of this file.
1/*
2
3OOJSEngineNativeWrappers.h
4(Included by OOJavaScriptEngine.h)
5
6Exception safety and profiling macros.
7
8Every JavaScript native callback that could concievably cause an
9Objective-C exception should begin with OOJS_NATIVE_ENTER() and end with
10OOJS_NATIVE_EXIT. Callbacks which have been carefully audited for potential
11exceptions, and support functions called from JavaScript native callbacks,
12may start with OOJS_PROFILE_ENTER and end with OOJS_PROFILE_EXIT to be
13included in profiling reports.
14
15Functions using either of these pairs _must_ return before
16OOJS_NATIVE_EXIT/OOJS_PROFILE_EXIT, or they will crash.
17
18For functions with a non-scalar return type, OOJS_PROFILE_EXIT should be
19replaced with OOJS_PROFILE_EXIT_VAL(returnValue). The returnValue is never
20used (and should be a constant expression), but is required to placate the
21compiler.
22
23For values with void return, use OOJS_PROFILE_EXIT_VOID. It is not
24necessary to insert a return statement before OOJS_PROFILE_EXIT_VOID.
25
26
27JavaScript support for Oolite
28Copyright (C) 2007-2013 David Taylor and Jens Ayton.
29
30This program is free software; you can redistribute it and/or
31modify it under the terms of the GNU General Public License
32as published by the Free Software Foundation; either version 2
33of the License, or (at your option) any later version.
34
35This program is distributed in the hope that it will be useful,
36but WITHOUT ANY WARRANTY; without even the implied warranty of
37MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38GNU General Public License for more details.
39
40You should have received a copy of the GNU General Public License
41along with this program; if not, write to the Free Software
42Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
43MA 02110-1301, USA.
44
45*/
46
47#import "OOCocoa.h"
48
49
50#define OOJS_PROFILE OOLITE_DEBUG
51
52#if OOJS_PROFILE
53
54
55#define OOJS_PROFILE_ENTER_NAMED(NAME) \
56 { \
57 OOJS_DECLARE_PROFILE_STACK_FRAME(oojsProfilerStackFrame) \
58 @try { \
59 OOJSProfileEnter(&oojsProfilerStackFrame, NAME);
60
61#define OOJS_PROFILE_ENTER \
62 OOJS_PROFILE_ENTER_NAMED(__FUNCTION__)
63
64#define OOJS_PROFILE_EXIT_VAL(rval) \
65 } @finally { \
66 OOJSProfileExit(&oojsProfilerStackFrame); \
67 } \
68 OOJSUnreachable(__FUNCTION__, __FILE__, __LINE__); \
69 return rval; \
70 }
71#define OOJS_PROFILE_EXIT_VOID return; OOJS_PROFILE_EXIT_VAL()
72
73#define OOJS_PROFILE_ENTER_FOR_NATIVE OOJS_PROFILE_ENTER
74
75#else
76
77#define OOJS_PROFILE_ENTER {
78#define OOJS_PROFILE_EXIT_VAL(rval) } OOJSUnreachable(__FUNCTION__, __FILE__, __LINE__); return (rval);
79#define OOJS_PROFILE_EXIT_VOID } return;
80#define OOJS_PROFILE_ENTER_FOR_NATIVE @try {
81
82#endif // OOJS_PROFILE
83
84#define OOJS_NATIVE_ENTER(cx) \
85 { \
86 JSContext *oojsNativeContext = (cx); \
87 OOJS_PROFILE_ENTER_FOR_NATIVE
88
89#define OOJS_NATIVE_EXIT \
90 } @catch(id exception) { \
91 OOJSReportWrappedException(oojsNativeContext, exception); \
92 return NO; \
93 OOJS_PROFILE_EXIT_VAL(NO) \
94 }
95
96
97void OOJSReportWrappedException(JSContext *context, id exception);
98
99
100#ifndef NDEBUG
101void OOJSUnreachable(const char *function, const char *file, unsigned line) NO_RETURN_FUNC;
102#else
103#define OOJSUnreachable(function, file, line) OO_UNREACHABLE()
104#endif
105
106
107#define OOJS_PROFILE_EXIT OOJS_PROFILE_EXIT_VAL(0)
108#define OOJS_PROFILE_EXIT_JSVAL OOJS_PROFILE_EXIT_VAL(JSVAL_VOID)
109
110
111/*
112 OOJS_BEGIN_FULL_NATIVE() and OOJS_END_FULL_NATIVE
113 These macros are used to bracket sections of native Oolite code within JS
114 callbacks which may take a long time. Thet do two things: pause the
115 time limiter, and (in JS_THREADSAFE builds) suspend the current JS context
116 request.
117
118 These macros must be used in balanced pairs. They introduce a scope.
119
120 JSAPI functions may not be used, directly or indirectily, between these
121 macros unless explicitly opening a request first.
122*/
123#if JS_THREADSAFE
124#define OOJS_BEGIN_FULL_NATIVE(context) \
125 { \
126 OOJSPauseTimeLimiter(); \
127 JSContext *oojsRequestContext = (context); \
128 jsrefcount oojsRequestRefCount = JS_SuspendRequest(oojsRequestContext); \
129 @try \
130 {
131
132#define OOJS_END_FULL_NATIVE \
133 } \
134 @finally \
135 { \
136 JS_ResumeRequest(oojsRequestContext, oojsRequestRefCount); \
137 OOJSResumeTimeLimiter(); \
138 } \
139 }
140#else
141#define OOJS_BEGIN_FULL_NATIVE(context) \
142 { \
143 (void)(context); \
144 OOJSPauseTimeLimiter(); \
145 @try \
146 {
147
148#define OOJS_END_FULL_NATIVE \
149 } \
150 @finally \
151 { \
152 OOJSResumeTimeLimiter(); \
153 } \
154 }
155#endif
156
157
158
159#if OOJS_PROFILE
160
162
163/*
164 Profiler implementation details. This should be internal to
165 OOJSTimeManagement.m, but needs to be declared on the stack by the macros
166 above when profiling is enabled.
167*/
168
169typedef struct OOJSProfileStackFrame OOJSProfileStackFrame;
170struct OOJSProfileStackFrame
171{
172 OOJSProfileStackFrame *back; // Stack link
173 const void *key; // Key to look up profile entries. May be any pointer; currently const char * for native frames and JSFunction * for JS frames.
174 const char *function; // Name of function, for native frames.
175 OOHighResTimeValue startTime; // Time frame was entered.
176 OOTimeDelta subTime; // Time spent in subroutine calls.
177 OOTimeDelta *total; // Pointer to accumulator for this type of frame.
178 void (*cleanup)(OOJSProfileStackFrame *); // Cleanup function if needed (used for JS frames).
179};
180
181
182
183#define OOJS_DECLARE_PROFILE_STACK_FRAME(name) OOJSProfileStackFrame name;
184void OOJSProfileEnter(OOJSProfileStackFrame *frame, const char *function);
185void OOJSProfileExit(OOJSProfileStackFrame *frame);
186
187#else
188
189#define OOJS_DECLARE_PROFILE_STACK_FRAME(name)
190#define OOJSProfileEnter(frame, function) do {} while (0)
191#define OOJSProfileExit(frame) do {} while (0)
192
193#endif
#define NO_RETURN_FUNC
void OOJSReportWrappedException(JSContext *context, id exception)
#define OOJSProfileExit(frame)
#define OOJSProfileEnter(frame, function)
void OOJSUnreachable(const char *function, const char *file, unsigned line) NO_RETURN_FUNC
uint64_t OOHighResTimeValue
double OOTimeDelta
Definition OOTypes.h:224