<commit_before>/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */

/*
 * This file is part of Seed, the GObject Introspection<->Javascript bindings.
 *
 * Seed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 * Seed 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 Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License
 * along with Seed.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright (C) <NAME> 2009 <<EMAIL>>
 */

#include "seed-private.h"
#include <sys/mman.h>

JSClassRef seed_native_callback_class;

static void
seed_closure_finalize (JSObjectRef object)
{
  SeedNativeClosure *privates =
    (SeedNativeClosure *) JSObjectGetPrivate (object);

  SEED_NOTE (FINALIZATION, "Finalizing closure object %p with "
	     "GIBaseInfo: %s \n", object,
	     g_base_info_get_name ((GIBaseInfo *) privates->info));

  g_free (privates->cif->arg_types);
  g_free (privates->cif);
  g_callable_info_free_closure (privates->info, privates->closure);
  g_base_info_unref ((GIBaseInfo *) privates->info);

  JSValueUnprotect (eng->context, object);
}

static void
seed_handle_closure (ffi_cif * cif, void *result, void **args, void *userdata)
{
  SeedNativeClosure *privates = userdata;
  gint num_args, i;
  JSValueRef *jsargs;
  JSValueRef return_value, exception = 0;
  GITypeTag return_tag;
  GIArgInfo *arg_info;
  GITypeInfo *return_type;
  GITypeInfo *arg_type;
  GITypeTag tag;
  GArgument rarg, return_arg;
  JSContextRef ctx = JSGlobalContextCreateInGroup (context_group, 0);
  GArgument *arg = &rarg;
  gchar *mes;

  seed_prepare_global_context (ctx);

  SEED_NOTE (INVOCATION, "Invoking closure of type: %s \n",
	     g_base_info_get_name ((GIBaseInfo *) privates->info));

  num_args = g_callable_info_get_n_args (privates->info);
  return_type = g_callable_info_get_return_type (privates->info);
  return_tag = g_type_info_get_tag (return_type);
  jsargs = (JSValueRef *) g_newa (JSValueRef, num_args);

  for (i = 0; i < num_args; i++)
    {

      arg_info = g_callable_info_get_arg (privates->info, i);
      arg_type = g_arg_info_get_type (arg_info);
      tag = g_type_info_get_tag (arg_type);

      switch (tag)
	{
	case GI_TYPE_TAG_BOOLEAN:
	  arg->v_boolean = *(gboolean *) args[i];
	  break;
	case GI_TYPE_TAG_INT8:
	  arg->v_int8 = *(gint8 *) args[i];
	  break;
	case GI_TYPE_TAG_UINT8:
	  arg->v_uint8 = *(guint8 *) args[i];
	  break;
	case GI_TYPE_TAG_INT16:
	  arg->v_int16 = *(gint16 *) args[i];
	  break;
	case GI_TYPE_TAG_UINT16:
	  arg->v_uint16 = *(guint16 *) args[i];
	  break;
	case GI_TYPE_TAG_INT32:
	  arg->v_int32 = *(gint32 *) args[i];
	  break;
	case GI_TYPE_TAG_UINT32:
	  arg->v_uint32 = *(guint32 *) args[i];
	  break;
	case GI_TYPE_TAG_LONG:
	  arg->v_long = *(glong *) args[i];
	  break;
	case GI_TYPE_TAG_INT64:
	  arg->v_int64 = *(gint64 *) args[i];
	  break;
	case GI_TYPE_TAG_ULONG:
	  arg->v_ulong = *(gulong *) args[i];
	  break;
	case GI_TYPE_TAG_UINT64:
	  arg->v_uint64 = *(guint64 *) args[i];
	  break;
	case GI_TYPE_TAG_INT:
	  arg->v_int = *(gint *) args[i];
	  break;
	case GI_TYPE_TAG_SSIZE:
	  arg->v_ssize = *(gssize *) args[i];
	  break;
	case GI_TYPE_TAG_SIZE:
	  arg->v_size = *(gsize *) args[i];
	  break;
	case GI_TYPE_TAG_UINT:
	  arg->v_uint = *(guint *) args[i];
	  break;
	case GI_TYPE_TAG_FLOAT:
	  arg->v_float = *(gfloat *) args[i];
	  break;
	case GI_TYPE_TAG_DOUBLE:
	  arg->v_double = *(gdouble *) args[i];
	  break;
	case GI_TYPE_TAG_UTF8:
	  arg->v_string = *(gchar **) args[i];
	  break;
	case GI_TYPE_TAG_INTERFACE:
	  {
	    GIBaseInfo *interface;
	    GIInfoType interface_type;

	    interface = g_type_info_get_interface (arg_type);
	    interface_type = g_base_info_get_type (interface);

	    if (interface_type == GI_INFO_TYPE_OBJECT ||
		interface_type == GI_INFO_TYPE_INTERFACE)
	      {
		arg->v_pointer = *(gpointer *) args[i];
		g_base_info_unref (interface);
		break;
	      }

	    else if (interface_type == GI_INFO_TYPE_ENUM ||
		     interface_type == GI_INFO_TYPE_FLAGS)
	      {
		arg->v_double = *(double *) args[i];
		g_base_info_unref (interface);
		break;
	      }
	    else if (interface_type == GI_INFO_TYPE_STRUCT)
	      {
		arg->v_pointer = *(gpointer *) args[i];
		g_base_info_unref (interface);
		break;
	      }

	    g_base_info_unref (interface);
	  }
	case GI_TYPE_TAG_GLIST:
	case GI_TYPE_TAG_GSLIST:
	  arg->v_pointer = *(gpointer *) args[i];
	  break;
	default:
	  arg->v_pointer = 0;
	}
      jsargs[i] = seed_gi_argument_make_js (ctx, arg, arg_type, 0);
      seed_gi_release_in_arg (g_arg_info_get_ownership_transfer (arg_info),
			      arg_type, arg);
      g_base_info_unref ((GIBaseInfo *) arg_info);
      g_base_info_unref ((GIBaseInfo *) arg_type);
    }

  return_value = (JSValueRef)
    JSObjectCallAsFunction (ctx,
			    (JSObjectRef) privates->function, 0,
			    num_args, jsargs, &exception);

  if (exception)
    {
      mes = seed_exception_to_string (ctx, exception);
      g_warning ("Exception in closure marshal. %s \n", mes);
      g_free (mes);
      exception = 0;
    }

  seed_gi_make_argument (ctx, (JSValueRef) return_value, return_type,
			 &return_arg, 0);<commit_msg>change callback release_in_arg to release_arg otherwise segfaults occur<commit_after>/* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */

/*
 * This file is part of Seed, the GObject Introspection<->Javascript bindings.
 *
 * Seed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 * Seed 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 Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License
 * along with Seed.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright (C) <NAME> 2009 <<EMAIL>>
 */

#include "seed-private.h"
#include <sys/mman.h>

JSClassRef seed_native_callback_class;

static void
seed_closure_finalize (JSObjectRef object)
{
  SeedNativeClosure *privates =
    (SeedNativeClosure *) JSObjectGetPrivate (object);

  SEED_NOTE (FINALIZATION, "Finalizing closure object %p with "
	     "GIBaseInfo: %s \n", object,
	     g_base_info_get_name ((GIBaseInfo *) privates->info));

  g_free (privates->cif->arg_types);
  g_free (privates->cif);
  g_callable_info_free_closure (privates->info, privates->closure);
  g_base_info_unref ((GIBaseInfo *) privates->info);

  JSValueUnprotect (eng->context, object);
}

static void
seed_handle_closure (ffi_cif * cif, void *result, void **args, void *userdata)
{
  SeedNativeClosure *privates = userdata;
  gint num_args, i;
  JSValueRef *jsargs;
  JSValueRef return_value, exception = 0;
  GITypeTag return_tag;
  GIArgInfo *arg_info;
  GITypeInfo *return_type;
  GITypeInfo *arg_type;
  GITypeTag tag;
  GArgument rarg, return_arg;
  JSContextRef ctx = JSGlobalContextCreateInGroup (context_group, 0);
  GArgument *arg = &rarg;
  gchar *mes;

  seed_prepare_global_context (ctx);

  SEED_NOTE (INVOCATION, "Invoking closure of type: %s \n",
	     g_base_info_get_name ((GIBaseInfo *) privates->info));

  num_args = g_callable_info_get_n_args (privates->info);
  return_type = g_callable_info_get_return_type (privates->info);
  return_tag = g_type_info_get_tag (return_type);
  jsargs = (JSValueRef *) g_newa (JSValueRef, num_args);

  for (i = 0; i < num_args; i++)
    {

      arg_info = g_callable_info_get_arg (privates->info, i);
      arg_type = g_arg_info_get_type (arg_info);
      tag = g_type_info_get_tag (arg_type);

      switch (tag)
	{
	case GI_TYPE_TAG_BOOLEAN:
	  arg->v_boolean = *(gboolean *) args[i];
	  break;
	case GI_TYPE_TAG_INT8:
	  arg->v_int8 = *(gint8 *) args[i];
	  break;
	case GI_TYPE_TAG_UINT8:
	  arg->v_uint8 = *(guint8 *) args[i];
	  break;
	case GI_TYPE_TAG_INT16:
	  arg->v_int16 = *(gint16 *) args[i];
	  break;
	case GI_TYPE_TAG_UINT16:
	  arg->v_uint16 = *(guint16 *) args[i];
	  break;
	case GI_TYPE_TAG_INT32:
	  arg->v_int32 = *(gint32 *) args[i];
	  break;
	case GI_TYPE_TAG_UINT32:
	  arg->v_uint32 = *(guint32 *) args[i];
	  break;
	case GI_TYPE_TAG_LONG:
	  arg->v_long = *(glong *) args[i];
	  break;
	case GI_TYPE_TAG_INT64:
	  arg->v_int64 = *(gint64 *) args[i];
	  break;
	case GI_TYPE_TAG_ULONG:
	  arg->v_ulong = *(gulong *) args[i];
	  break;
	case GI_TYPE_TAG_UINT64:
	  arg->v_uint64 = *(guint64 *) args[i];
	  break;
	case GI_TYPE_TAG_INT:
	  arg->v_int = *(gint *) args[i];
	  break;
	case GI_TYPE_TAG_SSIZE:
	  arg->v_ssize = *(gssize *) args[i];
	  break;
	case GI_TYPE_TAG_SIZE:
	  arg->v_size = *(gsize *) args[i];
	  break;
	case GI_TYPE_TAG_UINT:
	  arg->v_uint = *(guint *) args[i];
	  break;
	case GI_TYPE_TAG_FLOAT:
	  arg->v_float = *(gfloat *) args[i];
	  break;
	case GI_TYPE_TAG_DOUBLE:
	  arg->v_double = *(gdouble *) args[i];
	  break;
	case GI_TYPE_TAG_UTF8:
	  arg->v_string = *(gchar **) args[i];
	  break;
	case GI_TYPE_TAG_INTERFACE:
	  {
	    GIBaseInfo *interface;
	    GIInfoType interface_type;

	    interface = g_type_info_get_interface (arg_type);
	    interface_type = g_base_info_get_type (interface);

	    if (interface_type == GI_INFO_TYPE_OBJECT ||
		interface_type == GI_INFO_TYPE_INTERFACE)
	      {
		arg->v_pointer = *(gpointer *) args[i];
		g_base_info_unref (interface);
		break;
	      }

	    else if (interface_type == GI_INFO_TYPE_ENUM ||
		     interface_type == GI_INFO_TYPE_FLAGS)
	      {
		arg->v_double = *(double *) args[i];
		g_base_info_unref (interface);
		break;
	      }
	    else if (interface_type == GI_INFO_TYPE_STRUCT)
	      {
		arg->v_pointer = *(gpointer *) args[i];
		g_base_info_unref (interface);
		break;
	      }

	    g_base_info_unref (interface);
	  }
	case GI_TYPE_TAG_GLIST:
	case GI_TYPE_TAG_GSLIST:
	  arg->v_pointer = *(gpointer *) args[i];
	  break;
	default:
	  arg->v_pointer = 0;
	}
      jsargs[i] = seed_gi_argument_make_js (ctx, arg, arg_type, 0);
      seed_gi_release_arg (g_arg_info_get_ownership_transfer (arg_info),
			      arg_type, arg);
      g_base_info_unref ((GIBaseInfo *) arg_info);
      g_base_info_unref ((GIBaseInfo *) arg_type);
    }

  return_value = (JSValueRef)
    JSObjectCallAsFunction (ctx,
			    (JSObjectRef) privates->function, 0,
			    num_args, jsargs, &exception);

  if (exception)
    {
      mes = seed_exception_to_string (ctx, exception);
      g_warning ("Exception in closure marshal. %s \n", mes);
      g_free (mes);
      exception = 0;
    }

  seed_gi_make_argument (ctx, (JSValueRef) return_value, return_type,
			 &return_arg, 0);
{'fraction_non_alphanumeric': 0.11997493061151401, 'fraction_numerical': 0.010385889515623602, 'mean_word_length': 3.8105081826012057, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3705487', 'n_tokens_mistral': 4453, 'n_tokens_neox': 4125, 'n_words': 956}