JSCHelpers.h
3.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright 2004-present Facebook. All Rights Reserved.
#pragma once
#include <algorithm>
#include <functional>
#include <stdexcept>
#include <jschelpers/JavaScriptCore.h>
#include <jschelpers/Value.h>
#ifndef RN_EXPORT
#define RN_EXPORT __attribute__((visibility("default")))
#endif
namespace facebook {
namespace react {
class RN_EXPORT JSException : public std::exception {
public:
explicit JSException(const char* msg)
: msg_(msg) {}
explicit JSException(JSContextRef ctx, JSValueRef exn, const char* msg) {
buildMessage(ctx, exn, nullptr, msg);
}
explicit JSException(JSContextRef ctx, JSValueRef exn, JSStringRef sourceURL) {
buildMessage(ctx, exn, sourceURL, nullptr);
}
const std::string& getStack() const {
return stack_;
}
virtual const char* what() const noexcept override {
return msg_.c_str();
}
private:
std::string msg_;
std::string stack_;
void buildMessage(JSContextRef ctx, JSValueRef exn, JSStringRef sourceURL, const char* errorMsg);
};
namespace ExceptionHandling {
struct ExtractedEror {
std::string message;
// Stacktrace formatted like JS stack
// method@filename[:line[:column]]
std::string stack;
};
typedef ExtractedEror(*PlatformErrorExtractor)(const std::exception &ex, const char *context);
extern PlatformErrorExtractor platformErrorExtractor;
}
using JSFunction = std::function<JSValueRef(JSContextRef, JSObjectRef, size_t, const JSValueRef[])>;
JSObjectRef makeFunction(
JSContextRef ctx,
const char* name,
JSFunction function);
RN_EXPORT void installGlobalFunction(
JSGlobalContextRef ctx,
const char* name,
JSFunction function);
JSObjectRef makeFunction(
JSGlobalContextRef ctx,
const char* name,
JSObjectCallAsFunctionCallback callback);
RN_EXPORT void installGlobalFunction(
JSGlobalContextRef ctx,
const char* name,
JSObjectCallAsFunctionCallback callback);
void installGlobalProxy(
JSGlobalContextRef ctx,
const char* name,
JSObjectGetPropertyCallback callback);
void removeGlobal(JSGlobalContextRef ctx, const char* name);
JSValueRef evaluateScript(
JSContextRef ctx,
JSStringRef script,
JSStringRef sourceURL);
#if WITH_FBJSCEXTENSIONS
JSValueRef evaluateSourceCode(
JSContextRef ctx,
JSSourceCodeRef source,
JSStringRef sourceURL);
#endif
/**
* A lock for protecting accesses to the JSGlobalContext
* This will be a no-op for most compilations, where #if WITH_FBJSCEXTENSIONS is false,
* but avoids deadlocks in execution environments with advanced locking requirements,
* particularly with uses of the pthread mutex lock
**/
class JSContextLock {
public:
JSContextLock(JSGlobalContextRef ctx) noexcept;
~JSContextLock() noexcept;
private:
#if WITH_FBJSCEXTENSIONS
JSGlobalContextRef ctx_;
pthread_mutex_t globalLock_;
#endif
};
JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, const char *exceptionLocation);
JSValueRef translatePendingCppExceptionToJSError(JSContextRef ctx, JSObjectRef jsFunctionCause);
template<JSValueRef (method)(JSContextRef ctx,
JSObjectRef function,
JSObjectRef thisObject,
size_t argumentCount,
const JSValueRef arguments[],
JSValueRef *exception)>
inline JSObjectCallAsFunctionCallback exceptionWrapMethod() {
struct funcWrapper {
static JSValueRef call(
JSContextRef ctx,
JSObjectRef function,
JSObjectRef thisObject,
size_t argumentCount,
const JSValueRef arguments[],
JSValueRef *exception) {
try {
return (*method)(ctx, function, thisObject, argumentCount, arguments, exception);
} catch (...) {
*exception = translatePendingCppExceptionToJSError(ctx, function);
return JSC_JSValueMakeUndefined(ctx);
}
}
};
return &funcWrapper::call;
}
} }