blob: 477b31259d934297d5775e91ef7c28292d6c9947 [file] [log] [blame]
gwt.team.knortoncf244552008-03-20 09:40:25 +00001/*
2 * Copyright 2008 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
17#include <iostream>
18#include <JavaScriptCore/JavaScriptCore.h>
19#include "gwt-webkit.h"
20#include "JStringWrap.h"
21#include "java-dispatch.h"
22#include "trace.h"
23
24
25// http://unixjunkie.blogspot.com/2006/07/access-argc-and-argv-from-anywhere.html
26extern "C" int *_NSGetArgc(void);
27extern "C" char ***_NSGetArgv(void);
28
29/*
30 *
31 */
32JSContextRef ToJSContextRef(jint context) {
33 return reinterpret_cast<JSContextRef>(context);
34}
35
36/*
37 *
38 */
39JSValueRef ToJSValueRef(jint value) {
40 return reinterpret_cast<JSValueRef>(value);
41}
42
43/*
44 *
45 */
46JSObjectRef ToJSObjectRef(JSContextRef jsContext, jint object,
47 JSValueRef* jsException) {
48 JSValueRef jsValue = reinterpret_cast<JSValueRef>(object);
49 if (!jsValue || !JSValueIsObject(jsContext, jsValue)) {
50 return NULL;
51 }
52 return JSValueToObject(jsContext, jsValue, jsException);
53}
54
55/*
56 *
57 */
58JSObjectRef ToJSObjectRef(JSContextRef jsContext, JSValueRef jsValue,
59 JSValueRef* jsException) {
60 if (!jsValue || !JSValueIsObject(jsContext, jsValue)) {
61 return NULL;
62 }
63 return JSValueToObject(jsContext, jsValue, jsException);
64}
65
66/*
67 *
68 */
69JSObjectRef GetStringConstructor(JSContextRef jsContext,
70 JSValueRef* jsException) {
71 // This could only be cached relative to jsContext.
72 JSStringRef script = JSStringCreateWithUTF8CString("(String)");
73 JSValueRef ctorVal = JSEvaluateScript(jsContext, script, NULL, NULL, 0, jsException);
74 JSStringRelease(script);
75 return ToJSObjectRef(jsContext, ctorVal, jsException);
76}
77
78/*
79 *
80 */
81bool IsObjectOfStringConstructor(JSContextRef jsContext, JSValueRef jsValue,
82 JSValueRef* jsException) {
83 JSObjectRef jsObject = ToJSObjectRef(jsContext, jsValue, jsException);
84 if (!jsObject) {
85 return false;
86 }
87 JSObjectRef stringCtor = GetStringConstructor(jsContext, jsException);
88 if (!stringCtor) {
89 return false;
90 }
91 return JSValueIsInstanceOfConstructor(jsContext, jsObject, stringCtor,
92 jsException);
93}
94
95#if 0 // For debugging purposes only.
96void PrintJSString(JSStringRef jsString)
97{
98 size_t length = JSStringGetMaximumUTF8CStringSize(jsString);
99 char* buffer = new char[length];
100 JSStringGetUTF8CString(jsString, buffer, length);
101 std::cerr << "JSString: " << buffer << std::endl;
102 delete[] buffer;
103}
104
105void PrintJSValue(JSContextRef jsContext, JSValueRef jsValue)
106{
107 JSValueRef jsException = NULL;
108 JSStringRef jsResult = JSValueToStringCopy(jsContext, jsValue,
109 &jsException);
110 if (!jsException && jsValue) {
111 PrintJSString(jsResult);
112 } else {
113 std::cerr << "Could not convert the value to string." << std::endl;
114 }
115}
116#endif
117
118/*
119 *
120 */
121JSStringRef ToJSStringRef(JNIEnv* env, jstring jstr) {
122 if (!jstr) {
123 return NULL;
124 }
125
126 JStringWrap jstrw(env, jstr);
127 if (!jstrw.jstr()) {
128 return NULL;
129 }
130
131 return JSStringCreateWithCharacters(static_cast<const JSChar*>(jstrw.jstr()),
132 static_cast<size_t>(jstrw.length()));
133}
134
135/*
136 *
137 */
138JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsNull
139 (JNIEnv *env, jclass klass, jint context, jint value) {
140 TR_ENTER();
141 JSContextRef jsContext = ToJSContextRef(context);
142 JSValueRef jsValue = ToJSValueRef(value);
143 if (!jsContext || !jsValue) {
144 TR_FAIL();
145 return JNI_FALSE;
146 }
147 TR_LEAVE();
148 return static_cast<jboolean>(JSValueIsNull(jsContext, jsValue));
149}
150
151/*
152 *
153 */
154JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsUndefined
155 (JNIEnv *env, jclass klass, jint context, jint value) {
156 TR_ENTER();
157 JSContextRef jsContext = ToJSContextRef(context);
158 JSValueRef jsValue = ToJSValueRef(value);
159 if (!jsContext || !jsValue) {
160 TR_FAIL();
161 return JNI_FALSE;
162 }
163 TR_LEAVE();
164 return static_cast<jboolean>(JSValueIsUndefined(jsContext, jsValue));
165}
166
167/*
168 *
169 */
170JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getJsUndefined
171 (JNIEnv *env, jclass klass, jint context) {
172 TR_ENTER();
173 JSContextRef jsContext = ToJSContextRef(context);
174 if (!jsContext) {
175 return static_cast<jint>(NULL);
176 }
177
178 JSValueRef jsUndefined = JSValueMakeUndefined(jsContext);
179 JSValueProtectChecked(jsContext, jsUndefined);
180 TR_LEAVE();
181 return reinterpret_cast<jint>(jsUndefined);
182}
183
184/*
185 *
186 */
187JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getJsNull
188 (JNIEnv *env, jclass klass, jint context) {
189 TR_ENTER();
190 JSContextRef jsContext = ToJSContextRef(context);
191 if (!jsContext) {
192 return static_cast<jint>(NULL);
193 }
194 JSValueRef jsNull = JSValueMakeNull(jsContext);
195 JSValueProtectChecked(jsContext, jsNull);
196 TR_LEAVE();
197 return reinterpret_cast<jint>(jsNull);
198}
199
200/*
201 *
202 */
203JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsBoolean
204 (JNIEnv *env, jclass klass, jint context, jint value) {
205 TR_ENTER();
206 JSContextRef jsContext = ToJSContextRef(context);
207 JSValueRef jsValue = ToJSValueRef(value);
208 if (!jsContext || !jsValue) {
209 TR_FAIL();
210 return JNI_FALSE;
211 }
212 TR_LEAVE();
213 return static_cast<jboolean>(JSValueIsBoolean(jsContext, jsValue));
214}
215
216/*
217 *
218 */
219JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsNumber
220 (JNIEnv *env, jclass klass, jint context, jint value) {
221 TR_ENTER();
222 JSContextRef jsContext = ToJSContextRef(context);
223 JSValueRef jsValue = ToJSValueRef(value);
224 if (!jsContext || !jsValue) {
225 TR_FAIL();
226 return JNI_FALSE;
227 }
228 TR_LEAVE();
229 return static_cast<jboolean>(JSValueIsNumber(jsContext, jsValue));
230}
231
232/*
233 *
234 */
235JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toJsBooleanImpl
236 (JNIEnv *env, jclass klass, jint context, jboolean jValue, jintArray rval) {
237 TR_ENTER();
238 JSContextRef jsContext = ToJSContextRef(context);
239 if (!jsContext) {
240 TR_FAIL();
241 return JNI_FALSE;
242 }
243
244 JSValueRef jsValue = JSValueMakeBoolean(jsContext, static_cast<bool>(jValue));
245
246 env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsValue));
247 if (env->ExceptionCheck()) {
248 TR_FAIL();
249 return JNI_FALSE;
250 }
251 JSValueProtectChecked(jsContext, jsValue);
252
253 TR_LEAVE();
254 return JNI_TRUE;
255}
256
257/*
258 *
259 */
260JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_gcUnprotect
261 (JNIEnv *env, jclass klass, jint context, jint value) {
262 TR_ENTER();
263 JSContextRef jsContext = ToJSContextRef(context);
264 JSValueRef jsValue = ToJSValueRef(value);
265 if (!jsContext || !jsValue) {
266 return;
267 }
268 JSValueUnprotectChecked(jsContext, jsValue);
269 TR_LEAVE();
270}
271
272/*
273 *
274 */
275JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toJsNumberImpl
276 (JNIEnv *env, jclass klass, jint context, jdouble jValue, jintArray rval) {
277 TR_ENTER();
278 JSContextRef jsContext = ToJSContextRef(context);
279 if (!jsContext) {
280 TR_FAIL();
281 return JNI_FALSE;
282 }
283
284 JSValueRef jsValue = JSValueMakeNumber(jsContext, static_cast<jdouble>(jValue));
285
286 env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsValue));
287 if (env->ExceptionCheck()) {
288 TR_FAIL();
289 return JNI_FALSE;
290 }
291
292 JSValueProtectChecked(jsContext, jsValue);
293
294 TR_LEAVE();
295 return JNI_TRUE;
296}
297
298/*
299 *
300 */
301JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_executeScriptWithInfoImpl
302 (JNIEnv *env, jclass klass, jint context, jstring jScript, jstring jUrl,
303 jint jLine, jintArray rval) {
304 TR_ENTER();
305 JSValueRef jsException = NULL;
306
307 JSContextRef jsContext = ToJSContextRef(context);
308 if (!jsContext) {
309 TR_FAIL();
310 return JNI_FALSE;
311 }
312
313 JSStringRef jsScript = ToJSStringRef(env, jScript);
314 if (!jsScript) {
315 TR_FAIL();
316 return JNI_FALSE;
317 }
318
319 JSStringRef jsUrl = ToJSStringRef(env, jUrl);
320
321 // Evaluate will set this to global object.
322 JSValueRef jsResult = JSEvaluateScript(jsContext, jsScript, NULL, jsUrl,
323 static_cast<int>(jLine), &jsException);
324 if (jsException) {
325 TR_FAIL();
326 return JNI_FALSE;
327 }
328
329 JSStringRelease(jsScript);
330 if (jsUrl) {
331 JSStringRelease(jsUrl);
332 }
333
334 env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsResult));
335 if (env->ExceptionCheck()) {
336 TR_FAIL();
337 return JNI_FALSE;
338 }
339
340 JSValueProtectChecked(jsContext, jsResult);
341
342 TR_LEAVE();
343 return JNI_TRUE;
344}
345
346/*
347 *
348 */
349JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toJsStringImpl
350 (JNIEnv *env, jclass klass, jint context, jstring jValue, jintArray rval) {
351 TR_ENTER();
352 JSContextRef jsContext = ToJSContextRef(context);
353 if (!jsContext) {
354 TR_FAIL();
355 return JNI_FALSE;
356 }
357
358 JSStringRef jsString = ToJSStringRef(env, jValue);
359 if (!jsString) {
360 TR_FAIL();
361 return JNI_FALSE;
362 }
363
364 JSValueRef jsValue = JSValueMakeString(jsContext, jsString);
365 JSStringRelease(jsString);
366
367 env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsValue));
368 if (env->ExceptionCheck()) {
369 TR_FAIL();
370 return JNI_FALSE;
371 }
372
373 JSValueProtectChecked(jsContext, jsValue);
374
375 TR_LEAVE();
376 return JNI_TRUE;
377}
378
379/*
380 *
381 */
382JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsStringImpl
383 (JNIEnv *env, jclass klass, jint context, jint value, jbooleanArray rval) {
384 TR_ENTER();
385 JSContextRef jsContext = ToJSContextRef(context);
386 JSValueRef jsValue = ToJSValueRef(value);
387 if (!jsContext || !jsValue) {
388 TR_FAIL();
389 return JNI_FALSE;
390 }
391
392 bool isString = JSValueIsString(jsContext, jsValue);
393 if (!isString) {
394 JSValueRef jsException = NULL;
395 isString = IsObjectOfStringConstructor(jsContext, jsValue, &jsException);
396 if (jsException) {
397 TR_FAIL();
398 return JNI_FALSE;
399 }
400 }
401
402 jboolean jIsString = static_cast<jboolean>(isString);
403 env->SetBooleanArrayRegion(rval, 0, 1, &jIsString);
404 if (env->ExceptionCheck()) {
405 TR_FAIL();
406 return JNI_FALSE;
407 }
408
409 TR_LEAVE();
410 return JNI_TRUE;
411}
412
413/*
414 *
415 */
416JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_invokeImpl
417 (JNIEnv *env, jclass klass, jint context, jint scriptValue,
418 jstring jMethodName, jint thisVal, jintArray jArgs, jint jArgsLength,
419 jintArray rval) {
420 TR_ENTER();
421
422 JSContextRef jsContext = ToJSContextRef(context);
423 if (!jsContext) {
424 TR_FAIL();
425 return JNI_FALSE;
426 }
427
428 JSObjectRef jsScriptObj = ToJSObjectRef(jsContext, scriptValue, NULL);
429 if (!jsScriptObj) {
430 TR_FAIL();
431 return JNI_FALSE;
432 }
433
434 JSValueRef jsThisVal = ToJSValueRef(thisVal);
435 JSObjectRef jsThisObj = NULL;
436 // If thisVal is null, jsNull, or jsUndefined use the script object
437 // as this.
438 if (!jsThisVal || JSValueIsNull(jsContext, jsThisVal)
439 || JSValueIsUndefined(jsContext, jsThisVal)) {
440 jsThisObj = jsScriptObj;
441 } else {
442 // If we are given a value, ensure that it is an object.
443 jsThisObj = ToJSObjectRef(jsContext, jsThisVal, NULL);
444 if (!jsThisObj) {
445 TR_FAIL();
446 return JNI_FALSE;
447 }
448 }
449
450 JSStringRef jsMethodName = ToJSStringRef(env, jMethodName);
451 if (!jsMethodName) {
452 TR_FAIL();
453 return JNI_FALSE;
454 }
455
456 JSObjectRef jsMethod = ToJSObjectRef(jsContext, JSObjectGetProperty(jsContext,
457 jsScriptObj, jsMethodName, NULL), NULL);
458 if (!jsMethod || !JSObjectIsFunction(jsContext, jsMethod)) {
459 TR_FAIL();
460 return JNI_FALSE;
461 }
462
463 JSStringRelease(jsMethodName);
464
465 // NOTE (knorton): Fix for 64-bit.
466 JSValueRef* jsArgs = new JSValueRef[static_cast<size_t>(jArgsLength)];
467 env->GetIntArrayRegion(jArgs, 0, jArgsLength,
468 reinterpret_cast<jint*>(jsArgs));
469 if (env->ExceptionCheck()) {
470 TR_FAIL();
471 delete[] jsArgs;
472 return JNI_FALSE;
473 }
474
475 JSValueRef jsException = NULL;
476 JSValueRef jsResult = JSObjectCallAsFunction(jsContext, jsMethod, jsThisObj,
477 static_cast<size_t>(jArgsLength), jsArgs, &jsException);
478 if (jsException) {
479 TR_FAIL();
480 delete[] jsArgs;
481 return JNI_FALSE;
482 }
483 delete[] jsArgs;
484
485 env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsResult));
486 if (env->ExceptionCheck()) {
487 TR_FAIL();
488 return JNI_FALSE;
489 }
490
491 JSValueProtectChecked(jsContext, jsResult);
492
493 TR_LEAVE();
494 return JNI_TRUE;
495}
496
497/*
498 *
499 */
500JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsObject
501 (JNIEnv *env, jclass klass, jint context, jint value) {
502 TR_ENTER();
503 JSContextRef jsContext = ToJSContextRef(context);
504 JSValueRef jsValue = ToJSValueRef(value);
505 if (!jsContext || !jsValue) {
506 TR_FAIL();
507 return JNI_FALSE;
508 }
509
510 TR_LEAVE();
511 return static_cast<jboolean>(JSValueIsObject(jsContext, jsValue));
512}
513
514JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toBooleanImpl
515 (JNIEnv *env, jclass klass, jint context, jint value, jbooleanArray rval) {
516 TR_ENTER();
517 JSContextRef jsContext = ToJSContextRef(context);
518 JSValueRef jsValue = ToJSValueRef(value);
519 if (!jsContext || !jsValue) {
520 TR_FAIL();
521 return JNI_FALSE;
522 }
523
524 jboolean jResult = static_cast<jboolean>(JSValueToBoolean(jsContext, jsValue));
525 env->SetBooleanArrayRegion(rval, 0, 1, &jResult);
526 if (env->ExceptionCheck()) {
527 TR_FAIL();
528 return JNI_FALSE;
529 }
530
531 TR_LEAVE();
532 return JNI_TRUE;
533}
534
535/*
536 *
537 */
538JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toDoubleImpl
539 (JNIEnv *env, jclass klass, jint context, jint value, jdoubleArray rval) {
540 TR_ENTER();
541 JSContextRef jsContext = ToJSContextRef(context);
542 JSValueRef jsValue = ToJSValueRef(value);
543 if (!jsContext || !jsValue) {
544 TR_FAIL();
545 return JNI_FALSE;
546 }
547
548 JSValueRef jsException = NULL;
549 double result = JSValueToNumber(jsContext, jsValue, &jsException);
550 if (jsException) {
551 TR_FAIL();
552 return JNI_FALSE;
553 }
554
555 env->SetDoubleArrayRegion(rval, 0, 1, static_cast<jdouble*>(&result));
556 if (env->ExceptionCheck()) {
557 TR_FAIL();
558 return JNI_FALSE;
559 }
560
561 TR_LEAVE();
562 return JNI_TRUE;
563}
564
565/*
566 *
567 */
568JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toStringImpl
569 (JNIEnv *env, jclass klass, jint context, jint value, jobjectArray rval) {
570 TR_ENTER();
571 JSValueRef jsException = NULL;
572 JSContextRef jsContext = ToJSContextRef(context);
573 JSValueRef jsValue = ToJSValueRef(value);
574 if (!jsContext || !jsValue) {
575 TR_FAIL();
576 return JNI_FALSE;
577 }
578
579 jstring jResult = NULL;
580 // Convert all objects to their string representation, EXCEPT
581 // null and undefined which will be returned as a true NULL.
582 if (!JSValueIsNull(jsContext, jsValue) &&
583 !JSValueIsUndefined(jsContext, jsValue)) {
584 JSStringRef jsResult = JSValueToStringCopy(jsContext, jsValue, &jsException);
585 if (jsException) {
586 TR_FAIL();
587 return JNI_FALSE;
588 }
589
590 jResult = env->NewString(
591 static_cast<const jchar*>(JSStringGetCharactersPtr(jsResult)),
592 static_cast<jsize>(JSStringGetLength(jsResult)));
593 if (env->ExceptionCheck()) {
594 TR_FAIL();
595 return JNI_FALSE;
596 }
597
598 JSStringRelease(jsResult);
599 }
600
601 env->SetObjectArrayElement(rval, 0, jResult);
602 if (env->ExceptionCheck()) {
603 TR_FAIL();
604 return JNI_FALSE;
605 }
606
607 TR_LEAVE();
608 return JNI_TRUE;
609}
610
611/*
612 *
613 */
614JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_wrapDispatchObjectImpl
615 (JNIEnv *env, jclass klass, jint context, jobject dispatch, jintArray rval) {
616 TR_ENTER();
617 JSContextRef jsContext = ToJSContextRef(context);
618 if (!jsContext) {
619 TR_FAIL();
620 return JNI_FALSE;
621 }
622
623 JSObjectRef jsDispatch = gwt::DispatchObjectCreate(jsContext, dispatch);
624 if (!jsDispatch || env->ExceptionCheck()) {
625 TR_FAIL();
626 return JNI_FALSE;
627 }
628
629 env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<jint*>(&jsDispatch));
630 if (env->ExceptionCheck()) {
631 TR_FAIL();
632 return JNI_FALSE;
633 }
634
635 JSValueProtectChecked(jsContext, jsDispatch);
636
637 TR_LEAVE();
638 return JNI_TRUE;
639}
640
641/*
642 *
643 */
644JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_unwrapDispatchObjectImpl
645 (JNIEnv *env, jclass klass, jint context, jint value, jobjectArray rval) {
646 TR_ENTER();
647 JSContextRef jsContext = ToJSContextRef(context);
648 JSValueRef jsValue = ToJSValueRef(value);
649 if (!jsContext || !jsValue) {
650 TR_FAIL();
651 return JNI_FALSE;
652 }
653
654 if (!JSValueIsObjectOfClass(jsContext, jsValue, gwt::GetDispatchObjectClass())) {
655 TR_FAIL();
656 return JNI_FALSE;
657 }
658
659 JSObjectRef jsObject = ToJSObjectRef(jsContext, jsValue, NULL);
660 if (!jsObject) {
661 TR_FAIL();
662 return JNI_FALSE;
663 }
664
665 env->SetObjectArrayElement(rval, 0, reinterpret_cast<jobject>(JSObjectGetPrivate(jsObject)));
666 if (env->ExceptionCheck()) {
667 TR_FAIL();
668 return JNI_FALSE;
669 }
670
671 TR_LEAVE();
672 return JNI_TRUE;
673}
674
675/*
676 *
677 */
678JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_initImpl
679 (JNIEnv *env, jclass klass, jclass dispatchObjectClass,
gwt.team.knortonb3682d72008-03-29 03:19:56 +0000680 jclass dispatchMethodClass, jclass lowLevelSafClass) {
gwt.team.knortoncf244552008-03-20 09:40:25 +0000681 TR_ENTER();
682 TR_LEAVE();
gwt.team.knortonb3682d72008-03-29 03:19:56 +0000683 return static_cast<jboolean>(gwt::Initialize(env, dispatchObjectClass, dispatchMethodClass, lowLevelSafClass));
gwt.team.knortoncf244552008-03-20 09:40:25 +0000684}
685
686/*
687 *
688 */
689JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_wrapDispatchMethodImpl
690 (JNIEnv *env, jclass klass, jint context, jstring name, jobject jDispatch,
691 jintArray rval) {
692 TR_ENTER();
693 JSContextRef jsContext = ToJSContextRef(context);
694 if (!jsContext) {
695 TR_FAIL();
696 return JNI_FALSE;
697 }
698
699 JStringWrap nameWrap(env, name);
700 std::string nameStr(nameWrap.str());
701 JSObjectRef jsDispatch = gwt::DispatchMethodCreate(jsContext, nameStr,
702 jDispatch);
703 if (!jsDispatch || env->ExceptionCheck()) {
704 TR_FAIL();
705 return JNI_FALSE;
706 }
707
708 env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<jint*>(&jsDispatch));
709 if (env->ExceptionCheck()) {
710 TR_FAIL();
711 return JNI_FALSE;
712 }
713
714 JSValueProtectChecked(jsContext, jsDispatch);
715
716 TR_LEAVE();
717 return JNI_TRUE;
718}
719
720/*
721 *
722 */
723JNIEXPORT jstring JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getTypeString
724 (JNIEnv *env, jclass klass, jint context, jint value) {
725 TR_ENTER();
726 JSContextRef jsContext = ToJSContextRef(context);
727 JSValueRef jsValue = ToJSValueRef(value);
728 if (!jsContext || !jsValue) {
729 return NULL;
730 }
731
732 switch (JSValueGetType(jsContext, jsValue)) {
733 case kJSTypeUndefined:
734 return env->NewStringUTF("undefined");
735 case kJSTypeNull:
736 return env->NewStringUTF("null");
737 case kJSTypeBoolean:
738 return env->NewStringUTF("boolean");
739 case kJSTypeNumber:
740 return env->NewStringUTF("number");
741 case kJSTypeString:
742 return env->NewStringUTF("string");
743 case kJSTypeObject:
744 return (JSValueIsObjectOfClass(jsContext, jsValue, gwt::GetDispatchObjectClass()))
745 ? env->NewStringUTF("Java object") : env->NewStringUTF("JavaScript object");
746 default:
747 return env->NewStringUTF("unknown");
748 }
749}
750
751/*
752 *
753 */
754JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isDispatchObjectImpl
755 (JNIEnv *env, jclass klass, jint context, jint value, jbooleanArray rval) {
756 TR_ENTER();
757 JSContextRef jsContext = ToJSContextRef(context);
758 JSValueRef jsValue = ToJSValueRef(value);
759 if (!jsContext || !jsValue) {
760 TR_FAIL();
761 return JNI_FALSE;
762 }
763
764 jboolean jIsDispatchObject = static_cast<jboolean>(JSValueIsObjectOfClass(
765 jsContext, jsValue, gwt::GetDispatchObjectClass()));
766 env->SetBooleanArrayRegion(rval, 0, 1, &jIsDispatchObject);
767 if (env->ExceptionCheck()) {
768 TR_FAIL();
769 return JNI_FALSE;
770 }
771
772 TR_LEAVE();
773 return JNI_TRUE;
774}
775
776/*
777 *
778 */
779JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getArgc
780 (JNIEnv *env, jclass klass) {
781 return *_NSGetArgc();
782}
783
784/*
785 *
786 */
787JNIEXPORT jstring JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getArgv
788 (JNIEnv *env, jclass klass, jint index) {
789 int argc = *_NSGetArgc();
790 if (index < 0 || index >= argc) {
791 return 0;
792 }
793 char **argv = *_NSGetArgv();
794 return env->NewStringUTF(argv[index]);
795}
796
797/*
798 *
799 */
800JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getGlobalJsObjectImpl
801 (JNIEnv *env, jclass klass, jint context, jintArray rval) {
802 TR_ENTER();
803
804 JSContextRef jsContext = ToJSContextRef(context);
805 if (!jsContext) {
806 TR_FAIL();
807 return JNI_FALSE;
808 }
809
810 JSObjectRef jsGlobalObject = JSContextGetGlobalObject(jsContext);
811 env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<jint*>(&jsGlobalObject));
812 if (env->ExceptionCheck()) {
813 TR_FAIL();
814 return JNI_FALSE;
815 }
816
817 JSValueProtectChecked(jsContext, jsGlobalObject);
818
819 TR_LEAVE();
820 return JNI_TRUE;
821}
822
823/*
824 *
825 */
826JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_gcProtect
827 (JNIEnv *env, jclass klass, jint context, jint value) {
828 TR_ENTER();
829
830 JSContextRef jsContext = ToJSContextRef(context);
831 JSValueRef jsValue = ToJSValueRef(value);
832 if (!jsContext || !jsValue) {
833 return;
834 }
835
836 JSValueProtectChecked(jsContext, jsValue);
837 TR_LEAVE();
838}
839
840/*
841 *
842 */
843JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_retainJsGlobalContext
844 (JNIEnv *env, jclass klass, jint context) {
845 TR_ENTER();
846 JSGlobalContextRef jsContext = reinterpret_cast<JSGlobalContextRef>(context);
847 if (!jsContext) {
848 TR_FAIL();
849 return;
850 }
851 JSGlobalContextRetain(jsContext);
852 TR_LEAVE();
853}
854
855/*
856 *
857 */
858JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_releaseJsGlobalContext
859 (JNIEnv *env, jclass klass, jint context) {
860 TR_ENTER();
861 JSGlobalContextRef jsContext = reinterpret_cast<JSGlobalContextRef>(context);
862 if (!jsContext) {
863 TR_FAIL();
864 return;
865 }
866 JSGlobalContextRelease(jsContext);
867 TR_LEAVE();
868}
869
870/*
871 *
872 */
873JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isGcProtected
874 (JNIEnv *env, jclass klass, jint value) {
875 JSValueRef jsValue = ToJSValueRef(value);
876 TR_ENTER();
877 TR_LEAVE();
878 return static_cast<jboolean>(JSValueIsProtected(jsValue));
879}
880
881JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsValueProtectionCheckingEnabledImpl
882 (JNIEnv *env, jclass klass) {
883 TR_ENTER();
884 TR_LEAVE();
885 return static_cast<jboolean>(JSValueProtectCheckingIsEnabled());
886}