Home | History | Annotate | Download | only in v8
      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 
     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 
     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
     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
     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 
     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 
    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 
    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 
    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