Skip to content

Commit 89a10bd

Browse files
committed
feat(v8-lockers): multithreaded javascript (part I)
1 parent 44bd694 commit 89a10bd

22 files changed

+127
-76
lines changed

test-app/runtime/src/main/cpp/ArgConverter.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ using namespace v8;
1313
using namespace std;
1414
using namespace tns;
1515

16-
void ArgConverter::Init(Isolate* isolate) {
16+
void ArgConverter::Init(Local<Context> context) {
17+
Isolate* isolate = context->GetIsolate();
1718
auto cache = GetTypeLongCache(isolate);
18-
auto context = isolate->GetCurrentContext();
1919

2020
auto ft = FunctionTemplate::New(isolate, ArgConverter::NativeScriptLongFunctionCallback);
2121
ft->SetClassName(V8StringConstants::GetLongNumber(isolate));
@@ -93,10 +93,11 @@ jstring ArgConverter::ObjectToString(jobject object) {
9393
return (jstring) object;
9494
}
9595

96-
Local<Array> ArgConverter::ConvertJavaArgsToJsArgs(Isolate* isolate, jobjectArray args) {
96+
Local<Array> ArgConverter::ConvertJavaArgsToJsArgs(Local<Context> context, jobjectArray args) {
9797
JEnv env;
9898

9999
int argc = env.GetArrayLength(args) / 3;
100+
auto isolate = context->GetIsolate();
100101
Local<Array> arr(Array::New(isolate, argc));
101102

102103
auto runtime = Runtime::GetRuntime(isolate);
@@ -155,7 +156,6 @@ Local<Array> ArgConverter::ConvertJavaArgsToJsArgs(Isolate* isolate, jobjectArra
155156
break;
156157
}
157158

158-
auto context = isolate->GetCurrentContext();
159159
arr->Set(context, i, jsArg);
160160
}
161161

test-app/runtime/src/main/cpp/ArgConverter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ namespace tns {
1717

1818
class ArgConverter {
1919
public:
20-
static void Init(v8::Isolate* isolate);
20+
static void Init(v8::Local<v8::Context> context);
2121

22-
static v8::Local<v8::Array> ConvertJavaArgsToJsArgs(v8::Isolate* isolate, jobjectArray args);
22+
static v8::Local<v8::Array> ConvertJavaArgsToJsArgs(v8::Local<v8::Context> context, jobjectArray args);
2323

2424
static v8::Local<v8::Value> ConvertFromJavaLong(v8::Isolate* isolate, jlong value);
2525

test-app/runtime/src/main/cpp/ArrayBufferHelper.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@ ArrayBufferHelper::ArrayBufferHelper()
1212
m_remainingMethodID(nullptr), m_getMethodID(nullptr) {
1313
}
1414

15-
void ArrayBufferHelper::CreateConvertFunctions(Isolate* isolate, const Local<Object>& global, ObjectManager* objectManager) {
15+
void ArrayBufferHelper::CreateConvertFunctions(Local<Context> context, const Local<Object>& global, ObjectManager* objectManager) {
1616
m_objectManager = objectManager;
17+
Isolate* isolate = context->GetIsolate();
1718
auto extData = External::New(isolate, this);
18-
auto context = isolate->GetCurrentContext();
1919
auto fromFunc = FunctionTemplate::New(isolate, CreateFromCallbackStatic, extData)->GetFunction(context).ToLocalChecked();
20-
auto ctx = isolate->GetCurrentContext();
2120
auto arrBufferCtorFunc = global->Get(context, ArgConverter::ConvertToV8String(isolate, "ArrayBuffer")).ToLocalChecked().As<Function>();
22-
arrBufferCtorFunc->Set(ctx, ArgConverter::ConvertToV8String(isolate, "from"), fromFunc);
21+
arrBufferCtorFunc->Set(context, ArgConverter::ConvertToV8String(isolate, "from"), fromFunc);
2322
}
2423

2524
void ArrayBufferHelper::CreateFromCallbackStatic(const FunctionCallbackInfo<Value>& info) {

test-app/runtime/src/main/cpp/ArrayBufferHelper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace tns {
99
public:
1010
ArrayBufferHelper();
1111

12-
void CreateConvertFunctions(v8::Isolate* isolate, const v8::Local<v8::Object>& global, ObjectManager* objectManager);
12+
void CreateConvertFunctions(v8::Local<v8::Context> context, const v8::Local<v8::Object>& global, ObjectManager* objectManager);
1313

1414
private:
1515

test-app/runtime/src/main/cpp/ArrayElementAccessor.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ using namespace v8;
99
using namespace std;
1010
using namespace tns;
1111

12-
Local<Value> ArrayElementAccessor::GetArrayElement(Isolate* isolate, const Local<Object>& array, uint32_t index, const string& arraySignature) {
12+
Local<Value> ArrayElementAccessor::GetArrayElement(Local<Context> context, const Local<Object>& array, uint32_t index, const string& arraySignature) {
1313
JEnv env;
1414

15+
Isolate* isolate = context->GetIsolate();
1516
EscapableHandleScope handleScope(isolate);
1617
auto runtime = Runtime::GetRuntime(isolate);
1718
auto objectManager = runtime->GetObjectManager();
@@ -79,13 +80,13 @@ Local<Value> ArrayElementAccessor::GetArrayElement(Isolate* isolate, const Local
7980
return handleScope.Escape(value);
8081
}
8182

82-
void ArrayElementAccessor::SetArrayElement(Isolate* isolate, const Local<Object>& array, uint32_t index, const string& arraySignature, Local<Value>& value) {
83+
void ArrayElementAccessor::SetArrayElement(Local<Context> context, const Local<Object>& array, uint32_t index, const string& arraySignature, Local<Value>& value) {
8384
JEnv env;
8485

86+
Isolate* isolate = context->GetIsolate();
8587
HandleScope handleScope(isolate);
8688
auto runtime = Runtime::GetRuntime(isolate);
8789
auto objectManager = runtime->GetObjectManager();
88-
auto context = isolate->GetCurrentContext();
8990

9091
tns::JniLocalRef arr = objectManager->GetJavaObjectByJsObject(array);
9192

@@ -140,7 +141,7 @@ void ArrayElementAccessor::SetArrayElement(Isolate* isolate, const Local<Object>
140141
if (isReferenceType) {
141142
auto object = value.As<Object>();
142143

143-
JsArgToArrayConverter argConverter(isolate, value, false, (int) Type::Null);
144+
JsArgToArrayConverter argConverter(context, value, false, (int) Type::Null);
144145
if (argConverter.IsValid()) {
145146
jobjectArray objArr = static_cast<jobjectArray>(arr);
146147
jobject objectElementValue = argConverter.GetConvertedArg();

test-app/runtime/src/main/cpp/ArrayElementAccessor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
namespace tns {
1010
class ArrayElementAccessor {
1111
public:
12-
v8::Local<v8::Value> GetArrayElement(v8::Isolate* isolate, const v8::Local<v8::Object>& array, uint32_t index, const std::string& arraySignature);
12+
v8::Local<v8::Value> GetArrayElement(v8::Local<v8::Context> context, const v8::Local<v8::Object>& array, uint32_t index, const std::string& arraySignature);
1313

14-
void SetArrayElement(v8::Isolate* isolate, const v8::Local<v8::Object>& array, uint32_t index, const std::string& arraySignature, v8::Local<v8::Value>& value);
14+
void SetArrayElement(v8::Local<v8::Context> context, const v8::Local<v8::Object>& array, uint32_t index, const std::string& arraySignature, v8::Local<v8::Value>& value);
1515

1616
private:
1717
v8::Local<v8::Value> ConvertToJsValue(v8::Isolate* isolate, ObjectManager* objectManager, JEnv& env, const std::string& elementSignature, const void* value);

test-app/runtime/src/main/cpp/CallbackHandlers.cpp

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -171,15 +171,15 @@ string CallbackHandlers::ResolveClassName(Isolate* isolate, jclass& clazz) {
171171
return className;
172172
}
173173

174-
Local<Value> CallbackHandlers::GetArrayElement(Isolate* isolate, const Local<Object>& array,
174+
Local<Value> CallbackHandlers::GetArrayElement(Local<Context> context, const Local<Object>& array,
175175
uint32_t index, const string& arraySignature) {
176-
return arrayElementAccessor.GetArrayElement(isolate, array, index, arraySignature);
176+
return arrayElementAccessor.GetArrayElement(context, array, index, arraySignature);
177177
}
178178

179-
void CallbackHandlers::SetArrayElement(Isolate* isolate, const Local<Object>& array, uint32_t index,
179+
void CallbackHandlers::SetArrayElement(Local<Context> context, const Local<Object>& array, uint32_t index,
180180
const string& arraySignature, Local<Value>& value) {
181181

182-
arrayElementAccessor.SetArrayElement(isolate, array, index, arraySignature, value);
182+
arrayElementAccessor.SetArrayElement(context, array, index, arraySignature, value);
183183
}
184184

185185
Local<Value> CallbackHandlers::GetJavaField(Isolate* isolate, const Local<Object>& caller,
@@ -568,7 +568,7 @@ CallbackHandlers::GetImplementedInterfaces(JEnv& env, const Local<Object>& imple
568568

569569
vector<jstring> interfacesToImplement;
570570
auto isolate = implementationObject->GetIsolate();
571-
auto context = isolate->GetCurrentContext();
571+
auto context = implementationObject->CreationContext();
572572
auto propNames = implementationObject->GetOwnPropertyNames(context).ToLocalChecked();
573573
for (int i = 0; i < propNames->Length(); i++) {
574574
auto name = propNames->Get(context, i).ToLocalChecked().As<String>();
@@ -582,7 +582,6 @@ CallbackHandlers::GetImplementedInterfaces(JEnv& env, const Local<Object>& imple
582582
if (arrNameC == "interfaces") {
583583
auto interfacesArr = prop->ToObject(context).ToLocalChecked();
584584

585-
auto context = isolate->GetCurrentContext();
586585
int length = interfacesArr->Get(
587586
context,
588587
v8::String::NewFromUtf8(isolate, "length").ToLocalChecked()).ToLocalChecked()->ToObject(context).ToLocalChecked()->Uint32Value(
@@ -628,7 +627,7 @@ CallbackHandlers::GetMethodOverrides(JEnv& env, const Local<Object>& implementat
628627

629628
vector<jstring> methodNames;
630629
auto isolate = implementationObject->GetIsolate();
631-
auto context = isolate->GetCurrentContext();
630+
auto context = implementationObject->CreationContext();
632631
auto propNames = implementationObject->GetOwnPropertyNames(context).ToLocalChecked();
633632
for (int i = 0; i < propNames->Length(); i++) {
634633
auto name = propNames->Get(context, i).ToLocalChecked().As<String>();
@@ -833,7 +832,7 @@ Local<Value> CallbackHandlers::CallJSMethod(Isolate* isolate, JNIEnv* _env,
833832
JEnv env(_env);
834833
Local<Value> result;
835834

836-
auto context = isolate->GetCurrentContext();
835+
auto context = Runtime::GetRuntime(isolate)->GetContext();
837836
auto method = jsObject->Get(context, ArgConverter::ConvertToV8String(isolate, methodName)).ToLocalChecked();
838837

839838
if (method.IsEmpty() || method->IsUndefined()) {
@@ -848,16 +847,14 @@ Local<Value> CallbackHandlers::CallJSMethod(Isolate* isolate, JNIEnv* _env,
848847
EscapableHandleScope handleScope(isolate);
849848

850849
auto jsMethod = method.As<Function>();
851-
auto jsArgs = ArgConverter::ConvertJavaArgsToJsArgs(isolate, args);
850+
auto jsArgs = ArgConverter::ConvertJavaArgsToJsArgs(context, args);
852851
int argc = jsArgs->Length();
853852

854853
std::vector<Local<Value>> arguments(argc);
855854
for (int i = 0; i < argc; i++) {
856855
arguments[i] = jsArgs->Get(context, i).ToLocalChecked();
857856
}
858857

859-
auto context = isolate->GetCurrentContext();
860-
861858
TryCatch tc(isolate);
862859
Local<Value> jsResult;
863860
{
@@ -1160,12 +1157,11 @@ CallbackHandlers::WorkerObjectOnMessageCallback(Isolate* isolate, jint workerId,
11601157

11611158
if (!isEmpty && isFunction) {
11621159
auto msgString = ArgConverter::jstringToV8String(isolate, message).As<String>();
1163-
auto context = isolate->GetCurrentContext();
11641160
Local<Value> msg;
11651161
JSON::Parse(context, msgString).ToLocal(&msg);
11661162

11671163
auto obj = Object::New(isolate);
1168-
obj->DefineOwnProperty(isolate->GetCurrentContext(),
1164+
obj->DefineOwnProperty(context,
11691165
ArgConverter::ConvertToV8String(isolate, "data"), msg,
11701166
PropertyAttribute::ReadOnly);
11711167
Local<Value> args1[] = {obj};
@@ -1430,8 +1426,6 @@ CallbackHandlers::CallWorkerObjectOnErrorHandle(Isolate* isolate, jint workerId,
14301426

14311427
auto func = callback.As<Function>();
14321428

1433-
auto context = isolate->GetCurrentContext();
1434-
14351429
// Handle exceptions thrown in onmessage with the worker.onerror handler, if present
14361430
Local<Value> result;
14371431
func->Call(context, Undefined(isolate), 1, args1).ToLocal(&result);
@@ -1490,9 +1484,6 @@ void CallbackHandlers::ClearWorkerPersistent(int workerId) {
14901484
}
14911485

14921486
void CallbackHandlers::TerminateWorkerThread(Isolate* isolate) {
1493-
auto context = isolate->GetCurrentContext();
1494-
context->Exit();
1495-
14961487
isolate->TerminateExecution();
14971488
}
14981489

test-app/runtime/src/main/cpp/CallbackHandlers.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ namespace tns {
4747
static std::string ResolveClassName(v8::Isolate *isolate, jclass &clazz);
4848

4949
static v8::Local<v8::Value>
50-
GetArrayElement(v8::Isolate *isolate, const v8::Local<v8::Object> &array, uint32_t index,
50+
GetArrayElement(v8::Local<v8::Context> context, const v8::Local<v8::Object> &array, uint32_t index,
5151
const std::string &arraySignature);
5252

5353
static void
54-
SetArrayElement(v8::Isolate *isolate, const v8::Local<v8::Object> &array, uint32_t index,
54+
SetArrayElement(v8::Local<v8::Context> context, const v8::Local<v8::Object> &array, uint32_t index,
5555
const std::string &arraySignature, v8::Local<v8::Value> &value);
5656

5757
static int GetArrayLength(v8::Isolate *isolate, const v8::Local<v8::Object> &arr);

test-app/runtime/src/main/cpp/JsArgConverter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ bool JsArgConverter::ConvertJavaScriptArray(const Local<Array>& jsArr, int index
433433
arr = m_env.NewObjectArray(arrLength, elementClass, nullptr);
434434
for (int i = 0; i < arrLength; i++) {
435435
auto v = jsArr->Get(context, i).ToLocalChecked();
436-
JsArgToArrayConverter c(m_isolate, v, false, (int) Type::Null);
436+
JsArgToArrayConverter c(context, v, false, (int) Type::Null);
437437
jobject o = c.GetConvertedArg();
438438
m_env.SetObjectArrayElement((jobjectArray) arr, i, o);
439439
}

test-app/runtime/src/main/cpp/JsArgToArrayConverter.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,22 @@ using namespace tns;
1616
/*
1717
* Converts a single JavaScript (V8) object to its respective Java representation
1818
*/
19-
JsArgToArrayConverter::JsArgToArrayConverter(Isolate* isolate, const v8::Local<Value>& arg, bool isImplementationObject, int classReturnType)
20-
: m_isolate(isolate), m_arr(nullptr), m_argsAsObject(nullptr), m_argsLen(0), m_isValid(false), m_error(Error()), m_return_type(classReturnType) {
19+
JsArgToArrayConverter::JsArgToArrayConverter(Local<Context> context, const v8::Local<Value>& arg, bool isImplementationObject, int classReturnType)
20+
: m_arr(nullptr), m_argsAsObject(nullptr), m_argsLen(0), m_isValid(false), m_error(Error()), m_return_type(classReturnType) {
2121
if (!isImplementationObject) {
2222
m_argsLen = 1;
2323
m_argsAsObject = new jobject[m_argsLen];
2424
memset(m_argsAsObject, 0, m_argsLen * sizeof(jobject));
2525

26-
m_isValid = ConvertArg(arg, 0);
26+
m_isValid = ConvertArg(context, arg, 0);
2727
}
2828
}
2929

3030
/*
3131
* Converts an array of JavaScript (V8) objects to a Java array of objects
3232
*/
3333
JsArgToArrayConverter::JsArgToArrayConverter(const v8::FunctionCallbackInfo<Value>& args, bool hasImplementationObject)
34-
: m_isolate(args.GetIsolate()), m_arr(nullptr), m_argsAsObject(nullptr), m_argsLen(0), m_isValid(false), m_error(Error()), m_return_type(static_cast<int>(Type::Null)) {
34+
: m_arr(nullptr), m_argsAsObject(nullptr), m_argsLen(0), m_isValid(false), m_error(Error()), m_return_type(static_cast<int>(Type::Null)) {
3535
m_argsLen = !hasImplementationObject ? args.Length() : args.Length() - 2;
3636

3737
bool success = true;
@@ -40,8 +40,9 @@ JsArgToArrayConverter::JsArgToArrayConverter(const v8::FunctionCallbackInfo<Valu
4040
m_argsAsObject = new jobject[m_argsLen];
4141
memset(m_argsAsObject, 0, m_argsLen * sizeof(jobject));
4242

43+
auto context = args.GetIsolate()->GetCurrentContext();
4344
for (int i = 0; i < m_argsLen; i++) {
44-
success = ConvertArg(args[i], i);
45+
success = ConvertArg(context, args[i], i);
4546

4647
if (!success) {
4748
break;
@@ -52,14 +53,14 @@ JsArgToArrayConverter::JsArgToArrayConverter(const v8::FunctionCallbackInfo<Valu
5253
m_isValid = success;
5354
}
5455

55-
bool JsArgToArrayConverter::ConvertArg(const Local<Value>& arg, int index) {
56+
bool JsArgToArrayConverter::ConvertArg(Local<Context> context, const Local<Value>& arg, int index) {
5657
bool success = false;
5758
stringstream s;
5859

5960
JEnv env;
6061

6162
Type returnType = JType::getClassType(m_return_type);
62-
auto context = m_isolate->GetCurrentContext();
63+
auto isolate = context->GetIsolate();
6364

6465
if (arg.IsEmpty()) {
6566
s << "Cannot convert empty JavaScript object";
@@ -110,13 +111,13 @@ bool JsArgToArrayConverter::ConvertArg(const Local<Value>& arg, int index) {
110111
success = true;
111112
}
112113
} else if (arg->IsBoolean()) {
113-
jboolean value = arg->BooleanValue(m_isolate);
114+
jboolean value = arg->BooleanValue(isolate);
114115
auto javaObject = JType::NewBoolean(env, value);
115116
SetConvertedObject(env, index, javaObject);
116117
success = true;
117118
} else if (arg->IsBooleanObject()) {
118119
auto boolObj = Local<BooleanObject>::Cast(arg);
119-
jboolean value = boolObj->BooleanValue(m_isolate) ? JNI_TRUE : JNI_FALSE;
120+
jboolean value = boolObj->BooleanValue(isolate) ? JNI_TRUE : JNI_FALSE;
120121
auto javaObject = JType::NewBoolean(env, value);
121122
SetConvertedObject(env, index, javaObject);
122123

@@ -129,7 +130,7 @@ bool JsArgToArrayConverter::ConvertArg(const Local<Value>& arg, int index) {
129130
} else if (arg->IsObject()) {
130131
auto jsObj = arg->ToObject(context).ToLocalChecked();
131132

132-
auto castType = NumericCasts::GetCastType(m_isolate, jsObj);
133+
auto castType = NumericCasts::GetCastType(isolate, jsObj);
133134

134135
Local<Value> castValue;
135136
jchar charValue;
@@ -141,7 +142,7 @@ bool JsArgToArrayConverter::ConvertArg(const Local<Value>& arg, int index) {
141142
jobject javaObject;
142143
JniLocalRef obj;
143144

144-
auto runtime = Runtime::GetRuntime(m_isolate);
145+
auto runtime = Runtime::GetRuntime(isolate);
145146
auto objectManager = runtime->GetObjectManager();
146147

147148
switch (castType) {
@@ -230,7 +231,7 @@ bool JsArgToArrayConverter::ConvertArg(const Local<Value>& arg, int index) {
230231
case CastType::None:
231232
obj = objectManager->GetJavaObjectByJsObject(jsObj);
232233

233-
V8GetPrivateValue(m_isolate, jsObj, V8StringConstants::GetNullNodeName(m_isolate), castValue);
234+
V8GetPrivateValue(isolate, jsObj, V8StringConstants::GetNullNodeName(isolate), castValue);
234235

235236
if (!castValue.IsEmpty()) {
236237
auto node = reinterpret_cast<MetadataNode*>(castValue.As<External>()->Value());
@@ -264,7 +265,7 @@ bool JsArgToArrayConverter::ConvertArg(const Local<Value>& arg, int index) {
264265
if (success) {
265266
SetConvertedObject(env, index, obj.Move(), obj.IsGlobal());
266267
} else {
267-
String::Utf8Value jsObjStr(m_isolate, jsObj);
268+
String::Utf8Value jsObjStr(isolate, jsObj);
268269
s << "Cannot marshal JavaScript argument " << (*jsObjStr ? *jsObjStr : "<failed-to-string>") << " at index " << index << " to Java type.";
269270
}
270271
break;

0 commit comments

Comments
 (0)