/* ---------------------------------------------------------------------------
 * These typedefs and defines are used to deal with v8 API changes
 *
 * Useful table of versions: https://nodejs.org/en/download/releases/
 * ---------------------------------------------------------------------------*/

#define SWIGV8_STRING_NEW2(cstr, len) (v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), cstr, v8::NewStringType::kNormal, len)).ToLocalChecked()

typedef void SwigV8ReturnValue;
typedef v8::FunctionCallbackInfo<v8::Value> SwigV8Arguments;
typedef v8::PropertyCallbackInfo<v8::Value> SwigV8PropertyCallbackInfo;
#define SWIGV8_RETURN(val) args.GetReturnValue().Set(val); return
#define SWIGV8_RETURN_INFO(val, info) info.GetReturnValue().Set(val); return

/* The object a wrapped method or accessor was invoked on.
 *
 * v8 12.6 deprecated FunctionCallbackInfo::Holder() and 13.5 removed it.  This() has
 * always been available and is what v8 says to use instead, so no version check is needed.
 *
 * For PropertyCallbackInfo, v8 12.7 added HolderV2(), 14.4 removed Holder() and 14.6
 * removed This() too, leaving HolderV2() as the only way to get at the receiver.
 */
#define SWIGV8_ARGS_THIS(args) (args).This()
#if (SWIG_V8_VERSION < 0x1207)
#define SWIGV8_INFO_HOLDER(info) (info).Holder()
#else
#define SWIGV8_INFO_HOLDER(info) (info).HolderV2()
#endif

#define SWIGV8_HANDLESCOPE() v8::HandleScope scope(v8::Isolate::GetCurrent());
#define SWIGV8_HANDLESCOPE_ESC() v8::EscapableHandleScope scope(v8::Isolate::GetCurrent());
#define SWIGV8_ESCAPE(val) return scope.Escape(val)

#define SWIGV8_ADJUST_MEMORY(size) v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(size)
#define SWIGV8_CURRENT_CONTEXT() v8::Isolate::GetCurrent()->GetCurrentContext()
#define SWIGV8_THROW_EXCEPTION(err) v8::Isolate::GetCurrent()->ThrowException(err)

#define SWIGV8_STRING_NEW(str) (v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), str, v8::NewStringType::kNormal)).ToLocalChecked()
#define SWIGV8_SYMBOL_NEW(sym) (v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sym, v8::NewStringType::kNormal)).ToLocalChecked()

#define SWIGV8_MAYBE_CHECK(maybe) maybe.Check()

#define SWIGV8_ARRAY_NEW(size) v8::Array::New(v8::Isolate::GetCurrent(), size)
#define SWIGV8_BOOLEAN_NEW(bool) v8::Boolean::New(v8::Isolate::GetCurrent(), bool)
/* v8 14.3 added a type tag to v8::External and deprecated the versions without one */
#if (SWIG_V8_VERSION < 0x1403)
#define SWIGV8_EXTERNAL_NEW(val) v8::External::New(v8::Isolate::GetCurrent(), val)
#define SWIGV8_EXTERNAL_VALUE(handle) (handle)->Value()
#else
#define SWIGV8_EXTERNAL_NEW(val) v8::External::New(v8::Isolate::GetCurrent(), val, v8::kExternalPointerTypeTagDefault)
#define SWIGV8_EXTERNAL_VALUE(handle) (handle)->Value(v8::kExternalPointerTypeTagDefault)
#endif
#define SWIGV8_FUNCTEMPLATE_NEW(func) v8::FunctionTemplate::New(v8::Isolate::GetCurrent(), func)
#define SWIGV8_FUNCTEMPLATE_NEW_VOID() v8::FunctionTemplate::New(v8::Isolate::GetCurrent())
#define SWIGV8_INT32_NEW(num) v8::Int32::New(v8::Isolate::GetCurrent(), num)
#define SWIGV8_INTEGER_NEW(num) v8::Integer::New(v8::Isolate::GetCurrent(), num)
#define SWIGV8_INTEGER_NEW_UNS(num) v8::Integer::NewFromUnsigned(v8::Isolate::GetCurrent(), num)
#define SWIGV8_NUMBER_NEW(num) v8::Number::New(v8::Isolate::GetCurrent(), num)
#define SWIGV8_OBJECT_NEW() v8::Object::New(v8::Isolate::GetCurrent())
#define SWIGV8_UNDEFINED() v8::Undefined(v8::Isolate::GetCurrent())
#define SWIGV8_ARRAY v8::Local<v8::Array>
#define SWIGV8_FUNCTION_TEMPLATE v8::Local<v8::FunctionTemplate>
#define SWIGV8_OBJECT v8::Local<v8::Object>
#define SWIGV8_OBJECT_TEMPLATE v8::Local<v8::ObjectTemplate>
#define SWIGV8_OBJECT_TEMPLATE_NEW() v8::ObjectTemplate::New(v8::Isolate::GetCurrent())
#define SWIGV8_VALUE v8::Local<v8::Value>
#define SWIGV8_NULL() v8::Null(v8::Isolate::GetCurrent())
#define SWIGV8_ARRAY_GET(array, index) (array)->Get(SWIGV8_CURRENT_CONTEXT(), index).ToLocalChecked()
#define SWIGV8_ARRAY_SET(array, index, value) SWIGV8_MAYBE_CHECK((array)->Set(SWIGV8_CURRENT_CONTEXT(), index, value))

/* v8 14.2 removed the aligned internal field pointer accessors that take no
 * EmbedderDataTypeTag, having added the tagged versions in 14.1.  Only the tagged setter
 * exists in 14.1, so the switch is made at 14.2 when both are available.
 *
 * The tag passed when setting must match the tag passed when getting, so the default tag
 * is used - a SWIG specific tag would stop a module wrapped by an older SWIG from being
 * read by one wrapped by a newer SWIG.
 */
#if (SWIG_V8_VERSION < 0x1402)
#define SWIGV8_ALIGNED_POINTER_GET(obj, index) (obj)->GetAlignedPointerFromInternalField(index)
#define SWIGV8_ALIGNED_POINTER_SET(obj, index, ptr) (obj)->SetAlignedPointerInInternalField(index, ptr)
#else
#define SWIGV8_ALIGNED_POINTER_GET(obj, index) (obj)->GetAlignedPointerFromInternalField(index, v8::kEmbedderDataTypeTagDefault)
#define SWIGV8_ALIGNED_POINTER_SET(obj, index, ptr) (obj)->SetAlignedPointerInInternalField(index, ptr, v8::kEmbedderDataTypeTagDefault)
#endif

#define SWIGV8_SET_CLASS_TEMPL(class_templ, class) class_templ.Reset(v8::Isolate::GetCurrent(), class);

#define SWIGV8_TO_OBJECT(handle) (handle)->ToObject(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked()
#define SWIGV8_TO_STRING(handle) (handle)->ToString(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked()
#define SWIGV8_NUMBER_VALUE(handle) (handle)->NumberValue(SWIGV8_CURRENT_CONTEXT()).ToChecked()
#define SWIGV8_INTEGER_VALUE(handle) (handle)->IntegerValue(SWIGV8_CURRENT_CONTEXT()).ToChecked()
/* v8 13.3 added Utf8LengthV2/WriteUtf8V2 and deprecated Utf8Length/WriteUtf8, which
 * 14.4 then removed.  The V2 versions are used as soon as they are available as the
 * deprecation warning is an error when compiling with -Werror.
 *
 * SWIGV8_UTF8_LENGTH is the number of bytes needed to encode the string, excluding the
 * terminating NUL.  SWIGV8_WRITE_UTF8's 'len' is the full size of the buffer, including
 * room for the NUL; it always NUL terminates and returns the number of bytes written,
 * including the NUL.
 */
#if (SWIG_V8_VERSION < 0x1303)
#define SWIGV8_WRITE_UTF8(handle, buffer, len) ((size_t)(handle)->WriteUtf8(v8::Isolate::GetCurrent(), buffer, (int)(len)))
#define SWIGV8_UTF8_LENGTH(handle) ((size_t)(handle)->Utf8Length(v8::Isolate::GetCurrent()))
#else
#define SWIGV8_WRITE_UTF8(handle, buffer, len) (handle)->WriteUtf8V2(v8::Isolate::GetCurrent(), buffer, len, v8::String::WriteFlags::kNullTerminate)
#define SWIGV8_UTF8_LENGTH(handle) (handle)->Utf8LengthV2(v8::Isolate::GetCurrent())
#endif
#define SWIGV8_OBJECT_TEMPLATE_INSTACE(tmpl) tmpl->NewInstance(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked();
#define SWIGV8_BOOLEAN_VALUE(handle) (handle)->BooleanValue(v8::Isolate::GetCurrent())

/* ---------------------------------------------------------------------------
 * Error handling
 *
 * ---------------------------------------------------------------------------*/

#define SWIG_Error(code, msg)     SWIGV8_ErrorHandler.error(code, msg)
#define SWIG_fail                 goto fail
#define SWIGV8_OVERLOAD false

SWIGINTERN void SWIG_V8_Raise(const char *msg) {
  SWIGV8_THROW_EXCEPTION(v8::Exception::Error(SWIGV8_STRING_NEW(msg)));
}

SWIGINTERN void SWIG_V8_Raise(SWIGV8_VALUE obj, const char *msg) {
  SWIGV8_THROW_EXCEPTION(v8::Exception::Error(SWIGV8_TO_STRING(obj)));
}


/*
  Note: There are two contexts for handling errors.
  A static V8ErrorHandler is used in not overloaded methods.
  For overloaded methods the throwing type checking mechanism is used
  during dispatching. As V8 exceptions can not be reset properly
  the trick is to use a dynamic ErrorHandler with same local name as the global
  one.

  - See definition of SWIG_Error above.
  - See code templates 'JS_function_dispatcher', 'JS_functionwrapper_overload',
    and 'JS_function_dispatch_case' in javascriptcode.swg

*/
class V8ErrorHandler {
public:
  virtual ~V8ErrorHandler() {}
  virtual void error(int code, const char *msg) {
    SWIG_V8_Raise(msg);
  }
};
// this is used in usually
SWIGRUNTIME V8ErrorHandler SWIGV8_ErrorHandler;

// instances of this are used in overloaded functions
class OverloadErrorHandler: public V8ErrorHandler {
public:
  virtual void error(int code, const char *msg) {
    err = v8::Exception::Error(SWIGV8_STRING_NEW(msg));
    if(code != SWIG_TypeError) {
        SWIGV8_THROW_EXCEPTION(err);
    }
  }
  SWIGV8_VALUE err;
};

/* ---------------------------------------------------------------------------
 * Basic Proxy object
 *
 * ---------------------------------------------------------------------------*/

// Note: to trigger the v8 gc more often one can tell v8 about the memory consumption
// TODO: we could add a v8 specific parameter to control this value
#define SWIGV8_AVG_OBJ_SIZE 1000

class SWIGV8_Proxy {
public:
  SWIGV8_Proxy(): swigCMemOwn(false), swigCObject(0), info(0) {
    SWIGV8_ADJUST_MEMORY(SWIGV8_AVG_OBJ_SIZE);
  }

  ~SWIGV8_Proxy() {
    handle.ClearWeak();
    handle.Reset();

    SWIGV8_ADJUST_MEMORY(-SWIGV8_AVG_OBJ_SIZE);
  }

  bool swigCMemOwn;
  void *swigCObject;
  swig_type_info *info;
  v8::Persistent<v8::Object> handle;
};

class SWIGV8_ClientData {
public:
  v8::Persistent<v8::FunctionTemplate> class_templ;

  void (*dtor) (const v8::WeakCallbackInfo<SWIGV8_Proxy> &data);
};

SWIGRUNTIME v8::Persistent<v8::FunctionTemplate> SWIGV8_SWIGTYPE_Proxy_class_templ;

SWIGRUNTIME int SWIG_V8_ConvertInstancePtr(SWIGV8_OBJECT objRef, void **ptr, swig_type_info *info, int flags) {
  SWIGV8_HANDLESCOPE();

  if(objRef->InternalFieldCount() < 1) return SWIG_ERROR;

  SWIGV8_Proxy *cdata = static_cast<SWIGV8_Proxy *>(SWIGV8_ALIGNED_POINTER_GET(objRef, 0));

  if(cdata == NULL) {
    return SWIG_ERROR;
  }
  if(info && cdata->info != info) {
    swig_cast_info *tc = SWIG_TypeCheckStruct(cdata->info, info);
    if (!tc && cdata->info->name) {
      tc = SWIG_TypeCheck(cdata->info->name, info);
    }
    bool type_valid = tc != 0;
    if(!type_valid) {
      return SWIG_TypeError;
    }
    int newmemory = 0;
    *ptr = SWIG_TypeCast(tc, cdata->swigCObject, &newmemory);
    assert(!newmemory); /* newmemory handling not yet implemented */
  } else {
    *ptr = cdata->swigCObject;
  }

  if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !cdata->swigCMemOwn) {
    return SWIG_ERROR_RELEASE_NOT_OWNED;
  } else {
    if (flags & SWIG_POINTER_DISOWN) {
      cdata->swigCMemOwn = false;
    }
    if (flags & SWIG_POINTER_CLEAR) {
      cdata->swigCObject = 0;
    }
  }
  return SWIG_OK;
}


SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(const v8::WeakCallbackInfo<SWIGV8_Proxy> &data) {
  SWIGV8_Proxy *proxy = data.GetParameter();
  delete proxy;
}

SWIGRUNTIME int SWIG_V8_GetInstancePtr(SWIGV8_VALUE valRef, void **ptr) {
  if(!valRef->IsObject()) {
    return SWIG_TypeError;
  }
  SWIGV8_OBJECT objRef = SWIGV8_OBJECT::Cast(valRef);

  if(objRef->InternalFieldCount() < 1) return SWIG_ERROR;

  SWIGV8_Proxy *cdata = static_cast<SWIGV8_Proxy *>(SWIGV8_ALIGNED_POINTER_GET(objRef, 0));

  if(cdata == NULL) {
    return SWIG_ERROR;
  }

  *ptr = cdata->swigCObject;

  return SWIG_OK;
}

SWIGRUNTIME void SWIGV8_SetPrivateData(SWIGV8_OBJECT obj, void *ptr, swig_type_info *info, int flags) {
  SWIGV8_Proxy *cdata = new SWIGV8_Proxy();
  cdata->swigCObject = ptr;
  cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0;
  cdata->info = info;

  SWIGV8_ALIGNED_POINTER_SET(obj, 0, cdata);

  cdata->handle.Reset(v8::Isolate::GetCurrent(), obj);

  if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) {
    cdata->handle.SetWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor, v8::WeakCallbackType::kParameter);
  } else {
    cdata->handle.SetWeak(cdata, SWIGV8_Proxy_DefaultDtor, v8::WeakCallbackType::kParameter);
  }
}

SWIGRUNTIME int SWIG_V8_ConvertPtr(SWIGV8_VALUE valRef, void **ptr, swig_type_info *info, int flags) {
  SWIGV8_HANDLESCOPE();
  
  /* special case: JavaScript null => C NULL pointer */
  if(valRef->IsNull()) {
    *ptr=0;
    return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
  }
  if(!valRef->IsObject()) {
    return SWIG_TypeError;
  }
  SWIGV8_OBJECT objRef = SWIGV8_OBJECT::Cast(valRef);
  return SWIG_V8_ConvertInstancePtr(objRef, ptr, info, flags);
}

SWIGRUNTIME SWIGV8_VALUE SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) {
  SWIGV8_HANDLESCOPE_ESC();
  
  SWIGV8_FUNCTION_TEMPLATE class_templ;

  if (ptr == NULL) {
    v8::Local<v8::Primitive> result = SWIGV8_NULL();
    SWIGV8_ESCAPE(result);
  }

  v8::Isolate *isolate = v8::Isolate::GetCurrent();

  if(info->clientdata != 0) {
    class_templ = v8::Local<v8::FunctionTemplate>::New(isolate, ((SWIGV8_ClientData*) info->clientdata)->class_templ);
  } else {
    class_templ = v8::Local<v8::FunctionTemplate>::New(isolate, SWIGV8_SWIGTYPE_Proxy_class_templ);
  }

  v8::Local<v8::Object> result = class_templ->InstanceTemplate()->NewInstance(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked();

  SWIGV8_SetPrivateData(result, ptr, info, flags);

  SWIGV8_ESCAPE(result);
}

#define SWIG_ConvertPtr(obj, ptr, info, flags)    SWIG_V8_ConvertPtr(obj, ptr, info, flags)
#define SWIG_NewPointerObj(ptr, info, flags)      SWIG_V8_NewPointerObj(ptr, info, flags)

#define SWIG_ConvertInstance(obj, pptr, type, flags)    SWIG_V8_ConvertInstancePtr(obj, pptr, type, flags)
#define SWIG_NewInstanceObj(thisvalue, type, flags)     SWIG_V8_NewPointerObj(thisvalue, type, flags)

#define SWIG_ConvertFunctionPtr(obj, pptr, type)        SWIG_V8_ConvertPtr(obj, pptr, type, 0)
#define SWIG_NewFunctionPtrObj(ptr, type)               SWIG_V8_NewPointerObj(ptr, type, 0)

#define SWIG_GetInstancePtr(obj, ptr)    SWIG_V8_GetInstancePtr(obj, ptr)

SWIGRUNTIME SwigV8ReturnValue _SWIGV8_wrap_equals(const SwigV8Arguments &args) {
  SWIGV8_HANDLESCOPE();
  
  SWIGV8_VALUE jsresult;
  void *arg1 = (void *) 0 ;
  void *arg2 = (void *) 0 ;
  bool result;
  int res1;
  int res2;

  if(args.Length() != 1) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for equals.");

  res1 = SWIG_GetInstancePtr(SWIGV8_ARGS_THIS(args), &arg1);
  if (!SWIG_IsOK(res1)) {
    SWIG_exception_fail(SWIG_ERROR, "Could not get pointer from 'this' object for equals.");
  }
  res2 = SWIG_GetInstancePtr(args[0], &arg2);
  if (!SWIG_IsOK(res2)) {
    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "equals" "', argument " "1"" of type '" "void *""'");
  }

  result = (bool)(arg1 == arg2);
  jsresult =  SWIGV8_BOOLEAN_NEW(result);

  SWIGV8_RETURN(jsresult);
  goto fail;
fail:
  SWIGV8_RETURN(SWIGV8_UNDEFINED());
}

SWIGRUNTIME SwigV8ReturnValue _wrap_getCPtr(const SwigV8Arguments &args) {
  SWIGV8_HANDLESCOPE();
  
  SWIGV8_VALUE jsresult;
  void *arg1 = (void *) 0 ;
  intptr_t result;
  int res1;

  res1 = SWIG_GetInstancePtr(SWIGV8_ARGS_THIS(args), &arg1);
  if (!SWIG_IsOK(res1)) {
    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "getCPtr" "', argument " "1"" of type '" "void *""'");
  }

  result = (intptr_t)arg1;
  jsresult = SWIGV8_NUMBER_NEW(result);

  SWIGV8_RETURN(jsresult);
  goto fail;
fail:
  SWIGV8_RETURN(SWIGV8_UNDEFINED());
}

/* ---------------------------------------------------------------------------
 * PackedData object
 *
 * ---------------------------------------------------------------------------*/

class SwigV8PackedData {
public:
  SwigV8PackedData(void *data, size_t size, swig_type_info *type): data(nullptr), size(size), type(type) {
    this->data = malloc(size);
    if (this->data != nullptr)
      memcpy(this->data, data, size);
  }

  ~SwigV8PackedData() {
    free(this->data);
  }

  void *data;
  size_t size;
  swig_type_info *type;

  v8::Persistent<v8::Object> handle;
};

SWIGRUNTIMEINLINE
int SwigV8Packed_Check(SWIGV8_VALUE valRef) {
  SWIGV8_HANDLESCOPE();
  
  SWIGV8_OBJECT objRef = SWIGV8_TO_OBJECT(valRef);
  if(objRef->InternalFieldCount() < 1) return false;
  v8::Local<v8::Private> privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("__swig__packed_data__"));
  v8::Local<v8::Value> flag;
  if (!objRef->GetPrivate(SWIGV8_CURRENT_CONTEXT(), privateKey).ToLocal(&flag))
    return false;
  return (flag->IsBoolean() && SWIGV8_BOOLEAN_VALUE(flag));
}

SWIGRUNTIME
swig_type_info *SwigV8Packed_UnpackData(SWIGV8_VALUE valRef, void *ptr, size_t size) {
  if (SwigV8Packed_Check(valRef)) {
    SWIGV8_HANDLESCOPE();
    
    SwigV8PackedData *sobj;

    SWIGV8_OBJECT objRef = SWIGV8_TO_OBJECT(valRef);

    sobj = static_cast<SwigV8PackedData*>(SWIGV8_ALIGNED_POINTER_GET(objRef, 0));
    if (sobj == NULL || sobj->size != size) return 0;
    memcpy(ptr, sobj->data, size);
    return sobj->type;
  } else {
    return 0;
  }
}

SWIGRUNTIME
int SWIGV8_ConvertPacked(SWIGV8_VALUE valRef, void *ptr, size_t sz, swig_type_info *ty) {
  swig_type_info *to = SwigV8Packed_UnpackData(valRef, ptr, sz);
  if (!to) return SWIG_ERROR;
  if (ty) {
    if (to != ty) {
      /* check type cast? */
      swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
      if (!tc) return SWIG_ERROR;
    }
  }
  return SWIG_OK;
}

SWIGRUNTIME void _wrap_SwigV8PackedData_delete(const v8::WeakCallbackInfo<SwigV8PackedData> &data) {
  SwigV8PackedData *cdata = data.GetParameter();
  cdata->handle.Reset();
  delete cdata;
}

SWIGRUNTIME
SWIGV8_VALUE SWIGV8_NewPackedObj(void *data, size_t size, swig_type_info *type) {
  SWIGV8_HANDLESCOPE_ESC();

  SwigV8PackedData *cdata = new SwigV8PackedData(data, size, type);
  SWIGV8_OBJECT_TEMPLATE tmpl = SWIGV8_OBJECT_TEMPLATE_NEW();
  tmpl->SetInternalFieldCount(1);
  v8::Local<v8::Object> obj = SWIGV8_OBJECT_TEMPLATE_INSTACE(tmpl);

  v8::Local<v8::Private> privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("__swig__packed_data__"));
  obj->SetPrivate(SWIGV8_CURRENT_CONTEXT(), privateKey, SWIGV8_BOOLEAN_NEW(true));

  SWIGV8_ALIGNED_POINTER_SET(obj, 0, cdata);

  cdata->handle.Reset(v8::Isolate::GetCurrent(), obj);

  cdata->handle.SetWeak(cdata, _wrap_SwigV8PackedData_delete, v8::WeakCallbackType::kParameter);

  SWIGV8_ESCAPE(obj);
}

#define SWIG_ConvertMember(obj, ptr, sz, ty)            SWIGV8_ConvertPacked(obj, ptr, sz, ty)
#define SWIG_NewMemberObj(ptr, sz, type)                SWIGV8_NewPackedObj(ptr, sz, type)


/* ---------------------------------------------------------------------------
 * Support for IN/OUTPUT typemaps (see Lib/typemaps/inoutlist.swg)
 *
 * ---------------------------------------------------------------------------*/

SWIGRUNTIME

SWIGV8_VALUE SWIGV8_AppendOutput(SWIGV8_VALUE result, SWIGV8_VALUE obj) {
  SWIGV8_HANDLESCOPE_ESC();
  
  if (result->IsUndefined()) {
    result = SWIGV8_ARRAY_NEW(0);
  } else if (!result->IsArray()) {
    SWIGV8_ARRAY tmparr = SWIGV8_ARRAY_NEW(0);
    SWIGV8_ARRAY_SET(tmparr, 0, result);
    result = tmparr;
  }

  SWIGV8_ARRAY arr = SWIGV8_ARRAY::Cast(result);
  SWIGV8_ARRAY_SET(arr, arr->Length(), obj);
  SWIGV8_ESCAPE(arr);
}
