Browse Source

allow modules to return arbitrary values

Stefan Siegl 7 years ago
parent
commit
1c7e355937
4 changed files with 36 additions and 6 deletions
  1. 29 0
      tests/commonjs_node_compat_002.phpt
  2. 2 2
      v8js_class.cc
  3. 2 1
      v8js_class.h
  4. 3 3
      v8js_methods.cc

+ 29 - 0
tests/commonjs_node_compat_002.phpt

@@ -0,0 +1,29 @@
+--TEST--
+Test V8Js::setModuleLoader : modules can return arbitrary values
+--SKIPIF--
+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
+--FILE--
+<?php
+
+$v8 = new V8Js();
+
+$v8->setModuleLoader(function ($moduleName) {
+    return <<<'EOJS'
+        module.exports = 23;
+EOJS
+    ;
+});
+
+$v8->executeString(<<<'EOJS'
+    var result = require('foo');
+    var_dump(typeof result);
+    var_dump(result);
+EOJS
+);
+
+?>
+===EOF===
+--EXPECT--
+string(6) "number"
+int(23)
+===EOF===

+ 2 - 2
v8js_class.cc

@@ -182,7 +182,7 @@ static void v8js_free_storage(zend_object *object) /* {{{ */
 	c->script_objects.~vector();
 
 	/* Clear persistent handles in module cache */
-	for (std::map<char *, v8js_persistent_obj_t>::iterator it = c->modules_loaded.begin();
+	for (std::map<char *, v8js_persistent_value_t>::iterator it = c->modules_loaded.begin();
 		 it != c->modules_loaded.end(); ++it) {
 		efree(it->first);
 		it->second.Reset();
@@ -227,7 +227,7 @@ static zend_object* v8js_new(zend_class_entry *ce) /* {{{ */
 
 	new(&c->modules_stack) std::vector<char*>();
 	new(&c->modules_base) std::vector<char*>();
-	new(&c->modules_loaded) std::map<char *, v8js_persistent_obj_t, cmp_str>;
+	new(&c->modules_loaded) std::map<char *, v8js_persistent_value_t, cmp_str>;
 
 	new(&c->template_cache) std::map<const zend_string *,v8js_function_tmpl_t>();
 	new(&c->accessor_list) std::vector<v8js_accessor_ctx *>();

+ 2 - 1
v8js_class.h

@@ -20,6 +20,7 @@
 typedef v8::Persistent<v8::FunctionTemplate, v8::CopyablePersistentTraits<v8::FunctionTemplate> > v8js_function_tmpl_t;
 typedef v8::Persistent<v8::ObjectTemplate, v8::CopyablePersistentTraits<v8::ObjectTemplate> > v8js_object_tmpl_t;
 typedef v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> > v8js_persistent_obj_t;
+typedef v8::Persistent<v8::Value, v8::CopyablePersistentTraits<v8::Value> > v8js_persistent_value_t;
 
 /* Forward declarations */
 struct v8js_v8object;
@@ -57,7 +58,7 @@ struct v8js_ctx {
 
   std::vector<char *> modules_stack;
   std::vector<char *> modules_base;
-  std::map<char *, v8js_persistent_obj_t, cmp_str> modules_loaded;
+  std::map<char *, v8js_persistent_value_t, cmp_str> modules_loaded;
   std::map<const zend_string *,v8js_function_tmpl_t> template_cache;
 
   std::map<zend_object *, v8js_persistent_obj_t> weak_objects;

+ 3 - 3
v8js_methods.cc

@@ -336,7 +336,7 @@ V8JS_METHOD(require)
 
     // If we have already loaded and cached this module then use it
 	if (c->modules_loaded.count(normalised_module_id) > 0) {
-		v8::Persistent<v8::Object> newobj;
+		v8::Persistent<v8::Value> newobj;
 		newobj.Reset(isolate, c->modules_loaded[normalised_module_id]);
 		info.GetReturnValue().Set(newobj);
 
@@ -492,12 +492,12 @@ V8JS_METHOD(require)
 		return;
 	}
 
-	v8::Local<v8::Object> newobj;
+	v8::Local<v8::Value> newobj;
 
 	// Cache the module so it doesn't need to be compiled and run again
 	// Ensure compatibility with CommonJS implementations such as NodeJS by playing nicely with module.exports and exports
 	if (module->Has(V8JS_SYM("exports"))) {
-		newobj = module->Get(V8JS_SYM("exports"))->ToObject();
+		newobj = module->Get(V8JS_SYM("exports"));
 	}
 
 	c->modules_loaded[normalised_module_id].Reset(isolate, newobj);