duk_ret_t JavaScriptObject::finalizer(duk_context* ctx) {
    // Remove this pointers from the JS object's property.
    if (duk_get_prop_string(ctx, -1, WRAPPER_THIS_PROP_NAME)) {
        const duk_size_t length = duk_get_length(ctx, -1);
        for (duk_uarridx_t i = 0; i < length; ++i) {
            duk_get_prop_index(ctx, -1, i);

            JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(duk_get_pointer(ctx, -1));
            if (obj && obj->m_instance) {
                // Null out the instance pointer - it's been garbage collected!
                obj->m_instance = nullptr;

                if (obj->m_nextFinalizer) {
                    // Continue with the next finalizer in the chain.
                    obj->m_nextFinalizer(ctx);
                }
            }
            duk_pop(ctx);
        }
    }

    // Pop the array (or undefined if there was none).
    duk_pop(ctx);

    return 0;
}
ChromiumDLL::JSObjHandle JavaScriptFactory::CreateException(const char* value)
{
	JavaScriptObject *ret = new JavaScriptObject(CefV8Value::CreateString(value));
	ret->setException();

	return ret;
}
bool JavaScriptObject::setValue(int index, ChromiumDLL::JSObjHandle value)
{
	JavaScriptObject* jso = (JavaScriptObject*)value.get();

	if (!jso)
		return false;

	return m_pObject->SetValue(index, jso->getCefV8());
}
ChromiumDLL::JSObjHandle JavaScriptObject::executeFunction(ChromiumDLL::JavaScriptFunctionArgs *args)
{
	if (!isFunction())
		return GetJSFactory()->CreateException("Not a function!");

	if (!args)
		return GetJSFactory()->CreateException("Args are null for function call");

	JavaScriptContext* context = (JavaScriptContext*)args->context;
	JavaScriptObject* jso = (JavaScriptObject*)args->object.get();

	CefV8ValueList argList;

	for (int x=0; x<args->argc; x++)
	{
		JavaScriptObject* jsoa = (JavaScriptObject*)args->argv[x].get();

		if (jsoa)
			argList.push_back(jsoa->getCefV8());
		else
			argList.push_back(NULL);
	}

	CefRefPtr<CefV8Value> retval;
	CefString exception;

	bool res = m_pObject->ExecuteFunctionWithContext(context->getCefV8(), jso?jso->getCefV8():NULL, argList, retval, exception);

	if (!res)
	{
		if (exception.c_str())
			return GetJSFactory()->CreateException(exception.c_str());

		return GetJSFactory()->CreateException("failed to run function");
	}

	if (!retval)
		return NULL;

	return new JavaScriptObject(retval);
}
ChromiumDLL::JSObjHandle JavaScriptFactory::CreateException(const char* value)
{
    JavaScriptObject *ret = new JavaScriptObject(JSONNode("", value));
    ret->setException();
    return ret;
}