7
7
using namespace v8 ;
8
8
using namespace node ;
9
9
10
+ Persistent<FunctionTemplate> node::Context::constructor_template;
11
+
12
+ void
13
+ node::Context::Initialize (Handle <Object> target)
14
+ {
15
+ HandleScope scope;
16
+
17
+ Local<FunctionTemplate> t = FunctionTemplate::New (node::Context::New);
18
+ constructor_template = Persistent<FunctionTemplate>::New (t);
19
+ constructor_template->InstanceTemplate ()->SetInternalFieldCount (1 );
20
+ constructor_template->SetClassName (String::NewSymbol (" Context" ));
21
+
22
+ target->Set (String::NewSymbol (" Context" ), constructor_template->GetFunction ());
23
+ }
24
+
25
+ Handle <Value>
26
+ node::Context::New (const Arguments& args)
27
+ {
28
+ HandleScope scope;
29
+
30
+ node::Context *t = new node::Context ();
31
+ t->Wrap (args.This ());
32
+
33
+ return args.This ();
34
+ }
35
+
36
+ node::Context::~Context () {
37
+ _context.Dispose ();
38
+ }
39
+
40
+ Local<Object>
41
+ node::Context::NewInstance ()
42
+ {
43
+ Local<Object> context = constructor_template->GetFunction ()->NewInstance ();
44
+ node::Context *nContext = ObjectWrap::Unwrap<node::Context>(context);
45
+ nContext->_context = v8::Context::New ();
46
+ return context;
47
+ }
48
+
49
+ v8::Persistent<v8::Context>
50
+ node::Context::GetV8Context ()
51
+ {
52
+ return _context;
53
+ }
54
+
55
+
10
56
Persistent<FunctionTemplate> node::Script::constructor_template;
11
57
12
58
void
@@ -19,8 +65,12 @@ node::Script::Initialize (Handle<Object> target)
19
65
constructor_template->InstanceTemplate ()->SetInternalFieldCount (1 );
20
66
constructor_template->SetClassName (String::NewSymbol (" Script" ));
21
67
68
+ NODE_SET_PROTOTYPE_METHOD (constructor_template, " createContext" , node::Script::CreateContext);
69
+ NODE_SET_PROTOTYPE_METHOD (constructor_template, " runInContext" , node::Script::RunInContext);
22
70
NODE_SET_PROTOTYPE_METHOD (constructor_template, " runInThisContext" , node::Script::RunInThisContext);
23
71
NODE_SET_PROTOTYPE_METHOD (constructor_template, " runInNewContext" , node::Script::RunInNewContext);
72
+ NODE_SET_METHOD (constructor_template, " createContext" , node::Script::CreateContext);
73
+ NODE_SET_METHOD (constructor_template, " runInContext" , node::Script::CompileRunInContext);
24
74
NODE_SET_METHOD (constructor_template, " runInThisContext" , node::Script::CompileRunInThisContext);
25
75
NODE_SET_METHOD (constructor_template, " runInNewContext" , node::Script::CompileRunInNewContext);
26
76
@@ -44,6 +94,37 @@ node::Script::~Script() {
44
94
}
45
95
46
96
97
+ Handle <Value>
98
+ node::Script::CreateContext (const Arguments& args)
99
+ {
100
+ HandleScope scope;
101
+
102
+ Local<v8::Object> context = node::Context::NewInstance ();
103
+
104
+ if (args.Length () > 0 ) {
105
+
106
+ Local<Object> sandbox = args[0 ]->ToObject ();
107
+ Local<Array> keys = sandbox->GetPropertyNames ();
108
+
109
+ for (int i = 0 ; i < keys->Length (); i++) {
110
+ Handle <String> key = keys->Get (Integer::New (i))->ToString ();
111
+ Handle <Value> value = sandbox->Get (key);
112
+ context->Set (key, value);
113
+ }
114
+ }
115
+
116
+
117
+ return scope.Close (context);
118
+ }
119
+
120
+ Handle <Value>
121
+ node::Script::RunInContext (const Arguments& args)
122
+ {
123
+ return
124
+ node::Script::EvalMachine<unwrapExternal, userContext, returnResult>(args);
125
+ }
126
+
127
+
47
128
Handle <Value>
48
129
node::Script::RunInThisContext (const Arguments& args)
49
130
{
@@ -59,6 +140,14 @@ node::Script::RunInNewContext(const Arguments& args) {
59
140
}
60
141
61
142
143
+ Handle <Value>
144
+ node::Script::CompileRunInContext (const Arguments& args)
145
+ {
146
+ return
147
+ node::Script::EvalMachine<compileCode, userContext, returnResult>(args);
148
+ }
149
+
150
+
62
151
Handle <Value>
63
152
node::Script::CompileRunInThisContext (const Arguments& args)
64
153
{
@@ -91,29 +180,50 @@ Handle<Value> node::Script::EvalMachine(const Arguments& args) {
91
180
));
92
181
}
93
182
183
+ const int sbIndex = iFlag == compileCode ? 1 : 0 ;
184
+ if (cFlag == userContext && args.Length () < (sbIndex + 1 )) {
185
+ return ThrowException (Exception::TypeError (
186
+ String::New (" needs a 'context' argument." )
187
+ ));
188
+ }
189
+
190
+
94
191
Local<String> code;
95
192
if (iFlag == compileCode) { code = args[0 ]->ToString (); }
96
193
97
194
Local<Object> sandbox;
98
- const int sbIndex = iFlag == compileCode ? 1 : 0 ;
99
195
if (cFlag == newContext) {
100
196
sandbox = args.Length () > sbIndex ? args[sbIndex]->ToObject () : Object::New ();
101
197
}
198
+ else if (cFlag == userContext) {
199
+ sandbox = args[sbIndex]->ToObject ();
200
+ }
102
201
const int fnIndex = sbIndex + (cFlag == newContext ? 1 : 0 );
103
202
Local<String> filename = args.Length () > fnIndex ? args[fnIndex]->ToString ()
104
203
: String::New (" evalmachine.<anonymous>" );
105
204
106
- Persistent<Context> context;
205
+ Persistent<v8:: Context> context;
107
206
Local<Array> keys;
108
207
unsigned int i;
109
208
if (cFlag == newContext) {
110
209
// Create the new context
111
- context = Context::New ();
210
+ context = v8:: Context::New ();
112
211
113
- // Enter and compile script
212
+ } else if (cFlag == userContext) {
213
+ // Use the passed in context
214
+ Local<Object> contextArg = args[sbIndex]->ToObject ();
215
+ node::Context *nContext = ObjectWrap::Unwrap<node::Context>(sandbox);
216
+ context = nContext->GetV8Context ();
217
+ }
218
+
219
+ // New and user context share code. DRY it up.
220
+ if (cFlag == userContext || cFlag == newContext) {
221
+
222
+ // Enter the context
114
223
context->Enter ();
115
224
116
- // Copy objects from global context, to our brand new context
225
+ // Copy everything from the passed in sandbox (either the persistent
226
+ // context for runInContext(), or the sandbox arg to runInNewContext()).
117
227
keys = sandbox->GetPropertyNames ();
118
228
119
229
for (i = 0 ; i < keys->Length (); i++) {
@@ -167,7 +277,7 @@ Handle<Value> node::Script::EvalMachine(const Arguments& args) {
167
277
}
168
278
if (result.IsEmpty ()) {
169
279
return try_catch.ReThrow ();
170
- } else if (cFlag == newContext) {
280
+ } else if (cFlag == userContext || cFlag == newContext) {
171
281
// success! copy changes back onto the sandbox object.
172
282
keys = context->Global ()->GetPropertyNames ();
173
283
for (i = 0 ; i < keys->Length (); i++) {
@@ -183,6 +293,9 @@ Handle<Value> node::Script::EvalMachine(const Arguments& args) {
183
293
context->DetachGlobal ();
184
294
context->Exit ();
185
295
context.Dispose ();
296
+ } else if (cFlag == userContext) {
297
+ // Exit the passed in context.
298
+ context->Exit ();
186
299
}
187
300
188
301
return result == args.This () ? result : scope.Close (result);
0 commit comments