Fix memory leaks found by coverity (CID 1098781 & 1098880)
[scilab.git] / scilab / modules / external_objects_java / src / cpp / ScilabJavaEnvironment.cpp
index 8d1838e..fea094e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * PIMS ( http://forge.scilab.org/index.php/p/pims ) - This file is part of PIMS
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2013 - Scilab Enterprises - Sylvestre LEDRU
  *
  * This file must be used under the terms of the CeCILL.
@@ -23,7 +23,9 @@
 #include "ScilabJavaObject.hxx"
 #include "ScilabJavaArray.hxx"
 #include "ScilabJavaCompiler.hxx"
+#include "ScilabOperations.hxx"
 #include "NoMoreScilabMemoryException.hxx"
+#include "ScilabAutoCleaner.hxx"
 
 //#include "ScilabJavaObjectHelper.hxx"
 extern "C" {
@@ -45,44 +47,25 @@ ScilabJavaEnvironment::ScilabJavaEnvironment() :
     wrapper(*new ScilabJavaEnvironmentWrapper(helper)),
     traceEnabled(false),
     isInit(false),
-    scilabStream(*new ScilabStream()),
-    file(0) { }
+    scilabStream(*new ScilabStream()) { }
 
-//    ScilabJavaEnvironment::ScilabJavaEnvironment() {}
 ScilabJavaEnvironment::~ScilabJavaEnvironment()
 {
     //    delete &scope;
     delete &helper;
     delete &gwOptions;
     delete &wrapper;
-
-    if (file)
-    {
-        file->flush();
-        file->close();
-        delete file;
-        file = 0;
-    }
 }
 
 int ScilabJavaEnvironment::start()
 {
-    /*    if (!usable)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Due to Java interpreter limitations, Scilab must be restarted"));
-            }*/
-
     if (envId == -1)
     {
         instance = new ScilabJavaEnvironment();
         envId = ScilabEnvironments::registerScilabEnvironment(instance);
         instance->Initialize();
-        /*        ScilabJavaOStream::initJavaStreams();
-                ScilabJavaOStream::setStdOutStream(&instance->scilabStream);
-                ScilabJavaOStream::setStdErrStream(&instance->scilabStream);*/
         instance->helper.setUseLastName(true);
         instance->helper.setNewAllowed(true);
-        instance->enabletrace((std::string(getTMPDIR()) + std::string("/eo_java.log")).c_str());
     }
 
     return envId;
@@ -94,9 +77,9 @@ void ScilabJavaEnvironment::finish()
     {
         ScilabEnvironments::unregisterScilabEnvironment(envId);
         envId = -1;
+        instance->Finalize();
         delete instance;
         instance = 0;
-        instance->Finalize();
         usable = false;
     }
 }
@@ -137,332 +120,89 @@ const std::string & ScilabJavaEnvironment::getEnvironmentName()
 
 void ScilabJavaEnvironment::getEnvironmentInfos(const ScilabStringStackAllocator & allocator)
 {
+    JavaVM * vm = getScilabJavaVM();
+    int len;
+    char ** info = ScilabJavaObject::getInfos(vm, &len);
 
-    writeLog("getEnvironmentInfos", "Get information");
-
-    /*
-        std::vector<char *> version = breakInLines(std::string(Py_GetVersion()));
-        std::vector<char *> platform = breakInLines(std::string(Py_GetPlatform()));
-        std::vector<char *> copyright = breakInLines(std::string(Py_GetCopyright()));
-        std::vector<char *> compiler = breakInLines(std::string(Py_GetCompiler()));
-        std::vector<char *> buildInfo = breakInLines(std::string(Py_GetBuildInfo()));
-
-        int nbRows = version.size() + platform.size() + copyright.size() + compiler.size() + buildInfo.size();
-
-        std::vector<char *> all(nbRows, const_cast<char* >(""));
-        all[0] = const_cast<char* >("Version");
-        all[version.size()] = const_cast<char* >("Platform");
-        all[version.size() + platform.size()] = const_cast<char* >("Copyright");
-        all[version.size() + platform.size() + copyright.size()] = const_cast<char* >("Compiler");
-        all[version.size() + platform.size() + copyright.size() + compiler.size()] = const_cast<char* >("Build info");
-
-        all.insert(all.end(), version.begin(), version.end());
-        all.insert(all.end(), platform.begin(), platform.end());
-        all.insert(all.end(), copyright.begin(), copyright.end());
-        all.insert(all.end(), compiler.begin(), compiler.end());
-        all.insert(all.end(), buildInfo.begin(), buildInfo.end());
-
-        allocator.allocate(nbRows, 2, &(all[0]));
-    */
-}
+    allocator.allocate(len, 1, info);
 
-int ScilabJavaEnvironment::extract(int id, int * args, int argsSize)
-{
-    if (traceEnabled)
+    for (int i = 0; i < len; i++)
     {
-        std::ostringstream os;
-        for (int i = 0; i < argsSize - 1; i++)
-        {
-            os << args[i] << ", ";
-        }
-        os << args[argsSize - 1];
-        os.flush();
-
-        writeLog("extract", "Extraction on object %d with arguments: %s.", id, os.str().c_str());
+        delete[] info[i];
     }
 
-    /*    PyObject * obj = scope.getObject(id);
-        if (!obj)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
-        }
-
-        if (PyDict_Check(obj))
-        {
-            if (argsSize != 1)
-            {
-                throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot extract more than one element from a dictionary"));
-            }
-
-            PyObject * key = scope.getObject(*args);
-            if (!obj)
-            {
-                throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid key object"));
-            }
-
-            if (!PyDict_Contains(obj, key))
-            {
-                throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid key"));
-            }
-
-            PyObject * value = PyDict_GetItem(obj, key);
-       Py_INCREF(value);
+    delete[] info;
+}
 
-            int ret = scope.addObject(value);
-            writeLog("extract", "returned id: %d.", ret);
+int ScilabJavaEnvironment::extract(int id, int * args, int argsSize)
+{
+    JavaVM * vm = getScilabJavaVM();
+    const int ret = ScilabJavaObject::extract(vm, id, args, argsSize);
 
-            return ret;
-            }
-    */
+    ScilabAutoCleaner::registerVariable(envId, ret);
 
-    throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot extract from Java object"));
+    return ret;
 }
 
 void ScilabJavaEnvironment::insert(int id, int * args, int argsSize)
 {
-    if (traceEnabled)
-    {
-        std::ostringstream os;
-        for (int i = 0; i < argsSize - 1; i++)
-        {
-            os << args[i] << ", ";
-        }
-        os << args[argsSize - 1];
-        os.flush();
-
-        writeLog("insert", "Insertion on object %d with arguments: %s.", id, os.str().c_str());
-    }
-    /*
-        PyObject * obj = scope.getObject(id);
-        if (!obj)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
-        }
-
-        if (argsSize != 2)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot insert more than one element in a dictionary"));
-        }
-
-        PyObject * key = scope.getObject(args[0]);
-        if (!obj)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid key object"));
-        }
-
-        PyObject * value = scope.getObject(args[1]);
-        if (!value)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid value object"));
-        }
-
-        if (PyDict_Check(obj))
-        {
-            PyDict_SetItem(obj, key, value);
-
-            writeLog("insert", "success.");
-
-            return;
-        }
-        else
-        {
-            if (!PyString_Check(key))
-            {
-                throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid key object: A string expected"));
-            }
-
-            int ret = PyObject_SetAttr(obj, key, value);
-            if (ret == -1)
-            {
-                if (PyErr_Occurred())
-                {
-                    PyObject *type, *value, *traceback;
-                    PyErr_Fetch(&type, &value, &traceback);
-                    PyErr_NormalizeException(&type, &value, &traceback);
-                    PyErr_Clear();
-
-                    throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Cannot evaluate the code"));
-                }
-                throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot set the attribute."));
-            }
-
-            writeLog("insert", "success.");
-
-            return;
-        }
-    */
-    throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot insert in Java object"));
+    JavaVM * vm = getScilabJavaVM();
+    ScilabJavaObject::insert(vm, id, args, argsSize - 1, args[argsSize - 1]);
 }
 
-void ScilabJavaEnvironment::garbagecollect() { }
+void ScilabJavaEnvironment::garbagecollect()
+{
+    JavaVM *vm = getScilabJavaVM();
+    ScilabJavaObject::garbageCollect(vm);
+}
 
 void ScilabJavaEnvironment::addtoclasspath(const char * path)
 {
-    writeLog("addtoclasspath", "Add the path %s to syspath", path);
-    /*
-        PyObject * syspath = PySys_GetObject(const_cast<char *>("path"));
-        PyObject * _path = PyString_FromString(path);
-        PyList_Append(syspath, _path);
-    */
+    // Useless: we already have javaclasspath
 }
 
 void ScilabJavaEnvironment::getclasspath(const ScilabStringStackAllocator & allocator)
 {
-    writeLog("getclasspath", "Get syspath");
-    /*
-        PyObject * syspath = PySys_GetObject(const_cast<char *>("path"));
-        int size = PyList_Size(syspath);
-        char ** arr = new char*[size];
-
-        for (int i = 0; i < size; i++)
-        {
-            PyObject * item = PyList_GetItem(syspath, i);
-            arr[i] = strdup(PyString_AsString(item));
-        }
-
-        allocator.allocate(size, 1, arr);
-        for (int i = 0; i < size; i++)
-        {
-            free(arr[i]);
-        }
-        delete arr;
-    */
+    // Useless: we already have javaclasspath
 }
 
 void ScilabJavaEnvironment::addNamedVariable(int id, const char * varName)
 {
-    writeLog("addNamedVariable", "Associate the variable named %s with object with id %d.", varName, id);
-
-    /*    PyObject * obj = scope.getObject(id);
-        if (!obj)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
-        }
-
-        PyObject * _main_ = PyImport_AddModule("__main__");
-        if (!_main_)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot evaluate the code since __main__ is not accessible."));
-        }
-
-        if (PyObject_SetAttrString(_main_, varName, obj) == -1)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot set the variable named %s."), varName);
-        }
-    */
+    // Useless in Java environment
 }
 
 int ScilabJavaEnvironment::getNamedVariable(const char * varName)
 {
-    writeLog("getNamedVariable", "Get the variable named %s.", varName);
-    /*
-        PyObject * _main_ = PyImport_AddModule("__main__");
-        if (!_main_)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot evaluate the code since __main__ is not accessible."));
-        }
-
-        PyObject * var = PyObject_GetAttrString(_main_, varName);
-        if (!var)
-        {
-            if (PyErr_Occurred())
-            {
-                PyObject *type, *value, *traceback;
-                PyErr_Fetch(&type, &value, &traceback);
-                PyErr_NormalizeException(&type, &value, &traceback);
-                PyErr_Clear();
-
-                throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Cannot get the variable value"));
-            }
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot get the variable value"));
-        }
-
-        int ret = scope.addObject(var);
-
-        writeLog("getNamedVariable", "returned id %d.", ret);
-
-        return ret;
-    */
     return 0;
 }
 
 void ScilabJavaEnvironment::evalString(const char ** code, int nbLines, ScilabStringStackAllocator * allocator)
 {
-    writeLog("evalString", "Evaluate code: %s...(truncated)", *code);
-    /*
-        std::ostringstream os;
-        for (int i = 0; i < nbLines; i++)
-        {
-            os << code[i] << std::endl;
-        }
-        os.flush();
-
-        PyObject * _main_ = PyImport_AddModule("__main__");
-        if (!_main_)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot evaluate the code since __main__ is not accessible."));
-        }
-
-        std::ostream * old;
-        std::ostringstream os1;
-        if (allocator)
-        {
-            old = ScilabJavaOStream::setStdOutStream(&os1);
-        }
-
-        PyObject * dict = PyModule_GetDict(_main_);
-        PyObject * ret = PyRun_StringFlags(os.str().c_str(), Py_file_input, dict, dict, 0);
-
-        if (allocator)
-        {
-            ScilabJavaOStream::setStdOutStream(old);
-        }
-
-        if (!ret)
-        {
-            if (PyErr_Occurred())
-            {
-                PyObject *type, *value, *traceback;
-                PyErr_Fetch(&type, &value, &traceback);
-                PyErr_NormalizeException(&type, &value, &traceback);
-                PyErr_Clear();
-
-                throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Cannot evaluate the code"));
-            }
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot evaluate the code"));
-        }
-
-        if (allocator)
-        {
-            std::vector<char *> buf = breakInLines(os1.str());
-            allocator->allocate(buf.size(), 1, &(buf[0]));
-            for (std::vector<char *>::iterator i = buf.begin(); i != buf.end(); i++)
-            {
-                free(*i);
-            }
-        }
-
-        Py_DECREF(ret);
-    */
+    // Useless in Java (it is not a script language !)
 }
 
 int ScilabJavaEnvironment::createarray(char * className, int * dims, int len)
 {
-    writeLog("createarray", "Create array %s of size (%d, %d).", className, dims, len);
     JavaVM *vm = getScilabJavaVM();
-    return ScilabJavaArray::newInstance(vm, className, dims, len);
+    const int ret = ScilabJavaArray::newInstance(vm, className, dims, len);
+
+    ScilabAutoCleaner::registerVariable(envId, ret);
+
+    return ret;
 }
 
 int ScilabJavaEnvironment::loadclass(char * className, char * currentSciPath, bool isNamedVarCreated, bool allowReload)
 {
-    writeLog("loadclass", "Load the module %s and allowReload is set to %s", className, allowReload ? "true" : "false");
     JavaVM *vm = getScilabJavaVM();
-    return ScilabClassLoader::loadJavaClass(vm, className, allowReload);
+    const int ret = ScilabClassLoader::loadJavaClass(vm, className, allowReload);
+
+    ScilabAutoCleaner::registerVariable(envId, ret);
+
+    return ret;
 }
 
 void ScilabJavaEnvironment::getrepresentation(int id, const ScilabStringStackAllocator & allocator)
 {
-    writeLog("getrepresentation", "Get the representation of object %d.", id);
     JavaVM *vm = getScilabJavaVM();
     char *str = ScilabJavaObject::getRepresentation(vm, id);
     allocator.allocate(1, 1, &str);
@@ -470,7 +210,6 @@ void ScilabJavaEnvironment::getrepresentation(int id, const ScilabStringStackAll
 
 std::string ScilabJavaEnvironment::getrepresentation(int id)
 {
-    writeLog("getrepresentation", "Get the representation of object %d.", id);
     JavaVM *vm = getScilabJavaVM();
     return std::string(ScilabJavaObject::getRepresentation(vm, id));
 }
@@ -478,113 +217,62 @@ std::string ScilabJavaEnvironment::getrepresentation(int id)
 /* Used by jexists */
 bool ScilabJavaEnvironment::isvalidobject(int id)
 {
-
     JavaVM *vm = getScilabJavaVM();
-    bool ret = ScilabJavaObject::isValidJavaObject(vm, id);
-    writeLog("isvalidobject", "Test the validity of object %d which is%s valid.", id, ret ? "" : " not");
-    return ret;
+    return ScilabJavaObject::isValidJavaObject(vm, id);
 }
 
 int ScilabJavaEnvironment::newinstance(int id, int * args, int argsSize)
 {
     JavaVM *vm = getScilabJavaVM();
-    return ScilabJavaClass::newInstance(vm, id, args, argsSize);
+    const int ret = ScilabJavaClass::newInstance(vm, id, args, argsSize);
+
+    ScilabAutoCleaner::registerVariable(envId, ret);
+
+    return ret;
 }
 
 int ScilabJavaEnvironment::operation(int idA, int idB, const OperatorsType type)
 {
-    writeLog("operation", "Evalute an operation (%d) with objects with id %d and %d.", (int)type, idA, idB);
-    /*
-        const char * opName = getOpNameFromType(type);
-
-        PyObject * _operator_ = PyImport_AddModule("operator");
-        if (!_operator_)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot get the operator module."));
-        }
-
-        PyObject * objA = scope.getObject(idA);
-        if (!objA)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), idA);
-        }
-
-        PyObject * objB = 0;
-        if (idB != -1)
-        {
-            // Binary op
-            objB = scope.getObject(idB);
-            if (!objB)
-            {
-                throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), idB);
-            }
-        }
-
-        PyObject * _op_ = PyObject_GetAttrString(_operator_, opName);
-
-        PyObject * pArgs = PyTuple_New(objB ? 2 : 1);
-        Py_INCREF(objA);
-        PyTuple_SetItem(pArgs, 0, objA);
-
-        if (objB)
-        {
-            Py_INCREF(objB);
-            PyTuple_SetItem(pArgs, 1, objB);
-        }
-
-        PyObject * result = PyObject_Call(_op_, pArgs, 0);
-        Py_DECREF(pArgs);
-        Py_DECREF(_op_);
-
-        if (!result)
-        {
-            if (PyErr_Occurred())
-            {
-                PyObject * type, * value, * traceback;
-                PyErr_Fetch(&type, &value, &traceback);
-                PyErr_NormalizeException(&type, &value, &traceback);
-                PyErr_Clear();
-
-                throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Unable to make the operation (%s)."), opName);
-            }
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Unable to make the operation (%s)."), opName);
-        }
+    JavaVM *vm = getScilabJavaVM();
+    int ret;
 
-        int ret = scope.addObject(result);
+    switch (type)
+    {
+        case Add :
+            ret = ScilabOperations::add(vm, idA, idB);
+            break;
+        default :
+            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid operation"));
+    }
 
-        writeLog("operation", "returned id %d.", ret);
+    if (ret != 0 && ret != -1)
+    {
+        ScilabAutoCleaner::registerVariable(envId, ret);
+    }
 
-        return ret;
-    */
-    return 0;
+    return ret;
 }
 
 int * ScilabJavaEnvironment::invoke(int id, const char * methodName, int * args, int argsSize)
 {
-    if (traceEnabled)
-    {
-        std::ostringstream os;
-        for (int i = 0; i < argsSize - 1; i++)
-        {
-            os << args[i] << ", ";
-        }
-        os << args[argsSize - 1];
-        os.flush();
-
-        writeLog("invoke", "Invoke the method %s on object %d with arguments: %s.", methodName, id, os.str().c_str());
-    }
+    // TODO: In Java, an array can be passed as a reference so we need to "return" it
+    // for example, stream.read(buf, ...), the bytes are put in buf so we need to get it !
 
     JavaVM *vm = getScilabJavaVM();
     int * invokedId = new int[2];
     invokedId[0] = 1 ; //1 object returned
     invokedId[1] = ScilabJavaObject::invoke(vm, id, methodName, args, argsSize);
+
+    if (invokedId[1] != 0 && invokedId[1] != -1)
+    {
+        ScilabAutoCleaner::registerVariable(envId, invokedId[1]);
+    }
+
     return invokedId;
 }
 
 void ScilabJavaEnvironment::setfield(int id, const char * fieldName, int idarg)
 {
-    writeLog("setfield", "Set the field named %s with value id %d on object with id %d.", fieldName, idarg, id);
-
     if (*fieldName == '\0')
     {
         throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid field name"));
@@ -599,340 +287,165 @@ void ScilabJavaEnvironment::setfield(int id, const char * fieldName, int idarg)
     {
         throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot set the field: %s"), fieldName);
     }
-
-    writeLog("setfield", "Value successfully set.");
 }
 
 int ScilabJavaEnvironment::getfield(int id, const char * fieldName)
 {
-    writeLog("getfield", "Get the field named %s on object with id %d.", fieldName, id);
-
     if (*fieldName == '\0')
     {
         throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid field name"));
     }
 
     JavaVM * vm = getScilabJavaVM();
-    int ret = ScilabJavaObject::getField(vm, id, fieldName);
+    const int ret = ScilabJavaObject::getField(vm, id, fieldName);
+
+    ScilabAutoCleaner::registerVariable(envId, ret);
 
     return ret;
 }
 
 int ScilabJavaEnvironment::getfieldtype(int id, const char * fieldName)
 {
-    writeLog("getfieldtype", "Get the type of the field %s on object with id %d.", fieldName, id);
-
-    if ((!helper.getShowPrivate() && *fieldName == '_') || *fieldName == '\0')
-    {
-        writeLog("getfieldtype", "Return NONE.");
-        return -1;
-    }
-    /*
-        PyObject * obj = scope.getObject(id);
-        if (!obj)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
-        }
-
-        if (!PyObject_HasAttrString(obj, fieldName))
-        {
-            writeLog("getfieldtype", "Return NONE.");
-            return -1;
-        }
-
-        PyObject * field = PyObject_GetAttrString(obj, fieldName);
-        if (!field)
-        {
-            writeLog("getfieldtype", "Return NONE.");
-            return -1;
-        }
-
-        if (PyCallable_Check(field))
-        {
-            Py_DECREF(field);
-            writeLog("getfieldtype", "Return METHOD.");
-            return 0;
-        }
-        else
-        {
-            Py_DECREF(field);
-            writeLog("getfieldtype", "Return FIELD.");
-            return 1;
-        }
-    */
-    return 0;
+    JavaVM * vm = getScilabJavaVM();
+    return ScilabJavaObject::getFieldType(vm, id, fieldName);
 }
 
 int ScilabJavaEnvironment::getarrayelement(int id, int * index, int length)
 {
-    if (traceEnabled)
-    {
-        std::ostringstream os;
-        for (int i = 0; i < length - 1; i++)
-        {
-            os << index[i] << ", ";
-        }
-        os << index[length - 1];
-        os.flush();
-
-        writeLog("getarrayelement", "Get element from array with id %d and with index: %s.", id, os.str().c_str());
-    }
-    /*
-        PyObject * obj = scope.getObject(id);
-        if (!obj)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
-        }
-
-        if (!PyList_Check(obj) && !PyArray_Check(obj))
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Not a list or an array"));
-        }
-
-        if (length == 0)
-        {
-            return 0;
-        }
-
-        if (PyList_Check(obj))
-        {
-            for (int i = 0; i < length; i++)
-            {
-                if (index[i] < 0 || index[i] >= PyList_Size(obj))
-                {
-                    throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index"));
-                }
-                obj = PyList_GetItem(obj, index[i]);
-                if (i != length - 1 && !PyList_Check(obj))
-                {
-                    throw ScilabJavaException(__LINE__, __FILE__, gettext("Not a list"));
-                }
-            }
-       Py_INCREF(obj);
-        }
-        else if (PyArray_Check(obj))
-        {
-            PyArrayObject * arr = reinterpret_cast<PyArrayObject *>(obj);
-            npy_intp * ind = reinterpret_cast<npy_intp *>(index);
-
-            if (length != PyArray_NDIM(arr))
-            {
-                throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index dimension"));
-            }
+    JavaVM * vm = getScilabJavaVM();
+    const int ret = ScilabJavaObject::getArrayElement(vm, id, index, length);
 
-            npy_intp * dims = PyArray_DIMS(arr);
+    ScilabAutoCleaner::registerVariable(envId, ret);
 
-            if (sizeof(int) != sizeof(npy_intp))
-            {
-                ind = new npy_intp[length];
-                for (int i = 0; i < length; i++)
-                {
-                    if (index[i] < 0 || index[i] >= dims[i])
-                    {
-                        delete[] ind;
-                        throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index at position %d"), i + 1);
-                    }
-
-                    ind[i] = static_cast<npy_intp>(index[i]);
-                }
-            }
-
-            obj = PyArray_GETITEM(arr, PyArray_GetPtr(arr, ind));
-
-            if (sizeof(int) != sizeof(npy_intp))
-            {
-                delete[] ind;
-            }
-        }
-        else
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Must be a list or a Numpy array"));
-        }
-
-        int ret = scope.addObject(obj);
-        writeLog("getarrayelement", "returned id %d.", ret);
-
-        return ret;
-    */
-    return 0;
+    return ret;
 }
 
 void ScilabJavaEnvironment::setarrayelement(int id, int * index, int length, int idArg)
 {
-    if (traceEnabled)
-    {
-        std::ostringstream os;
-        for (int i = 0; i < length - 1; i++)
-        {
-            os << index[i] << ", ";
-        }
-        os << index[length - 1];
-        os.flush();
-
-        writeLog("setarrayelement", "Set element with id %d in array with id %d and with index: %s.", idArg, id, os.str().c_str());
-    }
-    /*
-        PyObject * obj = scope.getObject(id);
-        if (!obj)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
-        }
-
-        PyObject * value = scope.getObject(idArg);
-        if (!value)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
-        }
-
-        if (PyList_Check(obj))
-        {
-            if (length == 0)
-            {
-                return;
-            }
-
-            for (int i = 0; i < length - 1; i++)
-            {
-                if (index[i] < 0 || index[i] >= PyList_Size(obj))
-                {
-                    throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index at position %d"), i + 1);
-                }
-                obj = PyList_GetItem(obj, index[i]);
-                if (!PyList_Check(obj))
-                {
-                    throw ScilabJavaException(__LINE__, __FILE__, gettext("Not a list at position %d"), index[i]);
-                }
-            }
-
-            Py_INCREF(value);
-            PyList_SetItem(obj, index[length - 1], value);
-        }
-        else if (PyArray_Check(obj))
-        {
-            PyArrayObject * arr = reinterpret_cast<PyArrayObject *>(obj);
-            npy_intp * ind = reinterpret_cast<npy_intp *>(index);
-
-            if (length != PyArray_NDIM(arr))
-            {
-                throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index dimension"));
-            }
-
-            npy_intp * dims = PyArray_DIMS(arr);
-
-            if (sizeof(int) != sizeof(npy_intp))
-            {
-                ind = new npy_intp[length];
-                for (int i = 0; i < length; i++)
-                {
-                    if (index[i] < 0 || index[i] >= dims[i])
-                    {
-                        delete[] ind;
-                        throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index at position %d"), i);
-                    }
-
-                    ind[i] = static_cast<npy_intp>(index[i]);
-                }
-            }
-
-            int ret = PyArray_SETITEM(arr, PyArray_GetPtr(arr, ind), value);
-
-            if (sizeof(int) != sizeof(npy_intp))
-            {
-                delete[] ind;
-            }
-
-            if (ret == -1)
-            {
-                throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot set the value in the array"));
-            }
-        }
-    */
-    writeLog("setarrayelement", "Successfully set");
+    JavaVM * vm = getScilabJavaVM();
+    ScilabJavaObject::setArrayElement(vm, id, index, length, idArg);
 }
 
 int ScilabJavaEnvironment::cast(int id, char * className)
 {
     JavaVM *vm = getScilabJavaVM();
-    return ScilabJavaObject::javaCast(vm, id, className);
+    const int ret = ScilabJavaObject::javaCast(vm, id, className);
+
+    ScilabAutoCleaner::registerVariable(envId, ret);
+
+    return ret;
 }
 
 int ScilabJavaEnvironment::castwithid(int id, int classId)
 {
     JavaVM *vm = getScilabJavaVM();
-    return ScilabJavaObject::javaCast(vm, id, classId);
+    const int ret = ScilabJavaObject::javaCast(vm, id, classId);
+
+    ScilabAutoCleaner::registerVariable(envId, ret);
+
+    return ret;
 }
 
 void ScilabJavaEnvironment::removeobject(int id)
 {
-    writeLog("removeobject", "Remove object with id %d.", id);
-    //    scope.removeObject(id);
-    //    ScilabAutoCleaner::unregisterVariable(envId, id);
+    JavaVM *vm = getScilabJavaVM();
+    ScilabJavaObject::removeScilabJavaObject(vm, id);
+    ScilabAutoCleaner::unregisterVariable(envId, id);
+}
+
+void ScilabJavaEnvironment::removeobject(const int * id, const int length)
+{
+    if (length == 1)
+    {
+        removeobject(*id);
+    }
+    else
+    {
+        JavaVM *vm = getScilabJavaVM();
+        ScilabJavaObject::removeScilabJavaObject(vm, id, length);
+        ScilabAutoCleaner::unregisterVariable(envId, id, length);
+    }
 }
 
 void ScilabJavaEnvironment::autoremoveobject(int id)
 {
-    //    scope.removeObject(id);
+    JavaVM *vm = getScilabJavaVM();
+    ScilabJavaObject::removeScilabJavaObject(vm, id);
 }
 
 void ScilabJavaEnvironment::getaccessiblemethods(int id, const ScilabStringStackAllocator & allocator)
 {
-    writeLog("getaccessiblemethods", "Get accessible methods on object with id %d.", id);
     JavaVM *vm = getScilabJavaVM();
     getMethodResult(vm, "getAccessibleMethods", id, allocator);
 }
 
 void ScilabJavaEnvironment::getaccessiblefields(int id, const ScilabStringStackAllocator & allocator)
 {
-    writeLog("getaccessiblefields", "Get accessible fields on object with id %d.", id);
     JavaVM *vm = getScilabJavaVM();
     getMethodResult(vm, "getAccessibleFields", id, allocator);
     getAccessibleFields(id, allocator, true);
 }
 
+std::vector<std::string> ScilabJavaEnvironment::getCompletion(int id, char ** fieldsPath, const int fieldPathLen)
+{
+    JavaVM * vm = getScilabJavaVM();
+    int len = 0;
+    char ** fields = ScilabJavaObject::getCompletion(vm, id, fieldsPath + 1 , fieldPathLen - 1, &len);
+    std::vector<std::string> v;
+
+    for (int i = 0; i < len; i++)
+    {
+        v.push_back(fields[i]);
+        delete fields[i];
+    }
+    delete fields;
+
+    return v;
+}
+
 std::string ScilabJavaEnvironment::getclassname(int id)
 {
-    writeLog("getclassname", "Get the class name of object with id %d.", id);
     JavaVM *vm = getScilabJavaVM();
     return std::string(ScilabJavaObject::getClassName(vm, id));
 }
 
 VariableType ScilabJavaEnvironment::isunwrappable(int id)
 {
-    writeLog("isunwrappable", "Test if the object with id %d is unwrappable.", id);
     return wrapper.isunwrappable(id);
 }
 
 int ScilabJavaEnvironment::compilecode(char * className, char ** code, int size)
 {
-    writeLog("compilecode", "Compile the code %s...", *code);
+    JavaVM *vm = getScilabJavaVM();
+    const int ret = ScilabJavaCompiler::compileCode(vm, className, code, size);
 
-    std::ostringstream os;
-    for (int i = 0; i < size; i++)
+    if (ret != 0 && ret != -1)
     {
-        os << code[i] << std::endl;
+        ScilabAutoCleaner::registerVariable(envId, ret);
     }
-    os.flush();
 
-    JavaVM *vm = getScilabJavaVM();
-    return ScilabJavaCompiler::compileCode(vm, className, code, size);
+    return ret;
 }
 
 void ScilabJavaEnvironment::enabletrace(const char * filename)
 {
     JavaVM *vm = getScilabJavaVM();
     ScilabJavaObject::enableTrace(vm, filename);
+    traceEnabled = true;
 }
 
 void ScilabJavaEnvironment::disabletrace(void)
 {
     JavaVM *vm = getScilabJavaVM();
     ScilabJavaObject::disableTrace(vm);
+    traceEnabled = false;
 }
 
 void ScilabJavaEnvironment::writeLog(const std::string & fun, const std::string str, ...) const
 {
     if (traceEnabled)
     {
+        JavaVM * vm = getScilabJavaVM();
         char _str[LOG_BUFFER_SIZE];
         va_list args;
 
@@ -940,7 +453,7 @@ void ScilabJavaEnvironment::writeLog(const std::string & fun, const std::string
         vsnprintf(_str, LOG_BUFFER_SIZE, str.c_str(), args);
         va_end(args);
 
-        *file << fun << ": " << _str << std::endl;
+        ScilabJavaObject::writeLog(vm, _str);
     }
 }
 
@@ -1003,167 +516,4 @@ void ScilabJavaEnvironment::getMethodResult(JavaVM * jvm_, const char * const me
         throw GiwsException::JniCallMethodException(curEnv);
     }
 };
-
-/*
-template <typename T, typename U, class V>
-void unwrapMat(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
-{
-    SciErr err;
-    jint lenRow, lenCol;
-    jboolean isCopy = JNI_FALSE;
-    jarray oneDim;
-    JNIEnv * curEnv = NULL;
-    U *addr = NULL;
-
-    jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
-    jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
-
-    jmethodID id = curEnv->GetStaticMethodID(cls, V::getMatMethodName(), V::getMatMethodSignature()) ;
-    if (id == NULL)
-    {
-        throw GiwsException::JniMethodNotFoundException(curEnv, V::getMatMethodName());
-    }
-
-    jobjectArray res = static_cast<jobjectArray>(curEnv->CallStaticObjectMethod(cls, id, javaID));
-    if (curEnv->ExceptionCheck())
-    {
-        throw GiwsException::JniCallMethodException(curEnv);
-    }
-
-    lenRow = curEnv->GetArrayLength(res);
-    oneDim = reinterpret_cast<jarray>(curEnv->GetObjectArrayElement(res, 0));
-    lenCol = curEnv->GetArrayLength(oneDim);
-    curEnv->DeleteLocalRef(oneDim);
-
-//    allocator.allocate(lenRow, lenCol, addr);
-
-    if (getMethodOfConv())
-    {
-        err = V::allocMatrix(pvApiCtx, pos, lenRow, lenCol, (void**) &addr);
-    }
-    else
-    {
-        err = V::allocMatrix(pvApiCtx, pos, lenCol, lenRow, (void**) &addr);
-    }
-
-    if (err.iErr)
-    {
-        curEnv->DeleteLocalRef(res);
-        throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
-    }
-
-    T *resultsArray;
-    for (int i = 0; i < lenRow; i++)
-    {
-        oneDim = reinterpret_cast<jarray>(curEnv->GetObjectArrayElement(res, i));
-        resultsArray = static_cast<T *>(curEnv->GetPrimitiveArrayCritical(oneDim, &isCopy));
-        if (getMethodOfConv())
-        {
-            for (int j = 0; j < lenCol; j++)
-            {
-                addr[j * lenRow + i] = static_cast<U>(resultsArray[j]);
-            }
-        }
-        else
-        {
-            for (int j = 0; j < lenCol; j++)
-            {
-                addr[i * lenCol + j] = static_cast<U>(resultsArray[j]);
-            }
-        }
-        curEnv->ReleasePrimitiveArrayCritical(oneDim, resultsArray, JNI_ABORT);
-        curEnv->DeleteLocalRef(oneDim);
-    }
-
-    curEnv->DeleteLocalRef(res);
-    if (curEnv->ExceptionCheck())
-    {
-        throw GiwsException::JniCallMethodException(curEnv);
-    }
-}
-
-template <typename T, typename U, class V>
-void unwrapRow(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
-{
-    SciErr err;
-    jint lenRow;
-    jboolean isCopy = JNI_FALSE;
-    JNIEnv * curEnv = NULL;
-    U *addr = NULL;
-
-    jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
-    jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
-
-    jmethodID id = curEnv->GetStaticMethodID(cls, V::getRowMethodName(), V::getRowMethodSignature());
-    if (id == NULL)
-    {
-        throw GiwsException::JniMethodNotFoundException(curEnv, V::getRowMethodName());
-    }
-
-    jobjectArray res = static_cast<jobjectArray>(curEnv->CallStaticObjectMethod(cls, id, javaID));
-    if (curEnv->ExceptionCheck())
-    {
-        curEnv->DeleteLocalRef(res);
-        throw GiwsException::JniCallMethodException(curEnv);
-    }
-
-    lenRow = curEnv->GetArrayLength(res);
-
-    // err = V::allocMatrix(pvApiCtx, pos, 1, lenRow, (void**) &addr);
-
-    // if (err.iErr)
-    // {
-    //     curEnv->DeleteLocalRef(res);
-    //     throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
-    // }
-
-    T *resultsArray = static_cast<T *>(curEnv->GetPrimitiveArrayCritical(res, &isCopy));
-    for (int i = 0; i < lenRow; i++)
-    {
-        addr[i] = static_cast<U>(resultsArray[i]);
-    }
-
-    allocator.allocate(lenRow, lenCol, addr);
-
-    curEnv->ReleasePrimitiveArrayCritical(res, resultsArray, JNI_ABORT);
-    curEnv->DeleteLocalRef(res);
-    if (curEnv->ExceptionCheck())
-    {
-        throw GiwsException::JniCallMethodException(curEnv);
-    }
-}
-
-template <typename T, typename U, class V>
-void unwrapSingle(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
-{
-    SciErr err;
-    JNIEnv * curEnv = NULL;
-    U *addr = NULL;
-
-    jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
-    jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
-
-    jmethodID id = curEnv->GetStaticMethodID(cls, V::getMethodName(), V::getMethodSignature()) ;
-    if (id == NULL)
-    {
-        throw GiwsException::JniMethodNotFoundException(curEnv, V::getMethodName());
-    }
-
-    // err = V::allocMatrix(pvApiCtx, pos, 1, 1, (void**) &addr);
-
-    // if (err.iErr)
-    // {
-    //     throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
-    // }
-
-
-
-    *addr = static_cast<U>(V::getSingleVar(curEnv, cls, id, javaID));
-    allocator.allocate(lenRow, lenCol, addr);
-
-    if (curEnv->ExceptionCheck())
-    {
-        throw GiwsException::JniCallMethodException(curEnv);
-    }
-*/
 }