浏览代码

Provide key compare function for modules_loaded

Without the compare function std::map simply compares one
pointer to another.  However we need to compare the actual
strings.

Besides we must not efree normalised_module_id on return
of require method, since the pointer was added to
modules_loaded (and is valid until destruction of V8Js
class); instead it is now freed during V8Js object destruction.
Stefan Siegl 9 年之前
父节点
当前提交
3d89f0250d
共有 4 个文件被更改,包括 35 次插入3 次删除
  1. 26 0
      tests/commonjs_modules_caching.phpt
  2. 2 1
      v8js_class.cc
  3. 7 1
      v8js_class.h
  4. 0 1
      v8js_methods.cc

+ 26 - 0
tests/commonjs_modules_caching.phpt

@@ -0,0 +1,26 @@
+--TEST--
+Test V8Js::setModuleLoader : Returned modules are cached
+--SKIPIF--
+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
+--FILE--
+<?php
+
+$JS = <<< EOT
+var foo = require("test");
+var bar = require("test2");
+var baz = require("test");
+EOT;
+
+$v8 = new V8Js();
+$v8->setModuleLoader(function($module) {
+    print("setModuleLoader called for ".$module."\n");
+    return 'exports.bar = 23;';
+});
+
+$v8->executeString($JS, 'module.js');
+?>
+===EOF===
+--EXPECT--
+setModuleLoader called for test
+setModuleLoader called for test2
+===EOF===

+ 2 - 1
v8js_class.cc

@@ -156,6 +156,7 @@ static void v8js_free_storage(void *object TSRMLS_DC) /* {{{ */
 	/* Clear persistent handles in module cache */
 	for (std::map<char *, v8js_persistent_obj_t>::iterator it = c->modules_loaded.begin();
 		 it != c->modules_loaded.end(); ++it) {
+		efree(it->first);
 		it->second.Reset();
 	}
 	c->modules_loaded.~map();
@@ -200,7 +201,7 @@ static zend_object_value v8js_new(zend_class_entry *ce TSRMLS_DC) /* {{{ */
 
 	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>;
+	new(&c->modules_loaded) std::map<char *, v8js_persistent_obj_t, cmp_str>;
 
 	new(&c->template_cache) std::map<const char *,v8js_tmpl_t>();
 	new(&c->accessor_list) std::vector<v8js_accessor_ctx *>();

+ 7 - 1
v8js_class.h

@@ -23,6 +23,12 @@ typedef v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> > v8
 struct v8js_v8object;
 struct v8js_accessor_ctx;
 
+struct cmp_str {
+    bool operator()(char const *a, char const *b) const {
+        return strcmp(a, b) < 0;
+    }
+};
+
 /* {{{ Context container */
 struct v8js_ctx {
   zend_object std;
@@ -43,7 +49,7 @@ struct v8js_ctx {
   zval *module_loader;
   std::vector<char *> modules_stack;
   std::vector<char *> modules_base;
-  std::map<char *, v8js_persistent_obj_t> modules_loaded;
+  std::map<char *, v8js_persistent_obj_t, cmp_str> modules_loaded;
   std::map<const char *,v8js_tmpl_t> template_cache;
 
   std::map<zval *, v8js_persistent_obj_t> weak_objects;

+ 0 - 1
v8js_methods.cc

@@ -398,7 +398,6 @@ V8JS_METHOD(require)
 
 	c->modules_loaded[normalised_module_id].Reset(isolate, newobj);
 	info.GetReturnValue().Set(newobj);
-	efree(normalised_module_id);
 }
 
 void v8js_register_methods(v8::Handle<v8::ObjectTemplate> global, v8js_ctx *c) /* {{{ */