blob: aee8bba8069472df583e89258a653450be2fda63 [file] [log] [blame]
/*
Copyright (C) 2011 ProFUSION embedded systems
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "ewk_js.h"
#include <wtf/UnusedParam.h>
#if ENABLE(NETSCAPE_PLUGIN_API)
#include "NP_jsobject.h"
#include "ewk_js_private.h"
#include "ewk_private.h"
#include "npruntime.h"
#include "npruntime_impl.h"
#include <string.h>
#define EINA_MAGIC_CHECK_OR_RETURN(o, ...) \
if (!EINA_MAGIC_CHECK(o, EWK_JS_OBJECT_MAGIC)) { \
EINA_MAGIC_FAIL(o, EWK_JS_OBJECT_MAGIC); \
return __VA_ARGS__; \
}
struct _Ewk_JS_Class {
const Ewk_JS_Class_Meta* meta;
Eina_Hash* methods; // Key=NPIdentifier(name), value=pointer to meta->methods.
Eina_Hash* properties; // Key=NPIdentifier(name), value=pointer to meta->properties.
Ewk_JS_Default default_prop;
};
static Eina_Bool ewk_js_npvariant_to_variant(Ewk_JS_Variant* data, const NPVariant* result);
static Eina_Bool ewk_js_variant_to_npvariant(const Ewk_JS_Variant* data, NPVariant* result)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(data, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(result, false);
const char* string_value;
switch (data->type) {
case EWK_JS_VARIANT_VOID:
VOID_TO_NPVARIANT(*result);
break;
case EWK_JS_VARIANT_NULL:
NULL_TO_NPVARIANT(*result);
break;
case EWK_JS_VARIANT_INT32:
INT32_TO_NPVARIANT(data->value.i, *result);
break;
case EWK_JS_VARIANT_DOUBLE:
DOUBLE_TO_NPVARIANT(data->value.d, *result);
break;
case EWK_JS_VARIANT_STRING:
string_value = eina_stringshare_add(data->value.s);
if (string_value)
STRINGZ_TO_NPVARIANT(string_value, *result);
else
return false;
break;
case EWK_JS_VARIANT_BOOL:
BOOLEAN_TO_NPVARIANT(data->value.b, *result);
break;
case EWK_JS_VARIANT_OBJECT:
OBJECT_TO_NPVARIANT(reinterpret_cast<NPObject*>(data->value.o), *result);
break;
default:
return false;
}
return true;
}
// These methods are used by NPAI, thats the reason to use bool instead of Eina_Bool.
static bool ewk_js_property_has(NPObject* npObject, NPIdentifier name)
{
Ewk_JS_Object* object = reinterpret_cast<Ewk_JS_Object*>(npObject);
EINA_SAFETY_ON_NULL_RETURN_VAL(npObject, false);
EINA_MAGIC_CHECK_OR_RETURN(object, false);
if (!_NPN_IdentifierIsString(name)) {
ERR("int NPIdentifier is not supported.");
return false;
}
char* prop_name = _NPN_UTF8FromIdentifier(name);
bool fail = eina_hash_find(object->properties, prop_name); // FIXME: should search methods too?
free(prop_name);
return fail;
}
static bool ewk_js_property_get(NPObject* npObject, NPIdentifier name, NPVariant* result)
{
Ewk_JS_Object* object = reinterpret_cast<Ewk_JS_Object*>(npObject);
Ewk_JS_Variant* value;
Ewk_JS_Property* prop;
bool fail = false;
EINA_SAFETY_ON_NULL_RETURN_VAL(npObject, false);
EINA_MAGIC_CHECK_OR_RETURN(object, false);
if (!_NPN_IdentifierIsString(name)) {
ERR("int NPIdentifier is not supported.");
return false;
}
value = static_cast<Ewk_JS_Variant*>(malloc(sizeof(Ewk_JS_Variant)));
if (!value) {
ERR("Could not allocate memory for ewk_js_variant");
return false;
}
prop = static_cast<Ewk_JS_Property*>(eina_hash_find(object->cls->properties, name));
if (prop && prop->get) { // Class has property and property has getter.
fail = prop->get(object, prop->name, value);
if (!fail)
fail = ewk_js_variant_to_npvariant(value, result);
} else if (object->cls->default_prop.get) { // Default getter exists.
fail = object->cls->default_prop.get(object, prop->name, value);
if (!fail)
fail = ewk_js_variant_to_npvariant(value, result);
} else { // Fallback to objects hash map.
char* prop_name = _NPN_UTF8FromIdentifier(name);
free(value);
value = static_cast<Ewk_JS_Variant*>(eina_hash_find(object->properties, prop_name));
free(prop_name);
if (value)
return ewk_js_variant_to_npvariant(value, result);
}
free(value);
return fail;
}
static bool ewk_js_property_set(NPObject* npObject, NPIdentifier name, const NPVariant* npValue)
{
Ewk_JS_Object* object = reinterpret_cast<Ewk_JS_Object*>(npObject);
Ewk_JS_Variant* value;
Ewk_JS_Property* prop;
bool fail = false;
EINA_SAFETY_ON_NULL_RETURN_VAL(npObject, false);
EINA_MAGIC_CHECK_OR_RETURN(object, false);
if (!_NPN_IdentifierIsString(name)) {
ERR("int NPIdentifier is not supported.");
return fail;
}
value = static_cast<Ewk_JS_Variant*>(malloc(sizeof(Ewk_JS_Variant)));
if (!value) {
ERR("Could not allocate memory for ewk_js_variant");
return false;
}
ewk_js_npvariant_to_variant(value, npValue);
char* prop_name = _NPN_UTF8FromIdentifier(name);
prop = static_cast<Ewk_JS_Property*>(eina_hash_find(object->cls->properties, prop_name));
if (prop && prop->set)
fail = prop->set(object, prop->name, value); // Class has property and property has setter.
else if (object->cls->default_prop.set)
fail = object->cls->default_prop.set(object, prop_name, value); // Default getter exists.
else { // Fallback to objects hash map.
void* old = eina_hash_set(object->properties, prop_name, value);
free(old);
fail = true;
}
free(prop_name);
return fail;
}
static bool ewk_js_property_remove(NPObject* npObject, NPIdentifier name)
{
Ewk_JS_Object* object = reinterpret_cast<Ewk_JS_Object*>(npObject);
Ewk_JS_Property* prop;
bool fail = false;
EINA_SAFETY_ON_NULL_RETURN_VAL(npObject, false);
EINA_MAGIC_CHECK_OR_RETURN(object, false);
if (!_NPN_IdentifierIsString(name)) {
ERR("int NPIdentifier is not supported.");
return fail;
}
char* prop_name = _NPN_UTF8FromIdentifier(name);
prop = static_cast<Ewk_JS_Property*>(eina_hash_find(object->cls->properties, prop_name));
if (prop && prop->del)
fail = prop->del(object, prop->name); // Class has property and property has getter.
else if (object->cls->default_prop.del)
fail = object->cls->default_prop.del(object, prop_name);
else
fail = eina_hash_del(object->properties, prop_name, 0);
free(prop_name);
return fail;
}
static bool ewk_js_properties_enumerate(NPObject* npObject, NPIdentifier** value, uint32_t* count)
{
Ewk_JS_Object* object = reinterpret_cast<Ewk_JS_Object*>(npObject);
Eina_Iterator* it;
char* key;
int i = 0;
EINA_SAFETY_ON_NULL_RETURN_VAL(npObject, false);
EINA_MAGIC_CHECK_OR_RETURN(object, false);
*count = eina_hash_population(object->properties);
*value = static_cast<NPIdentifier*>(malloc(sizeof(NPIdentifier) * *count));
if (!*value) {
ERR("Could not allocate memory for NPIdentifier");
return false;
}
it = eina_hash_iterator_key_new(object->properties);
EINA_ITERATOR_FOREACH(it, key)
(*value)[i++] = _NPN_GetStringIdentifier(key);
eina_iterator_free(it);
return true;
}
static bool ewk_js_method_has(NPObject* npObject, NPIdentifier name)
{
Ewk_JS_Object* object = reinterpret_cast<Ewk_JS_Object*>(npObject);
EINA_SAFETY_ON_NULL_RETURN_VAL(npObject, false);
EINA_MAGIC_CHECK_OR_RETURN(object, false);
if (!_NPN_IdentifierIsString(name)) {
ERR("int NPIdentifier is not supported.");
return false;
}
return eina_hash_find(object->cls->methods, name); // Returns pointer if found(true), 0(false) otherwise.
}
static bool ewk_js_method_invoke(NPObject* npObject, NPIdentifier name, const NPVariant* npArgs, uint32_t npArgCount, NPVariant* result)
{
Ewk_JS_Object* object = reinterpret_cast<Ewk_JS_Object*>(npObject);
Ewk_JS_Method* method;
Ewk_JS_Variant* args;
Ewk_JS_Variant* ret_val;
EINA_SAFETY_ON_NULL_RETURN_VAL(npObject, false);
EINA_MAGIC_CHECK_OR_RETURN(object, false);
if (!_NPN_IdentifierIsString(name)) {
ERR("int NPIdentifier is not supported.");
return false;
}
method = static_cast<Ewk_JS_Method*>(eina_hash_find(object->cls->methods, name));
if (!method)
return false;
args = static_cast<Ewk_JS_Variant*>(malloc(sizeof(Ewk_JS_Variant) *npArgCount));
if (!args) {
ERR("Could not allocate memory for ewk_js_variant");
return false;
}
for (uint32_t i = 0; i < npArgCount; i++)
ewk_js_npvariant_to_variant(&args[i], &npArgs[i]);
ret_val = method->invoke(object, args, npArgCount);
ewk_js_variant_to_npvariant(ret_val, result);
ewk_js_variant_free(ret_val);
return true;
}
static Eina_Bool ewk_js_npobject_property_get(Ewk_JS_Object* jsObject, const char* name, Ewk_JS_Variant* value)
{
NPIdentifier id = _NPN_GetStringIdentifier(name);
NPVariant var;
bool fail = _NPN_GetProperty(0, reinterpret_cast<NPObject*>(jsObject), id, &var);
if (!fail)
fail = ewk_js_npvariant_to_variant(value, &var);
return fail;
}
static Eina_Bool ewk_js_npobject_property_set(Ewk_JS_Object* jsObject, const char* name, const Ewk_JS_Variant* value)
{
NPIdentifier id = _NPN_GetStringIdentifier(name);
NPVariant var;
bool fail = ewk_js_variant_to_npvariant(value, &var);
if (fail)
fail = _NPN_SetProperty(0, reinterpret_cast<NPObject*>(jsObject), id, &var);
return fail;
}
static Eina_Bool ewk_js_npobject_property_del(Ewk_JS_Object* jsObject, const char* name)
{
NPIdentifier id = _NPN_GetStringIdentifier(name);
return _NPN_RemoveProperty(0, reinterpret_cast<NPObject*>(jsObject), id);
}
static void ewk_js_property_free(Ewk_JS_Property* prop)
{
free(const_cast<char*>(prop->name));
if (prop->value.type == EWK_JS_VARIANT_STRING)
eina_stringshare_del(prop->value.value.s);
else if (prop->value.type == EWK_JS_VARIANT_OBJECT)
ewk_js_object_free(prop->value.value.o);
free(prop);
}
/**
* Create a Ewk_JS_Class to be used in @a ewk_js_object_new.
*
* @param meta @a Ewk_JS_Class_Meta that describes the class to be created.
*
* @return The Ewk_JS_Class created.
*/
Ewk_JS_Class* ewk_js_class_new(const Ewk_JS_Class_Meta* jsMetaClass)
{
Ewk_JS_Class* cls;
EINA_SAFETY_ON_NULL_RETURN_VAL(jsMetaClass, 0);
cls = static_cast<Ewk_JS_Class*>(malloc(sizeof(Ewk_JS_Class)));
if (!cls) {
ERR("Could not allocate memory for ewk_js_class");
return 0;
}
cls->meta = jsMetaClass;
cls->default_prop = cls->meta->default_prop;
// Don't free methods since they point to meta class methods(will be freed when meta class is freed).
cls->methods = eina_hash_pointer_new(0);
for (int i = 0; cls->meta->methods && cls->meta->methods[i].name; i++) {
NPIdentifier id = _NPN_GetStringIdentifier(cls->meta->methods[i].name);
eina_hash_add(cls->methods, id, &cls->meta->methods[i]);
}
// Don't free properties since they point to cls->meta class properties(will be freed when cls->meta class is freed).
cls->properties = eina_hash_pointer_new(0);
for (int i = 0; cls->meta->properties && cls->meta->properties[i].name; i++) {
NPIdentifier id = _NPN_GetStringIdentifier(cls->meta->properties[i].name);
eina_hash_add(cls->properties, id, &cls->meta->properties[i]);
}
return cls;
}
/**
* Release resources allocated by @a cls.
*
* @param cls @a Ewk_JS_Class to be released.
*/
void ewk_js_class_free(Ewk_JS_Class* jsClass)
{
EINA_SAFETY_ON_NULL_RETURN(jsClass);
eina_hash_free(jsClass->methods);
eina_hash_free(jsClass->properties);
free(jsClass);
}
static NPClass EWK_NPCLASS = {
NP_CLASS_STRUCT_VERSION,
0, // NPAllocateFunctionPtr
0, // NPDeallocateFunctionPtr
0, // NPInvalidateFunctionPtr
ewk_js_method_has, // NPHasMethodFunctionPtr
ewk_js_method_invoke, // NPInvokeFunctionPtr
0, // NPInvokeDefaultFunctionPtr
ewk_js_property_has, // NPHasPropertyFunctionPtr
ewk_js_property_get, // NPGetPropertyFunctionPtr
ewk_js_property_set, // NPSetPropertyFunctionPtr
ewk_js_property_remove, // NPRemovePropertyFunctionPtr
ewk_js_properties_enumerate, // NPEnumerationFunctionPtr
0 // NPConstructFunction
};
static Ewk_JS_Object* ewk_js_npobject_to_object(NPObject* npObject)
{
NPIdentifier* values;
uint32_t np_props_count;
Ewk_JS_Class* cls;
Ewk_JS_Object* object;
Eina_Iterator* it;
Ewk_JS_Property* prop;
JavaScriptObject* jso;
if (EINA_MAGIC_CHECK(reinterpret_cast<Ewk_JS_Object*>(npObject), EWK_JS_OBJECT_MAGIC))
return reinterpret_cast<Ewk_JS_Object*>(npObject);
if (!_NPN_Enumerate(0, npObject, &values, &np_props_count))
return 0;
cls = static_cast<Ewk_JS_Class*>(malloc(sizeof(Ewk_JS_Class)));
if (!cls) {
ERR("Could not allocate memory for ewk_js_class");
return 0;
}
cls->meta = 0;
Ewk_JS_Default def = {
ewk_js_npobject_property_set,
ewk_js_npobject_property_get,
ewk_js_npobject_property_del
};
cls->default_prop = def;
cls->methods = eina_hash_pointer_new(0);
cls->properties = eina_hash_pointer_new(reinterpret_cast<Eina_Free_Cb>(ewk_js_property_free));
for (uint32_t i = 0; i < np_props_count; i++) {
if (_NPN_HasProperty(0, npObject, values[i])) {
NPVariant var;
Ewk_JS_Property* prop = static_cast<Ewk_JS_Property*>(calloc(sizeof(Ewk_JS_Property), 1));
if (!prop) {
ERR("Could not allocate memory for ewk_js_property");
goto error;
}
_NPN_GetProperty(0, npObject, values[i], &var);
ewk_js_npvariant_to_variant(&(prop->value), &var);
prop->name = _NPN_UTF8FromIdentifier(values[i]);
eina_hash_add(cls->properties, values[i], prop);
}
}
// Can't use ewk_js_object_new(cls) because it expects cls->meta to exist.
object = static_cast<Ewk_JS_Object*>(malloc(sizeof(Ewk_JS_Object)));
if (!object) {
ERR("Could not allocate memory for ewk_js_object");
goto error;
}
free(values);
EINA_MAGIC_SET(object, EWK_JS_OBJECT_MAGIC);
object->name = 0;
object->cls = cls;
object->view = 0;
jso = reinterpret_cast<JavaScriptObject*>(npObject);
if (!strcmp("Array", jso->imp->methodTable()->className(jso->imp).ascii().data()))
object->type = EWK_JS_OBJECT_ARRAY;
else if (!strcmp("Function", jso->imp->methodTable()->className(jso->imp).ascii().data()))
object->type = EWK_JS_OBJECT_FUNCTION;
else
object->type = EWK_JS_OBJECT_OBJECT;
if (eina_hash_population(cls->properties) < 25)
object->properties = eina_hash_string_small_new(0);
else
object->properties = eina_hash_string_superfast_new(0);
it = eina_hash_iterator_data_new(cls->properties);
EINA_ITERATOR_FOREACH(it, prop) {
const char* key = prop->name;
Ewk_JS_Variant* value = &prop->value;
eina_hash_add(object->properties, key, value);
}
eina_iterator_free(it);
object->base = *reinterpret_cast<JavaScriptObject*>(npObject);
return object;
error:
ewk_js_class_free(cls);
free(values);
return 0;
}
static Eina_Bool ewk_js_npvariant_to_variant(Ewk_JS_Variant* data, const NPVariant* result)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(data, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(result, false);
switch (result->type) {
case NPVariantType_Void:
data->type = EWK_JS_VARIANT_VOID;
data->value.o = 0;
break;
case NPVariantType_Null:
data->type = EWK_JS_VARIANT_NULL;
data->value.o = 0;
break;
case NPVariantType_Int32:
data->type = EWK_JS_VARIANT_INT32;
data->value.i = NPVARIANT_TO_INT32(*result);
break;
case NPVariantType_Double:
data->type = EWK_JS_VARIANT_DOUBLE;
data->value.d = NPVARIANT_TO_DOUBLE(*result);
break;
case NPVariantType_String:
data->value.s = eina_stringshare_add_length(NPVARIANT_TO_STRING(*result).UTF8Characters, NPVARIANT_TO_STRING(*result).UTF8Length);
data->type = EWK_JS_VARIANT_STRING;
break;
case NPVariantType_Bool:
data->type = EWK_JS_VARIANT_BOOL;
data->value.b = NPVARIANT_TO_BOOLEAN(*result);
break;
case NPVariantType_Object:
data->type = EWK_JS_VARIANT_OBJECT;
data->value.o = ewk_js_npobject_to_object(NPVARIANT_TO_OBJECT(*result));
break;
default:
return false;
}
return true;
}
#endif // ENABLE(NETSCAPE_PLUGIN_API)
Ewk_JS_Object* ewk_js_object_new(const Ewk_JS_Class_Meta* jsMetaClass)
{
#if ENABLE(NETSCAPE_PLUGIN_API)
Ewk_JS_Object* object;
EINA_SAFETY_ON_NULL_RETURN_VAL(jsMetaClass, 0);
object = static_cast<Ewk_JS_Object*>(malloc(sizeof(Ewk_JS_Object)));
if (!object) {
ERR("Could not allocate memory for ewk_js_object");
return 0;
}
EINA_MAGIC_SET(object, EWK_JS_OBJECT_MAGIC);
object->cls = ewk_js_class_new(jsMetaClass);
object->view = 0;
object->name = 0;
object->type = EWK_JS_OBJECT_OBJECT;
if (eina_hash_population(object->cls->properties) < 25)
object->properties = eina_hash_string_small_new(reinterpret_cast<Eina_Free_Cb>(ewk_js_variant_free));
else
object->properties = eina_hash_string_superfast_new(reinterpret_cast<Eina_Free_Cb>(ewk_js_variant_free));
for (int i = 0; object->cls->meta->properties && object->cls->meta->properties[i].name; i++) {
Ewk_JS_Property prop = object->cls->meta->properties[i];
const char* key = object->cls->meta->properties[i].name;
Ewk_JS_Variant* value = static_cast<Ewk_JS_Variant*>(malloc(sizeof(Ewk_JS_Variant)));
if (!value) {
ERR("Could not allocate memory for ewk_js_variant");
goto error;
}
if (prop.get)
prop.get(object, key, value);
else {
value->type = prop.value.type;
switch (value->type) {
case EWK_JS_VARIANT_VOID:
case EWK_JS_VARIANT_NULL:
value->value.o = 0;
break;
case EWK_JS_VARIANT_STRING:
value->value.s = eina_stringshare_add(prop.value.value.s);
break;
case EWK_JS_VARIANT_BOOL:
value->value.b = prop.value.value.b;
break;
case EWK_JS_VARIANT_INT32:
value->value.i = prop.value.value.i;
break;
case EWK_JS_VARIANT_DOUBLE:
value->value.d = prop.value.value.d;
break;
case EWK_JS_VARIANT_OBJECT:
value->value.o = prop.value.value.o;
break;
}
}
eina_hash_add(object->properties, key, value);
}
object->base.object.referenceCount = 1;
object->base.object._class = &EWK_NPCLASS;
return object;
error:
ewk_js_object_free(object);
return 0;
#else
UNUSED_PARAM(jsMetaClass);
return 0;
#endif
}
void ewk_js_object_free(Ewk_JS_Object* jsObject)
{
#if ENABLE(NETSCAPE_PLUGIN_API)
EINA_SAFETY_ON_NULL_RETURN(jsObject);
EINA_MAGIC_CHECK_OR_RETURN(jsObject);
Eina_Bool script_obj = !jsObject->cls->meta;
eina_hash_free(jsObject->properties);
eina_stringshare_del(jsObject->name);
ewk_js_class_free(const_cast<Ewk_JS_Class*>(jsObject->cls));
EINA_MAGIC_SET(jsObject, EINA_MAGIC_NONE);
if (script_obj)
free(jsObject);
#else
UNUSED_PARAM(jsObject);
#endif
}
Evas_Object* ewk_js_object_view_get(const Ewk_JS_Object* jsObject)
{
#if ENABLE(NETSCAPE_PLUGIN_API)
EINA_SAFETY_ON_NULL_RETURN_VAL(jsObject, 0);
EINA_MAGIC_CHECK_OR_RETURN(jsObject, 0);
return jsObject->view;
#else
UNUSED_PARAM(jsObject);
return 0;
#endif
}
Eina_Hash* ewk_js_object_properties_get(const Ewk_JS_Object* jsObject)
{
#if ENABLE(NETSCAPE_PLUGIN_API)
EINA_SAFETY_ON_NULL_RETURN_VAL(jsObject, 0);
EINA_MAGIC_CHECK_OR_RETURN(jsObject, 0);
return jsObject->properties;
#else
UNUSED_PARAM(jsObject);
return 0;
#endif
}
const char* ewk_js_object_name_get(const Ewk_JS_Object* jsObject)
{
#if ENABLE(NETSCAPE_PLUGIN_API)
EINA_SAFETY_ON_NULL_RETURN_VAL(jsObject, 0);
EINA_MAGIC_CHECK_OR_RETURN(jsObject, 0);
return jsObject->name;
#else
UNUSED_PARAM(jsObject);
return 0;
#endif
}
Eina_Bool ewk_js_object_invoke(Ewk_JS_Object* jsObject, Ewk_JS_Variant* args, int argCount, Ewk_JS_Variant* result)
{
#if ENABLE(NETSCAPE_PLUGIN_API)
NPVariant* np_args;
NPVariant np_result;
bool fail = false;
EINA_MAGIC_CHECK_OR_RETURN(jsObject, false);
if (ewk_js_object_type_get(jsObject) != EWK_JS_OBJECT_FUNCTION)
return false;
if (argCount)
EINA_SAFETY_ON_NULL_RETURN_VAL(args, false);
np_args = static_cast<NPVariant*>(malloc(sizeof(NPVariant) *argCount));
if (!np_args) {
ERR("Could not allocate memory to method arguments");
return false;
}
for (int i = 0; i < argCount; i++)
if (!ewk_js_variant_to_npvariant(&args[i], &np_args[i]))
goto end;
if (!(fail = _NPN_InvokeDefault(0, reinterpret_cast<NPObject*>(jsObject), np_args, argCount, &np_result)))
goto end;
if (result)
fail = ewk_js_npvariant_to_variant(result, &np_result);
end:
free(np_args);
return fail;
#else
UNUSED_PARAM(jsObject);
UNUSED_PARAM(args);
UNUSED_PARAM(argCount);
UNUSED_PARAM(result);
return false;
#endif
}
Ewk_JS_Object_Type ewk_js_object_type_get(Ewk_JS_Object* jsObject)
{
#if ENABLE(NETSCAPE_PLUGIN_API)
EINA_SAFETY_ON_NULL_RETURN_VAL(jsObject, EWK_JS_OBJECT_OBJECT);
EINA_MAGIC_CHECK_OR_RETURN(jsObject, EWK_JS_OBJECT_OBJECT);
return jsObject->type;
#else
UNUSED_PARAM(jsObject);
return EWK_JS_OBJECT_INVALID;
#endif
}
void ewk_js_object_type_set(Ewk_JS_Object* jsObject, Ewk_JS_Object_Type type)
{
#if ENABLE(NETSCAPE_PLUGIN_API)
EINA_SAFETY_ON_NULL_RETURN(jsObject);
EINA_MAGIC_CHECK_OR_RETURN(jsObject);
jsObject->type = type;
#else
UNUSED_PARAM(jsObject);
UNUSED_PARAM(type);
#endif
}
void ewk_js_variant_free(Ewk_JS_Variant* jsVariant)
{
#if ENABLE(NETSCAPE_PLUGIN_API)
EINA_SAFETY_ON_NULL_RETURN(jsVariant);
if (jsVariant->type == EWK_JS_VARIANT_STRING)
eina_stringshare_del(jsVariant->value.s);
else if (jsVariant->type == EWK_JS_VARIANT_OBJECT)
ewk_js_object_free(jsVariant->value.o);
free(jsVariant);
#else
UNUSED_PARAM(jsVariant);
#endif
}
void ewk_js_variant_array_free(Ewk_JS_Variant* jsVariant, int count)
{
#if ENABLE(NETSCAPE_PLUGIN_API)
EINA_SAFETY_ON_NULL_RETURN(jsVariant);
for (int i = 0; i < count; i++) {
if (jsVariant[i].type == EWK_JS_VARIANT_STRING)
eina_stringshare_del(jsVariant[i].value.s);
else if (jsVariant[i].type == EWK_JS_VARIANT_OBJECT)
ewk_js_object_free(jsVariant[i].value.o);
}
free(jsVariant);
#else
UNUSED_PARAM(jsVariant);
UNUSED_PARAM(count);
#endif
}