55#include " V8GlobalHelpers.h"
66#include " V8StringConstants.h"
77#include " NativeScriptAssert.h"
8+ #include " JType.h"
89#include < assert.h>
910#include < sstream>
1011#include < cstdlib>
@@ -27,58 +28,6 @@ void ArgConverter::Init(JavaVM *jvm)
2728
2829 auto nanObject = Number::New (isolate, numeric_limits<double >::quiet_NaN ()).As <NumberObject>();
2930 NAN_NUMBER_OBJECT = new Persistent<NumberObject>(isolate, nanObject);
30-
31- JEnv env;
32-
33- STRING_CLASS = env.FindClass (" java/lang/String" );
34- assert (STRING_CLASS != nullptr );
35-
36- GET_BYTES_METHOD_ID = env.GetMethodID (STRING_CLASS, " getBytes" , " (Ljava/lang/String;)[B" );
37- assert (GET_BYTES_METHOD_ID != nullptr );
38-
39- JniLocalRef encoding (env.NewStringUTF (" UTF-8" ));
40- UTF_8_ENCODING = (jstring)env.NewGlobalRef (encoding);
41- assert (UTF_8_ENCODING != nullptr );
42-
43- auto charClass = env.FindClass (" java/lang/Character" );
44- assert (charClass != nullptr );
45- CHAR_VALUE_METHOD_ID = env.GetMethodID (charClass, " charValue" , " ()C" );
46- assert (CHAR_VALUE_METHOD_ID != nullptr );
47-
48- auto booleanClass = env.FindClass (" java/lang/Boolean" );
49- assert (booleanClass != nullptr );
50- BOOLEAN_VALUE_METHOD_ID = env.GetMethodID (booleanClass, " booleanValue" , " ()Z" );
51- assert (BOOLEAN_VALUE_METHOD_ID != nullptr );
52-
53- auto byteClass = env.FindClass (" java/lang/Byte" );
54- assert (byteClass != nullptr );
55- BYTE_VALUE_METHOD_ID = env.GetMethodID (byteClass, " byteValue" , " ()B" );
56- assert (BYTE_VALUE_METHOD_ID != nullptr );
57-
58- auto shortClass = env.FindClass (" java/lang/Short" );
59- assert (shortClass != nullptr );
60- SHORT_VALUE_METHOD_ID = env.GetMethodID (shortClass, " shortValue" , " ()S" );
61- assert (SHORT_VALUE_METHOD_ID != nullptr );
62-
63- auto integerClass = env.FindClass (" java/lang/Integer" );
64- assert (integerClass != nullptr );
65- INT_VALUE_METHOD_ID = env.GetMethodID (integerClass, " intValue" , " ()I" );
66- assert (INT_VALUE_METHOD_ID != nullptr );
67-
68- auto longClass = env.FindClass (" java/lang/Long" );
69- assert (longClass != nullptr );
70- LONG_VALUE_METHOD_ID = env.GetMethodID (longClass, " longValue" , " ()J" );
71- assert (LONG_VALUE_METHOD_ID != nullptr );
72-
73- auto floatClass = env.FindClass (" java/lang/Float" );
74- assert (floatClass != nullptr );
75- FLOAT_VALUE_METHOD_ID = env.GetMethodID (floatClass, " floatValue" , " ()F" );
76- assert (FLOAT_VALUE_METHOD_ID != nullptr );
77-
78- auto doubleClass = env.FindClass (" java/lang/Double" );
79- assert (doubleClass != nullptr );
80- DOUBLE_VALUE_METHOD_ID = env.GetMethodID (doubleClass, " doubleValue" , " ()D" );
81- assert (DOUBLE_VALUE_METHOD_ID != nullptr );
8231}
8332
8433void ArgConverter::NativeScriptLongValueOfFunctionCallback (const v8::FunctionCallbackInfo<Value>& args)
@@ -96,72 +45,13 @@ void ArgConverter::NativeScriptLongFunctionCallback(const v8::FunctionCallbackIn
9645{
9746 auto isolate = Isolate::GetCurrent ();
9847 args.This ()->SetHiddenValue (V8StringConstants::GetJavaLong (), Boolean::New (isolate, true ));
99- args.This ()->SetHiddenValue (ConvertToV8String ( V8StringConstants::MARKED_AS_LONG ), args[0 ]);
48+ args.This ()->SetHiddenValue (V8StringConstants::GetMarkedAsLong ( ), args[0 ]);
10049 args.This ()->Set (V8StringConstants::GetValue (), args[0 ]);
10150
10251 args.This ()->SetPrototype (Local<NumberObject>::New (Isolate::GetCurrent (), *NAN_NUMBER_OBJECT));
10352}
10453
10554
106- jlong ArgConverter::ObjectToLong (jobject object)
107- {
108- JEnv env;
109-
110- return env.CallLongMethod (object, LONG_VALUE_METHOD_ID);
111- }
112-
113- jboolean ArgConverter::ObjectToBoolean (jobject object)
114- {
115- JEnv env;
116-
117- return env.CallBooleanMethod (object, BOOLEAN_VALUE_METHOD_ID);
118- }
119-
120- jchar ArgConverter::ObjectToChar (jobject object)
121- {
122- JEnv env;
123-
124- return env.CallCharMethod (object, CHAR_VALUE_METHOD_ID);
125- }
126-
127-
128- jbyte ArgConverter::ObjectToByte (jobject object)
129- {
130- JEnv env;
131-
132- return env.CallByteMethod (object, BYTE_VALUE_METHOD_ID);
133- }
134-
135- jshort ArgConverter::ObjectToShort (jobject object)
136- {
137- JEnv env;
138-
139- return env.CallShortMethod (object, SHORT_VALUE_METHOD_ID);
140- }
141-
142- jint ArgConverter::ObjectToInt (jobject object)
143- {
144- JEnv env;
145-
146- return env.CallIntMethod (object, INT_VALUE_METHOD_ID);
147- }
148-
149-
150- jfloat ArgConverter::ObjectToFloat (jobject object)
151- {
152- JEnv env;
153-
154- return env.CallFloatMethod (object, FLOAT_VALUE_METHOD_ID);
155- }
156-
157- jdouble ArgConverter::ObjectToDouble (jobject object)
158- {
159- JEnv env;
160-
161- return env.CallDoubleMethod (object, DOUBLE_VALUE_METHOD_ID);
162- }
163-
164-
16555jstring ArgConverter::ObjectToString (jobject object)
16656{
16757 return (jstring)object;
@@ -184,30 +74,44 @@ Handle<Array> ArgConverter::ConvertJavaArgsToJsArgs(jobjectArray args)
18474 JniLocalRef argJavaClassPath (env.GetObjectArrayElement (args, jArrayIndex++));
18575
18676 jint length;
187- jint argTypeID = ObjectToInt ( argTypeIDObj);
77+ Type argTypeID = (Type) JType::IntValue (env, argTypeIDObj);
18878
18979 Handle<Value> jsArg;
19080 Handle<String> v8String;
19181 switch (argTypeID)
19282 {
193- case TypeID_Boolean : jsArg = Boolean::New (isolate, ObjectToBoolean (arg)); break ;
194- case TypeID_Char:
195- v8String = jcharToV8String (ObjectToChar (arg));
83+ case Type::Boolean:
84+ jsArg = Boolean::New (isolate, JType::BooleanValue (env, arg));
85+ break ;
86+ case Type::Char:
87+ v8String = jcharToV8String (JType::CharValue (env, arg));
19688 jsArg = v8String;
19789 break ;
198- case TypeID_Byte: jsArg = Number::New (isolate, ObjectToByte (arg)); break ;
199- case TypeID_Short: jsArg = Number::New (isolate, ObjectToShort (arg)); break ;
200- case TypeID_Int: jsArg = Number::New (isolate, ObjectToInt (arg)); break ;
201- case TypeID_Long: jsArg = Number::New (isolate, ObjectToLong (arg)); break ;
202- case TypeID_Float: jsArg = Number::New (isolate, ObjectToFloat (arg)); break ;
203- case TypeID_Double: jsArg = Number::New (isolate, ObjectToDouble (arg)); break ;
204- case TypeID_String:
205- v8String = jstringToV8String (ObjectToString (arg));
90+ case Type::Byte:
91+ jsArg = Number::New (isolate, JType::ByteValue (env, arg));
92+ break ;
93+ case Type::Short:
94+ jsArg = Number::New (isolate, JType::ShortValue (env, arg));
95+ break ;
96+ case Type::Int:
97+ jsArg = Number::New (isolate, JType::IntValue (env, arg));
98+ break ;
99+ case Type::Long:
100+ jsArg = Number::New (isolate, JType::LongValue (env, arg));
101+ break ;
102+ case Type::Float:
103+ jsArg = Number::New (isolate, JType::FloatValue (env, arg));
104+ break ;
105+ case Type::Double:
106+ jsArg = Number::New (isolate, JType::DoubleValue (env, arg));
107+ break ;
108+ case Type::String:
109+ v8String = jstringToV8String ((jstring)arg);
206110 jsArg = v8String;
207111 break ;
208- case TypeID_JsObject :
112+ case Type::JsObject :
209113 {
210- jint javaObjectID = ObjectToInt ( arg);
114+ jint javaObjectID = JType::IntValue (env, arg);
211115 jsArg = ObjectManager::GetJsObjectByJavaObjectStatic (javaObjectID);
212116
213117 if (jsArg.IsEmpty ())
@@ -218,7 +122,9 @@ Handle<Array> ArgConverter::ConvertJavaArgsToJsArgs(jobjectArray args)
218122 }
219123 break ;
220124 }
221- case TypeID_Null: jsArg = Null (isolate); break ;
125+ case Type::Null:
126+ jsArg = Null (isolate);
127+ break ;
222128 }
223129
224130 arr->Set (i, jsArg);
@@ -229,8 +135,16 @@ Handle<Array> ArgConverter::ConvertJavaArgsToJsArgs(jobjectArray args)
229135
230136std::string ArgConverter::jstringToString (jstring value)
231137{
232- if (value == nullptr )
138+ if (value == nullptr ) {
233139 return string ();
140+ }
141+
142+ jsize utfLength;
143+ bool readInBuffer = ReadJStringInBuffer (value, utfLength);
144+ if (readInBuffer) {
145+ string s (charBuffer, utfLength);
146+ return s;
147+ }
234148
235149 JEnv env;
236150
@@ -242,33 +156,43 @@ std::string ArgConverter::jstringToString(jstring value)
242156 return s;
243157}
244158
245- Handle <String> ArgConverter::jcharToV8String (jchar value)
159+ Local <String> ArgConverter::jstringToV8String (jstring value)
246160{
161+ if (value == nullptr )
162+ {
163+ return Handle<String>();
164+ }
165+
247166 JEnv env;
167+ auto chars = env.GetStringChars (value, NULL );
168+ auto length = env.GetStringLength (value);
169+ auto v8String = ConvertToV8String (chars, length);
170+ env.ReleaseStringChars (value, chars);
248171
249- JniLocalRef str (env.NewString (&value, 1 ));
250- jboolean bol = true ;
251- const char * resP = env.GetStringUTFChars (str, &bol);
252- auto v8String = ConvertToV8String (resP, 1 );
253- env.ReleaseStringUTFChars (str, resP);
254172 return v8String;
255173}
256174
257- Local<String> ArgConverter::jstringToV8String (jstring value)
258- {
259- if (value == nullptr )
260- {
261- return Handle<String>();
175+ bool ArgConverter::ReadJStringInBuffer (jstring value, jsize& utfLength) {
176+ if (value == nullptr ) {
177+ return false ;
262178 }
263179
264180 JEnv env;
181+ utfLength = env.GetStringUTFLength (value);
182+ if (utfLength > BUFFER_SIZE) {
183+ return false ;
184+ }
265185
266- JniLocalRef arr (env.CallObjectMethod (value, GET_BYTES_METHOD_ID, UTF_8_ENCODING));
267- int length = env.GetArrayLength (arr);
268- jbyte *data = env.GetByteArrayElements (arr, nullptr );
269- auto v8String = ConvertToV8String ((const char *)data, length);
270- env.ReleaseByteArrayElements (arr, data, JNI_ABORT);
186+ jsize strLength = env.GetStringLength (value);
187+ // use existing buffer to prevent extensive memory allocation
188+ env.GetStringUTFRegion (value, (jsize)0 , strLength, charBuffer);
271189
190+ return true ;
191+ }
192+
193+ Handle<String> ArgConverter::jcharToV8String (jchar value)
194+ {
195+ auto v8String = ConvertToV8String (&value, 1 );
272196 return v8String;
273197}
274198
@@ -345,14 +269,4 @@ bool ArgConverter::TryConvertToJavaLong(const Handle<Value>& value, jlong& javaL
345269JavaVM* ArgConverter::jvm = nullptr ;
346270Persistent<Function>* ArgConverter::NATIVESCRIPT_NUMERA_CTOR_FUNC = nullptr ;
347271Persistent<NumberObject>* ArgConverter::NAN_NUMBER_OBJECT = nullptr ;
348- jclass ArgConverter::STRING_CLASS = nullptr ;
349- jmethodID ArgConverter::GET_BYTES_METHOD_ID = nullptr ;
350- jmethodID ArgConverter::CHAR_VALUE_METHOD_ID = nullptr ;
351- jmethodID ArgConverter::BOOLEAN_VALUE_METHOD_ID = nullptr ;
352- jmethodID ArgConverter::BYTE_VALUE_METHOD_ID = nullptr ;
353- jmethodID ArgConverter::SHORT_VALUE_METHOD_ID = nullptr ;
354- jmethodID ArgConverter::INT_VALUE_METHOD_ID = nullptr ;
355- jmethodID ArgConverter::LONG_VALUE_METHOD_ID = nullptr ;
356- jmethodID ArgConverter::FLOAT_VALUE_METHOD_ID = nullptr ;
357- jmethodID ArgConverter::DOUBLE_VALUE_METHOD_ID = nullptr ;
358- jstring ArgConverter::UTF_8_ENCODING = nullptr ;
272+ char * ArgConverter::charBuffer = new char [ArgConverter::BUFFER_SIZE];
0 commit comments