Dear Leandro,

This is very nice commit for elev8 modularization. Thanks.

I have some problems compiling in my machine.

Object::HasOwnProperty() is not to be found in v8.h.
I did an apt-get update/upgrade and I did not find this in v8.h (version -
3.1.8.22) .
The reference API page does provide this API though.
Can you tell me which version of libv8 you have used?
I would prefer to use the API's provided as part of distro.

Regards,
Sanjeev



On Fri, Mar 2, 2012 at 3:35 AM, Enlightenment SVN <
no-re...@enlightenment.org> wrote:

> Log:
> elev8: Allow loading modules in runtime
>
>  There are now two kinds of modules: native (.so) and JavaScript (.js).
> Both
>  modules can be loaded using the same interface and is completely
> transparent
>  to the application developer, by using the global require() function.  For
>  example, to load the elementary module:
>
>      elm = require('elm');
>
>  This will try to open 'libelm.so' in the current directory, then
> 'libelm.so'
>  in elev8's module directory.  If that fails, it will try to open 'elm.js'
> in
>  the current directory, then 'elm.js' in elev8's directory.  Should any of
>  these attempts work, it will save the module in an internal cache and
> return
>  a reference to an object containing all exported symbols from that module.
>  The module loading path can be changed by changing the MODPATH environment
>  variable in the same way one would set the PATH environment variable.
>
>  To create a native module, one should create a
>  RegisterModule(Handle<ObjectTemplate>target) function, and manually add
>  exported symbols to the target object. Be sure to ``export "C"'' it or
> else
>  dlsym() will fail.
>
>  JavaScript modules works pretty much the same way: they're created and
>  executed in a separate context so that they do not mess up with the rest
> of
>  the application (for instance, it is very easy to forget a ``var''
> keyword,
>  making a variable global -- imagine the mess a for (i = 0; i < 10; i++)
>  derp() would make).  A global (to the module's context) object called
>  ``exports'' must be used to export functions and globals:
>
>      exports.pi = 3.14159265;
>      exports.calculate_the_answer = function() {
>        return Math.ceil((1337 * exports.pi) / 100.0);
>      }
>
>  Elev8 does not load all modules automatically anymore -- this is now
>  controlled by the init.js script, which is loaded and interpreted at
>  startup.  This can be used to load other modules, define useful constants,
>  this sort of thing.  Care should be taken when using this file, though,
> since
>  it is compiled and evaluated in the global context.
>
>  Also, support for Eina_Module has been temporarily removed; it will be
> back,
>  don't worry about it.  This means that module shutdown functions have been
>  temporarily removed as well.  There are more important cleanups to be made
>  in Elev8, so this will be postponed until further notice.
>
>
>
> Author:       acidx
> Date:         2012-03-01 10:35:09 -0800 (Thu, 01 Mar 2012)
> New Revision: 68583
> Trac:         http://trac.enlightenment.org/e/changeset/68583
>
> Added:
>  trunk/PROTO/elev8/src/bin/init.js
> trunk/PROTO/elev8/src/modules/elm/elev8_elm.cc
> Removed:
>  trunk/PROTO/elev8/src/bin/module.cc
> trunk/PROTO/elev8/src/modules/elm/elev8_elm.cc
> Modified:
>  trunk/PROTO/elev8/src/bin/Makefile.am trunk/PROTO/elev8/src/bin/main.cc
> trunk/PROTO/elev8/src/modules/dbus/Makefile.am
> trunk/PROTO/elev8/src/modules/dbus/elev8_dbus.cc
> trunk/PROTO/elev8/src/modules/elm/Makefile.am
> trunk/PROTO/elev8/src/modules/http/Makefile.am
> trunk/PROTO/elev8/src/modules/http/elev8_http.cc
>
> Modified: trunk/PROTO/elev8/src/bin/Makefile.am
> ===================================================================
> --- trunk/PROTO/elev8/src/bin/Makefile.am       2012-03-01 17:25:54 UTC
> (rev 68582)
> +++ trunk/PROTO/elev8/src/bin/Makefile.am       2012-03-01 18:35:09 UTC
> (rev 68583)
> @@ -12,14 +12,15 @@
>  -DPACKAGE_TMP_DIR=\"/tmp\" \
>  @ELEV8_CFLAGS@
>
> -
>  bin_PROGRAMS = elev8
>
> +elev8libdir = $(libdir)/elev8
> +elev8lib_SCRIPTS = init.js
> +
>  elev8_SOURCES = \
>        main.cc \
>        elev8_utils.cc \
> -       downloader.cc \
> -       module.cc
> +       downloader.cc
>
>  elev8_LDADD = @ELEV8_LIBS@ @V8_LIBS@
>
>
> Modified: trunk/PROTO/elev8/src/bin/main.cc
> ===================================================================
> --- trunk/PROTO/elev8/src/bin/main.cc   2012-03-01 17:25:54 UTC (rev 68582)
> +++ trunk/PROTO/elev8/src/bin/main.cc   2012-03-01 18:35:09 UTC (rev 68583)
> @@ -5,7 +5,6 @@
>  * then exit
>  */
>
> -
>  #include <sys/mman.h>
>  #include <fcntl.h>
>  #include <downloader.h>
> @@ -16,13 +15,25 @@
>  using namespace v8;
>  int elev8_log_domain = -1;
>
> -/* FIXME */
> -void elm_v8_setup(Handle<ObjectTemplate> global);
> -int xmlhttp_v8_setup(Handle<ObjectTemplate> global);
> -int dbus_v8_setup(Handle<ObjectTemplate> global);
> +#define MODLOAD_ENV "MODPATH"
> +#define MODLOAD_ENV_DEFAULT_DIRS ".:" PACKAGE_LIB_DIR
>
> +static Persistent<Object> module_cache;
> +
> +static Handle<Value> require(const Arguments& args);
> +static Handle<Value> modules(const Arguments& args);
> +static Handle<Value> print(const Arguments& args);
> +
> +static void
> +add_symbols_to_context_global(Handle<ObjectTemplate> global)
> +{
> +   global->Set(String::NewSymbol("require"),
> FunctionTemplate::New(require));
> +   global->Set(String::NewSymbol("modules"),
> FunctionTemplate::New(modules));
> +   global->Set(String::NewSymbol("print"), FunctionTemplate::New(print));
> +}
> +
>  Handle<Value>
> -Print(const Arguments& args)
> +print(const Arguments& args)
>  {
>    for (int i = 0; i < args.Length(); i++)
>      {
> @@ -121,44 +132,193 @@
>  {
>    HandleScope handle_scope;
>
> -   if (filename == strstr(filename, "http"))
> +   if (!strncmp(filename, "http://";, 7))
>      {
>         INF("Downloading elev8 Script");
>         show_download_ui((void *)filename);
> +        return;
>      }
> -   else
> +
> +   /* load the script and run it */
> +   Handle<String> source = string_from_file(filename);
> +   if (source.IsEmpty())
>      {
> -        /* load the script and run it */
> -        //Handle<String> origin = String::New(filename);
> -        Handle<String> source = string_from_file(filename);
> -        if (source.IsEmpty())
> +        ERR("Failed to read source %s", filename);
> +        return;
> +     }
> +   compile_and_run(source);
> +}
> +
> +static char *
> +find_module_file_name(char *module_name, const char *prefix, const char
> *type)
> +{
> +   char *modpath = getenv(MODLOAD_ENV);
> +   char default_modpath[] = MODLOAD_ENV_DEFAULT_DIRS;
> +
> +   if (!modpath) modpath = default_modpath;
> +
> +   for (char *token, *rest, *ptr = modpath;
> +             (token = strtok_r(ptr, ":", &rest));
> +             ptr = rest)
> +      {
> +         char full_path[PATH_MAX];
> +
> +         if (snprintf(full_path, PATH_MAX - 1, "%s/%s%s.%s", token,
> prefix, module_name, type) < 0)
> +             return NULL;
> +
> +         if (!access(full_path, R_OK))
> +             return strdup(full_path);
> +      }
> +
> +   return NULL;
> +}
> +
> +inline static char *
> +find_native_module_file_name(char *module_name)
> +{
> +   return find_module_file_name(module_name, "lib", "so");
> +}
> +
> +inline static char *
> +find_js_module_file_name(char *module_name)
> +{
> +   return find_module_file_name(module_name, "", "js");
> +}
> +
> +static bool
> +module_native_load(Handle<String> module_name, Handle<Object> name_space)
> +{
> +   char *file_name =
> find_native_module_file_name(*String::AsciiValue(module_name));
> +
> +   if (!file_name) return false;
> +
> +   DBG("Loading native module: %s", file_name);
> +
> +   // FIXME: Use Eina_Module here.
> +   void *handle = dlopen(file_name, RTLD_LAZY);
> +   if (!handle)
> +     {
> +        free(file_name);
> +        return false;
> +     }
> +
> +   void (*init_func)(Handle<Object> name_space);
> +   init_func = (void (*)(Handle<Object>))dlsym(handle, "RegisterModule");
> +   if (!init_func)
> +     {
> +        free(file_name);
> +        dlclose(handle);
> +        return false;
> +     }
> +
> +   init_func(name_space);
> +
> +   name_space->Set(String::NewSymbol("__dl_handle"),
> External::Wrap(handle));
> +   name_space->Set(String::NewSymbol("__file_name"),
> String::New(file_name));
> +
> +   free(file_name);
> +   return true;
> +}
> +
> +static bool
> +module_js_load(Handle<String> module_name, Handle<Object> name_space)
> +{
> +   char *file_name =
> find_js_module_file_name(*String::AsciiValue(module_name));
> +
> +   if (!file_name) return false;
> +
> +   DBG("Loading JavaScript module: %s", file_name);
> +
> +   Handle<Value> mod_source = string_from_file(file_name);
> +   if (mod_source->IsUndefined())
> +     {
> +        free(file_name);
> +        return false;
> +     }
> +
> +   HandleScope handle_scope;
> +   Handle<ObjectTemplate> mod_global = ObjectTemplate::New();
> +
> +   mod_global->Set(String::NewSymbol("exports"), name_space);
> +   add_symbols_to_context_global(mod_global);
> +
> +   Persistent<Context> mod_context = Context::New(NULL, mod_global);
> +   Context::Scope mod_context_scope(mod_context);
> +
> +   TryCatch try_catch;
> +   Local<Script> mod_script = Script::Compile(mod_source->ToString());
> +   if (try_catch.HasCaught())
> +     {
> +        mod_context.Dispose();
> +        free(file_name);
> +        return false;
> +     }
> +
> +   mod_script->Run();
> +
> +   name_space->Set(String::NewSymbol("__file_name"),
> String::New(file_name));
> +   // FIXME: How to wrap mod_context so that t can be Disposed() properly?
> +
> +   free(file_name);
> +   return true;
> +}
> +
> +static Handle<Value>
> +require(const Arguments& args)
> +{
> +   HandleScope scope;
> +   Local<Object> name_space;
> +   Local<String> module_name;
> +
> +   if (args.Length() < 1)
> +     return
> scope.Close(ThrowException(Exception::Error(String::New("Module name
> missing"))));
> +
> +   module_name = args[0]->ToString();
> +
> +   if (module_cache->HasOwnProperty(module_name))
>

I did an apt-get update/upgrade and I did not find this in v8.h (version -
3.1.8.22) . So, my compile fails. The reference API page does provide this
API though.
Can you tell me which version of libv8 you have used? I would prefer to use
the API's provided as part of distro.


> +     return scope.Close(module_cache->Get(module_name));
> +
> +   name_space = Object::New();
> +   if (!module_native_load(module_name, name_space))
> +     {
> +        if (!module_js_load(module_name, name_space))
>           {
> -             ERR("Failed to read source %s", filename);
> -             return;
> +             Local<String> msg = String::Concat(String::New("Cannot load
> module: "), module_name);
> +             return scope.Close(ThrowException(Exception::Error(msg)));
>           }
> -        compile_and_run(source);
> -      }
> +     }
> +
> +   module_cache->Set(module_name, Persistent<Object>::New(name_space));
> +   return scope.Close(name_space);
>  }
>
> +static Handle<Value>
> +modules(const Arguments&)
> +{
> +   HandleScope scope;
> +   return scope.Close(module_cache);
> +}
> +
>  void
>  elev8_run(const char *script)
>  {
>    HandleScope handle_scope;
>    Handle<ObjectTemplate> global = ObjectTemplate::New();
>
> -   global->Set(String::New("print"), FunctionTemplate::New(Print));
> +   add_symbols_to_context_global(global);
>
> -   load_modules();
> -   init_modules(global);
> -
> -   /* setup V8 */
>    Persistent<Context> context = Context::New(NULL, global);
>    Context::Scope context_scope(context);
> +
> +   module_cache = Persistent<Object>::New(Object::New());
> +
> +   run_script(PACKAGE_LIB_DIR "/../init.js");
>    run_script(script);
>
>    ecore_main_loop_begin();
>
>    context.Dispose();
> +   module_cache.Dispose();
>  }
>
>  static void
>
> Modified: trunk/PROTO/elev8/src/modules/dbus/Makefile.am
> ===================================================================
> --- trunk/PROTO/elev8/src/modules/dbus/Makefile.am      2012-03-01
> 17:25:54 UTC (rev 68582)
> +++ trunk/PROTO/elev8/src/modules/dbus/Makefile.am      2012-03-01
> 18:35:09 UTC (rev 68583)
> @@ -12,10 +12,10 @@
>  @ELEV8_CFLAGS@
>
>  moddir = $(libdir)/$(PACKAGE)/$(MODULE_ARCH)
> -mod_LTLIBRARIES = libelev8-dbus.la
> +mod_LTLIBRARIES = libdbus.la
>
> -libelev8_dbus_la_SOURCES = elev8_dbus.cc
> +libdbus_la_SOURCES = elev8_dbus.cc
>
> -libelev8_dbus_la_LIBADD = @ELEV8_LIBS@ @V8_LIBS@
> -libelev8_dbus_la_LDFLAGS = -module -avoid-version -no-undefined
> -libelev8_dbus_la_LIBTOOLFLAGS = --tag=disable-static
> +libdbus_la_LIBADD = @ELEV8_LIBS@ @V8_LIBS@
> +libdbus_la_LDFLAGS = -module -avoid-version -no-undefined
> +libdbus_la_LIBTOOLFLAGS = --tag=disable-static
>
> Modified: trunk/PROTO/elev8/src/modules/dbus/elev8_dbus.cc
> ===================================================================
> --- trunk/PROTO/elev8/src/modules/dbus/elev8_dbus.cc    2012-03-01
> 17:25:54 UTC (rev 68582)
> +++ trunk/PROTO/elev8/src/modules/dbus/elev8_dbus.cc    2012-03-01
> 18:35:09 UTC (rev 68583)
> @@ -640,7 +640,7 @@
>    return EINA_TRUE;
>  }
>
> -Handle<Value> dbus_method_invoke(const Arguments &args)
> +Handle<Value> dbus_method_invoke(const Arguments&)
>  {
>    HandleScope scope;
>
> @@ -848,7 +848,8 @@
>    return dbus->obj;
>  }
>
> -int dbus_module_init(Handle<ObjectTemplate> global, void *data)
> +extern "C"
> +void RegisterModule(Handle<ObjectTemplate>)
>  {
>    elev8_dbus_log_domain = eina_log_domain_register("elev8-dbus",
> EINA_COLOR_ORANGE);
>    if (!elev8_dbus_log_domain)
> @@ -858,29 +859,10 @@
>      }
>    DBUS_INF("elev8-dbus Logging initialized. %d", elev8_dbus_log_domain);
>
> -   if (!e_dbus_init())
> +   if (e_dbus_init())
>      {
> -        DBUS_ERR( "Cannot Init to E_DBus");
> -        return -1;
> +        /* Add support for DBus Service Introspection */
> +        dbusObj = ObjectTemplate::New();
> +        dbusObj->SetInternalFieldCount(1);
>      }
> -
> -   /* Add support for DBus Service Introspection */
> -   dbusObj = ObjectTemplate::New();
> -   dbusObj->SetInternalFieldCount(1);
> -   global->Set(String::New("dbus"),
> FunctionTemplate::New(createDBusInstance));
> -   return 0;
>  }
> -
> -int dbus_module_shutdown(void *data)
> -{
> -   DBUS_INF("SHUTTING DOWN MODULE DBUS");
> -   return 0;
> -}
> -
> -extern "C"
> -void setup(module_info *mi)
> -{
> -   strcpy(mi->name,DBUS_MODULE_NAME);
> -   mi->init = &dbus_module_init;
> -   mi->deinit = &dbus_module_shutdown;
> -}
>
> Modified: trunk/PROTO/elev8/src/modules/elm/Makefile.am
> ===================================================================
> --- trunk/PROTO/elev8/src/modules/elm/Makefile.am       2012-03-01
> 17:25:54 UTC (rev 68582)
> +++ trunk/PROTO/elev8/src/modules/elm/Makefile.am       2012-03-01
> 18:35:09 UTC (rev 68583)
> @@ -12,10 +12,10 @@
>  @ELEV8_CFLAGS@
>
>  moddir = $(libdir)/$(PACKAGE)/$(MODULE_ARCH)
> -mod_LTLIBRARIES = libelev8-elm.la
> +mod_LTLIBRARIES = libelm.la
>
> -libelev8_elm_la_SOURCES = elev8_elm.cc
> +libelm_la_SOURCES = elev8_elm.cc
>
> -libelev8_elm_la_LIBADD = @ELEV8_LIBS@ @V8_LIBS@
> -libelev8_elm_la_LDFLAGS = -module -avoid-version -no-undefined
> -libelev8_elm_la_LIBTOOLFLAGS = --tag=disable-static
> +libelm_la_LIBADD = @ELEV8_LIBS@ @V8_LIBS@
> +libelm_la_LDFLAGS = -module -avoid-version -no-undefined
> +libelm_la_LIBTOOLFLAGS = --tag=disable-static
>
> Modified: trunk/PROTO/elev8/src/modules/http/Makefile.am
> ===================================================================
> --- trunk/PROTO/elev8/src/modules/http/Makefile.am      2012-03-01
> 17:25:54 UTC (rev 68582)
> +++ trunk/PROTO/elev8/src/modules/http/Makefile.am      2012-03-01
> 18:35:09 UTC (rev 68583)
> @@ -12,10 +12,10 @@
>  @ELEV8_CFLAGS@
>
>  moddir = $(libdir)/$(PACKAGE)/$(MODULE_ARCH)
> -mod_LTLIBRARIES = libelev8-http.la
> +mod_LTLIBRARIES = libhttp.la
>
> -libelev8_http_la_SOURCES = elev8_http.cc
> +libhttp_la_SOURCES = elev8_http.cc
>
> -libelev8_http_la_LIBADD = @ELEV8_LIBS@ @V8_LIBS@
> -libelev8_http_la_LDFLAGS = -module -avoid-version -no-undefined
> -libelev8_http_la_LIBTOOLFLAGS = --tag=disable-static
> +libhttp_la_LIBADD = @ELEV8_LIBS@ @V8_LIBS@
> +libhttp_la_LDFLAGS = -module -avoid-version -no-undefined
> +libhttp_la_LIBTOOLFLAGS = --tag=disable-static
>
> Modified: trunk/PROTO/elev8/src/modules/http/elev8_http.cc
> ===================================================================
> --- trunk/PROTO/elev8/src/modules/http/elev8_http.cc    2012-03-01
> 17:25:54 UTC (rev 68582)
> +++ trunk/PROTO/elev8/src/modules/http/elev8_http.cc    2012-03-01
> 18:35:09 UTC (rev 68583)
> @@ -367,7 +367,8 @@
>    return reqObj->obj;
>  }
>
> -int http_module_init(Handle<ObjectTemplate> global, void *data)
> +extern "C"
> +void RegisterModule(Handle<ObjectTemplate> target)
>  {
>    elev8_http_log_domain = eina_log_domain_register("elev8-http",
> EINA_COLOR_ORANGE);
>    if (!elev8_http_log_domain)
> @@ -377,32 +378,11 @@
>      }
>    HTTP_INF("elev8-http Logging initialized. %d", elev8_http_log_domain);
>
> -
> -   if (!ecore_con_url_init())
> +   if (ecore_con_url_init())
>      {
> -        HTTP_ERR( "Cannot Init to ECore_Url");
> -        return -1;
> +        /* Add support for XML HTTP Request */
> +        xmlHttpReqObj = ObjectTemplate::New();
> +        xmlHttpReqObj->SetInternalFieldCount(1);
> +        target->Set(String::NewSymbol("XMLHttpRequest"),
> FunctionTemplate::New(createXMLHttpReqInstance)->GetFunction());
>      }
> -
> -   //HTTP_INF(  "Creating XML Http Request Instance");
> -
> -   /* Add support for XML HTTP Request */
> -   xmlHttpReqObj = ObjectTemplate::New();
> -   xmlHttpReqObj->SetInternalFieldCount(1);
> -   global->Set(String::New("XMLHttpRequest"),
> FunctionTemplate::New(createXMLHttpReqInstance));
> -   return 0;
>  }
> -
> -int http_module_shutdown(void *data)
> -{
> -   HTTP_INF("SHUTTING DOWN MODULE HTTP");
> -   return 0;
> -}
> -
> -extern "C"
> -void setup(module_info *mi)
> -{
> -   strcpy(mi->name,HTTP_MODULE_NAME);
> -   mi->init = &http_module_init;
> -   mi->deinit = &http_module_shutdown;
> -}
>
>
>
> ------------------------------------------------------------------------------
> Virtualization & Cloud Management Using Capacity Planning
> Cloud computing makes use of virtualization - but cloud computing
> also focuses on allowing computing to be delivered as a service.
> http://www.accelacomm.com/jaw/sfnl/114/51521223/
> _______________________________________________
> enlightenment-svn mailing list
> enlightenment-...@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/enlightenment-svn
>
------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing 
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to