Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

error handling introducing c++ exceptions #277

Merged
merged 3 commits into from
Nov 26, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/jni/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,19 @@ include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_CPPFLAGS += -std=c++11
LOCAL_MODULE := NativeScript
LOCAL_SRC_FILES := com_tns_AssetExtractor.cpp com_tns_Platform.cpp com_tns_JsDebugger.cpp com_tns_NativeScriptActity.cpp \
JEnv.cpp DirectBuffer.cpp \
LOCAL_SRC_FILES := com_tns_AssetExtractor.cpp AssetExtractor.cpp\
com_tns_Platform.cpp NativePlatform.cpp \
com_tns_JsDebugger.cpp com_tns_NativeScriptActity.cpp \
JEnv.cpp DirectBuffer.cpp NativeScriptException.cpp \
JsDebugger.cpp SimpleAllocator.cpp \
NativeScriptRuntime.cpp MetadataNode.cpp MetadataTreeNode.cpp MetadataReader.cpp \
MethodCache.cpp JavaObjectArrayCache.cpp \
JniLocalRef.cpp JniSignatureParser.cpp \
ArgConverter.cpp JsArgToArrayConverter.cpp JsArgConverter.cpp V8GlobalHelpers.cpp V8StringConstants.cpp \
FieldAccessor.cpp ArrayElementAccessor.cpp \
ExceptionUtil.cpp Util.cpp Logger.cpp Profiler.cpp \
Util.cpp Logger.cpp Profiler.cpp \
ObjectManager.cpp NumericCasts.cpp WeakRef.cpp \
MetadataMethodInfo.cpp SimpleProfiler.cpp JType.cpp File.cpp Module.cpp Constants.cpp
MetadataMethodInfo.cpp SimpleProfiler.cpp JType.cpp File.cpp Module.cpp Constants.cpp

LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_LDLIBS := -llog -landroid -lz
Expand Down
5 changes: 4 additions & 1 deletion src/jni/Application.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ APP_OPTIM := debug

#The new ndks require this or build fails
APP_CFLAGS += -Wno-error=format-security
APP_CFLAGS += -g
APP_CFLAGS += -g

#Turn on C++ exceptions
APP_CPPFLAGS += -fexceptions
31 changes: 31 additions & 0 deletions src/jni/ArgConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "V8GlobalHelpers.h"
#include "V8StringConstants.h"
#include "NativeScriptAssert.h"
#include "NativeScriptException.h"
#include "JType.h"
#include <assert.h>
#include <sstream>
Expand Down Expand Up @@ -32,23 +33,53 @@ void ArgConverter::Init(JavaVM *jvm)

void ArgConverter::NativeScriptLongValueOfFunctionCallback(const v8::FunctionCallbackInfo<Value>& args)
{
try {
auto isolate = Isolate::GetCurrent();
args.GetReturnValue().Set(Number::New(isolate, numeric_limits<double>::quiet_NaN()));
} catch (NativeScriptException& e) {
e.ReThrowToV8();
}
catch (exception e) {
DEBUG_WRITE("Error: c++ exception: %s", e.what());
}
catch (...) {
DEBUG_WRITE("Error: c++ exception!");
}
}

void ArgConverter::NativeScriptLongToStringFunctionCallback(const v8::FunctionCallbackInfo<Value>& args)
{
try {
args.GetReturnValue().Set(args.This()->Get(V8StringConstants::GetValue()));
} catch (NativeScriptException& e) {
e.ReThrowToV8();
}
catch (exception e) {
DEBUG_WRITE("Error: c++ exception: %s", e.what());
}
catch (...) {
DEBUG_WRITE("Error: c++ exception!");
}
}

void ArgConverter::NativeScriptLongFunctionCallback(const v8::FunctionCallbackInfo<Value>& args)
{
try {
auto isolate = Isolate::GetCurrent();
args.This()->SetHiddenValue(V8StringConstants::GetJavaLong(), Boolean::New(isolate, true));
args.This()->SetHiddenValue(V8StringConstants::GetMarkedAsLong(), args[0]);
args.This()->Set(V8StringConstants::GetValue(), args[0]);

args.This()->SetPrototype(Local<NumberObject>::New(Isolate::GetCurrent(), *NAN_NUMBER_OBJECT));
} catch (NativeScriptException& e) {
e.ReThrowToV8();
}
catch (exception e) {
DEBUG_WRITE("Error: c++ exception: %s", e.what());
}
catch (...) {
DEBUG_WRITE("Error: c++ exception!");
}
}


Expand Down
57 changes: 23 additions & 34 deletions src/jni/ArrayElementAccessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Util.h"
#include "V8GlobalHelpers.h"
#include "NativeScriptAssert.h"
#include "NativeScriptException.h"
#include "JType.h"
#include <assert.h>

Expand Down Expand Up @@ -39,14 +40,14 @@ Local<Value> ArrayElementAccessor::GetArrayElement(const Local<Object>& array, u
jbooleanArray boolArr = reinterpret_cast<jbooleanArray>(arr);
jboolean boolArrValue;
env.GetBooleanArrayRegion(boolArr, startIndex, length, &boolArrValue);
value = CheckForArrayAccessException(env, elementSignature, &boolArrValue);
value = ConvertToJsValue(env, elementSignature, &boolArrValue);
}
else if (elementSignature == "B")
{
jbyteArray byteArr = reinterpret_cast<jbyteArray>(arr);
jbyte byteArrValue;
env.GetByteArrayRegion(byteArr, startIndex, length, &byteArrValue);
value = CheckForArrayAccessException(env, elementSignature, &byteArrValue);
value = ConvertToJsValue(env, elementSignature, &byteArrValue);
}
else if (elementSignature == "C")
{
Expand All @@ -55,48 +56,48 @@ Local<Value> ArrayElementAccessor::GetArrayElement(const Local<Object>& array, u
env.GetCharArrayRegion(charArr, startIndex, length, &charArrValue);
JniLocalRef s(env.NewString(&charArrValue, 1));
const char* singleChar = env.GetStringUTFChars(s, &isCopy);
value = CheckForArrayAccessException(env, elementSignature, singleChar);
value = ConvertToJsValue(env, elementSignature, singleChar);
env.ReleaseStringUTFChars(s, singleChar);
}
else if (elementSignature == "S")
{
jshortArray shortArr = reinterpret_cast<jshortArray>(arr);
jshort shortArrValue;
env.GetShortArrayRegion(shortArr, startIndex, length, &shortArrValue);
value = CheckForArrayAccessException(env, elementSignature, &shortArrValue);
value = ConvertToJsValue(env, elementSignature, &shortArrValue);
}
else if (elementSignature == "I")
{
jintArray intArr = reinterpret_cast<jintArray>(arr);
jint intArrValue;
env.GetIntArrayRegion(intArr, startIndex, length, &intArrValue);
value = CheckForArrayAccessException(env, elementSignature, &intArrValue);
value = ConvertToJsValue(env, elementSignature, &intArrValue);
}
else if (elementSignature == "J")
{
jlongArray longArr = reinterpret_cast<jlongArray>(arr);
jlong longArrValue;
env.GetLongArrayRegion(longArr, startIndex, length, &longArrValue);
value = CheckForArrayAccessException(env, elementSignature, &longArrValue);
value = ConvertToJsValue(env, elementSignature, &longArrValue);
}
else if (elementSignature == "F")
{
jfloatArray floatArr = reinterpret_cast<jfloatArray>(arr);
jfloat floatArrValue;
env.GetFloatArrayRegion(floatArr, startIndex, length, &floatArrValue);
value = CheckForArrayAccessException(env, elementSignature, &floatArrValue);
value = ConvertToJsValue(env, elementSignature, &floatArrValue);
}
else if (elementSignature == "D")
{
jdoubleArray doubleArr = reinterpret_cast<jdoubleArray>(arr);
jdouble doubleArrValue;
env.GetDoubleArrayRegion(doubleArr, startIndex, length, &doubleArrValue);
value = CheckForArrayAccessException(env, elementSignature, &doubleArrValue);
value = ConvertToJsValue(env, elementSignature, &doubleArrValue);
}
else
{
jobject result = env.GetObjectArrayElement(reinterpret_cast<jobjectArray>(arr), index);
value = CheckForArrayAccessException(env, elementSignature, &result);
value = ConvertToJsValue(env, elementSignature, &result);
env.DeleteLocalRef(result);
}

Expand All @@ -116,19 +117,19 @@ void ArrayElementAccessor::SetArrayElement(const Local<Object>& array, uint32_t
const string elementSignature = arraySignature.substr(1);
jboolean isCopy = false;

if (elementSignature == "Z")
if (elementSignature == "Z") //bool
{
jboolean boolElementValue = (jboolean) value->BooleanValue();
jbooleanArray boolArr = reinterpret_cast<jbooleanArray>(arr);
env.SetBooleanArrayRegion(boolArr, index, 1, &boolElementValue);
}
else if (elementSignature == "B")
else if (elementSignature == "B") //byte
{
jbyte byteElementValue = (jbyte) value->Int32Value();
jbyteArray byteArr = reinterpret_cast<jbyteArray>(arr);
env.SetByteArrayRegion(byteArr, index, 1, &byteElementValue);
}
else if (elementSignature == "C")
else if (elementSignature == "C") //char
{
String::Utf8Value utf8(value->ToString());
JniLocalRef s(env.NewString((jchar*) *utf8, 1));
Expand All @@ -138,19 +139,19 @@ void ArrayElementAccessor::SetArrayElement(const Local<Object>& array, uint32_t
jcharArray charArr = reinterpret_cast<jcharArray>(arr);
env.SetCharArrayRegion(charArr, index, 1, &charElementValue);
}
else if (elementSignature == "S")
else if (elementSignature == "S") //short
{
jshort shortElementValue = (jshort) value->Int32Value();
jshortArray shortArr = reinterpret_cast<jshortArray>(arr);
env.SetShortArrayRegion(shortArr, index, 1, &shortElementValue);
}
else if (elementSignature == "I")
else if (elementSignature == "I") //int
{
jint intElementValue = value->Int32Value();
jintArray intArr = reinterpret_cast<jintArray>(arr);
env.SetIntArrayRegion(intArr, index, 1, &intElementValue);
}
else if (elementSignature == "J")
else if (elementSignature == "J") //long
{
jlong longElementValue;
if (value->IsObject())
Expand All @@ -164,19 +165,19 @@ void ArrayElementAccessor::SetArrayElement(const Local<Object>& array, uint32_t
jlongArray longArr = reinterpret_cast<jlongArray>(arr);
env.SetLongArrayRegion(longArr, index, 1, &longElementValue);
}
else if (elementSignature == "F")
else if (elementSignature == "F") //float
{
jfloat floatElementValue = (jfloat) value->NumberValue();
jfloatArray floatArr = reinterpret_cast<jfloatArray>(arr);
env.SetFloatArrayRegion(floatArr, index, 1, &floatElementValue);
}
else if (elementSignature == "D")
else if (elementSignature == "D") //double
{
jdouble doubleElementValue = (jdouble) value->NumberValue();
jdoubleArray doubleArr = reinterpret_cast<jdoubleArray>(arr);
env.SetDoubleArrayRegion(doubleArr, index, 1, &doubleElementValue);
}
else
else //string or object
{
bool isReferenceType = value->IsObject() || value->IsString();
if (isReferenceType)
Expand All @@ -193,35 +194,23 @@ void ArrayElementAccessor::SetArrayElement(const Local<Object>& array, uint32_t
else
{
JsArgToArrayConverter::Error err = argConverter.GetError();
ExceptionUtil::GetInstance()->ThrowExceptionToJs(err.msg);
return;
throw NativeScriptException(string(err.msg));
}
}
else
{
ExceptionUtil::GetInstance()->ThrowExceptionToJs("Cannot assign primitive value to array of objects.");
return;
throw NativeScriptException(string("Cannot assign primitive value to array of objects."));
}
}
}

Local<Value> ArrayElementAccessor::CheckForArrayAccessException(JEnv& env, const string& elementSignature, const void *value)
Local<Value> ArrayElementAccessor::ConvertToJsValue(JEnv& env, const string& elementSignature, const void *value)
{
Local<Value> jsValue;

auto isolate = Isolate::GetCurrent();

JniLocalRef exc(env.ExceptionOccurred());
if (nullptr != (jthrowable) exc)
{
DEBUG_WRITE("Error during getting array element");
// env.ExceptionDescribe(); We will print this manually in the ExceptionUtil
env.ExceptionClear();
string errMsg;
ExceptionUtil::GetInstance()->GetExceptionMessage(env, exc, errMsg);
ExceptionUtil::GetInstance()->ThrowExceptionToJs(errMsg);
}
else if (elementSignature == "Z")
if (elementSignature == "Z")
{
jsValue = Boolean::New(isolate, *(jboolean*) value);
}
Expand Down
3 changes: 1 addition & 2 deletions src/jni/ArrayElementAccessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "v8.h"
#include <string>
#include "ObjectManager.h"
#include "ExceptionUtil.h"

namespace tns
{
Expand All @@ -19,7 +18,7 @@ namespace tns
void SetArrayElement(const v8::Local<v8::Object>& array, uint32_t index, const std::string& arraySignature, v8::Local<v8::Value>& value);

private:
v8::Local<v8::Value> CheckForArrayAccessException(JEnv& env, const std::string& elementSignature, const void *value);
v8::Local<v8::Value> ConvertToJsValue(JEnv& env, const std::string& elementSignature, const void *value);

JavaVM *jvm;

Expand Down
Loading