• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2010, The Android Open Source Project
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *  * Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 
27 #include "config.h"
28 #include "JavaNPObjectV8.h"
29 
30 #include "JNIUtilityPrivate.h"
31 #include "JavaClassV8.h"
32 #include "JavaInstanceV8.h"
33 #include "npruntime_impl.h"
34 
35 namespace JSC {
36 
37 namespace Bindings {
38 
AllocJavaNPObject(NPP,NPClass *)39 static NPObject* AllocJavaNPObject(NPP, NPClass*)
40 {
41     JavaNPObject* obj = static_cast<JavaNPObject*>(malloc(sizeof(JavaNPObject)));
42     if (!obj)
43         return 0;
44     memset(obj, 0, sizeof(JavaNPObject));
45     return reinterpret_cast<NPObject*>(obj);
46 }
47 
FreeJavaNPObject(NPObject * npobj)48 static void FreeJavaNPObject(NPObject* npobj)
49 {
50     JavaNPObject* obj = reinterpret_cast<JavaNPObject*>(npobj);
51     obj->m_instance = 0; // free does not call the destructor
52     free(obj);
53 }
54 
55 static NPClass JavaNPObjectClass = {
56     NP_CLASS_STRUCT_VERSION,
57     AllocJavaNPObject, // allocate,
58     FreeJavaNPObject, // free,
59     0, // invalidate
60     JavaNPObjectHasMethod,
61     JavaNPObjectInvoke,
62     0, // invokeDefault,
63     JavaNPObjectHasProperty,
64     JavaNPObjectGetProperty,
65     0, // setProperty
66     0, // removeProperty
67     0, // enumerate
68     0 // construct
69 };
70 
71 // ANDROID-specific change. TODO: Upstream
JavaInstanceToNPObject(PassRefPtr<JavaInstance> instance)72 NPObject* JavaInstanceToNPObject(PassRefPtr<JavaInstance> instance)
73 // END ANDROID-specific change
74 {
75     JavaNPObject* object = reinterpret_cast<JavaNPObject*>(_NPN_CreateObject(0, &JavaNPObjectClass));
76     object->m_instance = instance;
77     return reinterpret_cast<NPObject*>(object);
78 }
79 
80 // Returns null if obj is not a wrapper of JavaInstance
ExtractJavaInstance(NPObject * obj)81 JavaInstance* ExtractJavaInstance(NPObject* obj)
82 {
83     if (obj->_class == &JavaNPObjectClass)
84         return reinterpret_cast<JavaNPObject*>(obj)->m_instance.get();
85     return 0;
86 }
87 
JavaNPObjectHasMethod(NPObject * obj,NPIdentifier identifier)88 bool JavaNPObjectHasMethod(NPObject* obj, NPIdentifier identifier)
89 {
90     JavaInstance* instance = ExtractJavaInstance(obj);
91     if (!instance)
92         return false;
93     NPUTF8* name = _NPN_UTF8FromIdentifier(identifier);
94     if (!name)
95         return false;
96 
97     instance->begin();
98     bool result = (instance->getClass()->methodsNamed(name).size() > 0);
99     instance->end();
100 
101     // TODO: use NPN_MemFree
102     free(name);
103 
104     return result;
105 }
106 
JavaNPObjectInvoke(NPObject * obj,NPIdentifier identifier,const NPVariant * args,uint32_t argCount,NPVariant * result)107 bool JavaNPObjectInvoke(NPObject* obj, NPIdentifier identifier, const NPVariant* args, uint32_t argCount, NPVariant* result)
108 {
109     JavaInstance* instance = ExtractJavaInstance(obj);
110     if (!instance)
111         return false;
112     NPUTF8* name = _NPN_UTF8FromIdentifier(identifier);
113     if (!name)
114         return false;
115 
116     instance->begin();
117     bool r = instance->invokeMethod(name, args, argCount, result);
118     instance->end();
119 
120     // TODO: use NPN_MemFree
121     free(name);
122     return r;
123 }
124 
JavaNPObjectHasProperty(NPObject * obj,NPIdentifier identifier)125 bool JavaNPObjectHasProperty(NPObject* obj, NPIdentifier identifier)
126 {
127     JavaInstance* instance = ExtractJavaInstance(obj);
128     if (!instance)
129         return false;
130     NPUTF8* name = _NPN_UTF8FromIdentifier(identifier);
131     if (!name)
132         return false;
133     instance->begin();
134     bool result = instance->getClass()->fieldNamed(name);
135     instance->end();
136     free(name);
137     return result;
138 }
139 
JavaNPObjectGetProperty(NPObject * obj,NPIdentifier identifier,NPVariant * result)140 bool JavaNPObjectGetProperty(NPObject* obj, NPIdentifier identifier, NPVariant* result)
141 {
142     VOID_TO_NPVARIANT(*result);
143     JavaInstance* instance = ExtractJavaInstance(obj);
144     if (!instance)
145         return false;
146     NPUTF8* name = _NPN_UTF8FromIdentifier(identifier);
147     if (!name)
148         return false;
149 
150     instance->begin();
151     JavaField* field = instance->getClass()->fieldNamed(name);
152     instance->end();
153     free(name); // TODO: use NPN_MemFree
154 
155     if (!field)
156         return false;
157 
158 #ifdef EMULATE_JSC_BINDINGS
159     // JSC does not seem to support returning object properties so we emulate that
160     // behaviour here.
161     jvalue value;
162 #else
163     // FIXME: Note here that field->type() refers to the Java class name and NOT the
164     // JNI signature i.e. "int" as opposed to "I". This means that the field lookup
165     // will fail.
166     jvalue value = getJNIField(instance->javaInstance(),
167                                field->getJNIType(),
168                                field->name().UTF8String(),
169                                field->type());
170 #endif
171     convertJValueToNPVariant(value, field->getJNIType(), field->type(), result);
172 
173     return true;
174 }
175 
176 } // namespace Bindings
177 
178 } // namespace JSC
179