Skip to content

Commit 8ae7606

Browse files
author
Simon Best
committed
Refactor CommonJS modules functionality to store state in the extension globals and context as appropriate.
1 parent 46e509c commit 8ae7606

File tree

5 files changed

+212
-157
lines changed

5 files changed

+212
-157
lines changed

config.m4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ LDFLAGS=$old_LDFLAGS
6767
AC_DEFINE_UNQUOTED([PHP_V8_VERSION], "$ac_cv_v8_version", [ ])
6868
fi
6969

70-
PHP_NEW_EXTENSION(v8js, v8js.cc v8js_convert.cc v8js_methods.cc v8js_variables.cc, $ext_shared, , "-std=c++0x")
70+
PHP_NEW_EXTENSION(v8js, v8js.cc v8js_convert.cc v8js_methods.cc v8js_variables.cc v8js_commonjs.cc, $ext_shared, , "-std=c++0x")
7171

7272
PHP_ADD_MAKEFILE_FRAGMENT
7373
fi

php_v8js_macros.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,20 @@
2222
#ifndef PHP_V8JS_MACROS_H
2323
#define PHP_V8JS_MACROS_H
2424

25+
extern "C" {
26+
#include "php.h"
27+
#include "php_v8js.h"
28+
}
29+
2530
#include <v8.h>
2631

32+
#include <chrono>
33+
#include <stack>
34+
#include <thread>
35+
36+
#include <map>
37+
#include <vector>
38+
2739
/* V8Js Version */
2840
#define V8JS_VERSION "0.1.3"
2941

@@ -107,9 +119,47 @@ struct php_v8js_ctx {
107119
bool memory_limit_hit;
108120
v8::Persistent<v8::FunctionTemplate> global_template;
109121
zval *module_loader;
122+
std::vector<char *> modules_stack;
123+
std::vector<char *> modules_base;
110124
};
111125
/* }}} */
112126

127+
// Timer context
128+
struct php_v8js_timer_ctx
129+
{
130+
long time_limit;
131+
long memory_limit;
132+
std::chrono::time_point<std::chrono::high_resolution_clock> time_point;
133+
php_v8js_ctx *v8js_ctx;
134+
};
135+
136+
/* Module globals */
137+
ZEND_BEGIN_MODULE_GLOBALS(v8js)
138+
int v8_initialized;
139+
HashTable *extensions;
140+
int disposed_contexts; /* Disposed contexts since last time V8 did GC */
141+
142+
/* Ini globals */
143+
char *v8_flags; /* V8 command line flags */
144+
int max_disposed_contexts; /* Max disposed context allowed before forcing V8 GC */
145+
146+
// Timer thread globals
147+
std::stack<php_v8js_timer_ctx *> timer_stack;
148+
std::thread *timer_thread;
149+
std::mutex timer_mutex;
150+
bool timer_stop;
151+
152+
std::map<char *, v8::Handle<v8::Object> > modules_loaded;
153+
ZEND_END_MODULE_GLOBALS(v8js)
154+
155+
extern zend_v8js_globals v8js_globals;
156+
157+
#ifdef ZTS
158+
# define V8JSG(v) TSRMG(v8js_globals_id, zend_v8js_globals *, v)
159+
#else
160+
# define V8JSG(v) (v8js_globals.v)
161+
#endif
162+
113163
/* Register builtin methods into passed object */
114164
void php_v8js_register_methods(v8::Handle<v8::ObjectTemplate>, php_v8js_ctx *c);
115165

v8js.cc

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -25,59 +25,20 @@
2525
#include "config.h"
2626
#endif
2727

28+
#include "php_v8js_macros.h"
29+
2830
extern "C" {
29-
#include "php.h"
3031
#include "php_ini.h"
3132
#include "ext/standard/info.h"
3233
#include "ext/standard/php_string.h"
3334
#include "ext/standard/php_smart_str.h"
3435
#include "zend_exceptions.h"
35-
#include "php_v8js.h"
3636
}
3737

38-
#include <v8.h>
39-
#include "php_v8js_macros.h"
40-
41-
#include <chrono>
42-
#include <stack>
43-
#include <thread>
44-
4538
/* Forward declarations */
4639
static void php_v8js_throw_script_exception(v8::TryCatch * TSRMLS_DC);
4740
static void php_v8js_create_script_exception(zval *, v8::TryCatch * TSRMLS_DC);
4841

49-
// Timer context
50-
struct php_v8js_timer_ctx
51-
{
52-
long time_limit;
53-
long memory_limit;
54-
std::chrono::time_point<std::chrono::high_resolution_clock> time_point;
55-
php_v8js_ctx *v8js_ctx;
56-
};
57-
58-
/* Module globals */
59-
ZEND_BEGIN_MODULE_GLOBALS(v8js)
60-
int v8_initialized;
61-
HashTable *extensions;
62-
int disposed_contexts; /* Disposed contexts since last time V8 did GC */
63-
64-
/* Ini globals */
65-
char *v8_flags; /* V8 command line flags */
66-
int max_disposed_contexts; /* Max disposed context allowed before forcing V8 GC */
67-
68-
// Timer thread globals
69-
std::stack<php_v8js_timer_ctx *> timer_stack;
70-
std::thread *timer_thread;
71-
std::mutex timer_mutex;
72-
bool timer_stop;
73-
ZEND_END_MODULE_GLOBALS(v8js)
74-
75-
#ifdef ZTS
76-
# define V8JSG(v) TSRMG(v8js_globals_id, zend_v8js_globals *, v)
77-
#else
78-
# define V8JSG(v) (v8js_globals.v)
79-
#endif
80-
8142
ZEND_DECLARE_MODULE_GLOBALS(v8js)
8243

8344
/* {{{ INI Settings */

v8js_commonjs.cc

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| PHP Version 5 |
4+
+----------------------------------------------------------------------+
5+
| Copyright (c) 1997-2012 The PHP Group |
6+
+----------------------------------------------------------------------+
7+
| This source file is subject to version 3.01 of the PHP license, |
8+
| that is bundled with this package in the file LICENSE, and is |
9+
| available through the world-wide-web at the following url: |
10+
| http://www.php.net/license/3_01.txt |
11+
| If you did not receive a copy of the PHP license and are unable to |
12+
| obtain it through the world-wide-web, please send a note to |
13+
| license@php.net so we can mail you a copy immediately. |
14+
+----------------------------------------------------------------------+
15+
| Author: Simon Best <simonjbest@gmail.com> |
16+
+----------------------------------------------------------------------+
17+
*/
18+
19+
#ifdef HAVE_CONFIG_H
20+
#include "config.h"
21+
#endif
22+
23+
extern "C" {
24+
#include "php.h"
25+
#include "zend_exceptions.h"
26+
}
27+
28+
#include "php_v8js_macros.h"
29+
30+
void php_v8js_commonjs_split_terms(char *identifier, std::vector<char *> &terms)
31+
{
32+
char *term = (char *)malloc(PATH_MAX), *ptr = term;
33+
34+
// Initialise the term string
35+
*term = 0;
36+
37+
while (*identifier > 0) {
38+
if (*identifier == '/') {
39+
if (strlen(term) > 0) {
40+
// Terminate term string and add to terms vector
41+
*ptr++ = 0;
42+
terms.push_back(strdup(term));
43+
44+
// Reset term string
45+
memset(term, 0, strlen(term));
46+
ptr = term;
47+
}
48+
} else {
49+
*ptr++ = *identifier;
50+
}
51+
52+
identifier++;
53+
}
54+
55+
if (strlen(term) > 0) {
56+
// Terminate term string and add to terms vector
57+
*ptr++ = 0;
58+
terms.push_back(strdup(term));
59+
}
60+
61+
if (term > 0) {
62+
free(term);
63+
}
64+
}
65+
66+
void php_v8js_commonjs_normalise_identifier(char *base, char *identifier, char *normalised_path, char *module_name)
67+
{
68+
std::vector<char *> id_terms, terms;
69+
php_v8js_commonjs_split_terms(identifier, id_terms);
70+
71+
// If we have a relative module identifier then include the base terms
72+
if (!strcmp(id_terms.front(), ".") || !strcmp(id_terms.front(), "..")) {
73+
php_v8js_commonjs_split_terms(base, terms);
74+
}
75+
76+
terms.insert(terms.end(), id_terms.begin(), id_terms.end());
77+
78+
std::vector<char *> normalised_terms;
79+
80+
for (std::vector<char *>::iterator it = terms.begin(); it != terms.end(); it++) {
81+
char *term = *it;
82+
83+
if (!strcmp(term, "..")) {
84+
// Ignore parent term (..) if it's the first normalised term
85+
if (normalised_terms.size() > 0) {
86+
// Remove the parent normalized term
87+
normalised_terms.pop_back();
88+
}
89+
} else if (strcmp(term, ".")) {
90+
// Add the term if it's not the current term (.)
91+
normalised_terms.push_back(term);
92+
}
93+
}
94+
95+
// Initialise the normalised path string
96+
*normalised_path = 0;
97+
*module_name = 0;
98+
99+
strcat(module_name, normalised_terms.back());
100+
normalised_terms.pop_back();
101+
102+
for (std::vector<char *>::iterator it = normalised_terms.begin(); it != normalised_terms.end(); it++) {
103+
char *term = *it;
104+
105+
if (strlen(normalised_path) > 0) {
106+
strcat(normalised_path, "/");
107+
}
108+
109+
strcat(normalised_path, term);
110+
}
111+
}

0 commit comments

Comments
 (0)