@@ -48,40 +48,29 @@ using v8::WeakCallbackData;
48
48
49
49
class ContextifyContext {
50
50
protected:
51
- enum Kind {
52
- kSandbox ,
53
- kContext
54
- };
51
+ // V8 reserves the first field in context objects for the debugger. We use the
52
+ // second field to hold a reference to the sandbox object.
53
+ enum { kSandboxObjectIndex = 1 };
55
54
56
55
Environment* const env_;
57
- Persistent<Object> sandbox_;
58
56
Persistent<Context> context_;
59
- int references_;
60
57
61
58
public:
62
- explicit ContextifyContext (Environment* env, Local<Object> sandbox)
63
- : env_(env),
64
- sandbox_(env->isolate (), sandbox),
65
- // Wait for sandbox_ and context_ to die
66
- references_(0 ) {
67
- context_.Reset (env->isolate (), CreateV8Context (env));
68
-
69
- sandbox_.SetWeak (this , WeakCallback<Object, kSandbox >);
70
- sandbox_.MarkIndependent ();
71
- references_++;
59
+ explicit ContextifyContext (Environment* env, Local<Object> sandbox_obj)
60
+ : env_(env) {
61
+ Local<Context> v8_context = CreateV8Context (env, sandbox_obj);
62
+ context_.Reset (env->isolate (), v8_context);
72
63
73
64
// Allocation failure or maximum call stack size reached
74
65
if (context_.IsEmpty ())
75
66
return ;
76
- context_.SetWeak (this , WeakCallback<Context, kContext >);
67
+ context_.SetWeak (this , WeakCallback<Context>);
77
68
context_.MarkIndependent ();
78
- references_++;
79
69
}
80
70
81
71
82
72
~ContextifyContext () {
83
73
context_.Reset ();
84
- sandbox_.Reset ();
85
74
}
86
75
87
76
@@ -99,6 +88,11 @@ class ContextifyContext {
99
88
return context ()->Global ();
100
89
}
101
90
91
+
92
+ inline Local<Object> sandbox () const {
93
+ return Local<Object>::Cast (context ()->GetEmbedderData (kSandboxObjectIndex ));
94
+ }
95
+
102
96
// XXX(isaacs): This function only exists because of a shortcoming of
103
97
// the V8 SetNamedPropertyHandler function.
104
98
//
@@ -126,15 +120,14 @@ class ContextifyContext {
126
120
Local<Context> context = PersistentToLocal (env ()->isolate (), context_);
127
121
Local<Object> global =
128
122
context->Global ()->GetPrototype ()->ToObject (env ()->isolate ());
129
- Local<Object> sandbox = PersistentToLocal (env ()->isolate (), sandbox_);
130
123
131
124
Local<Function> clone_property_method;
132
125
133
126
Local<Array> names = global->GetOwnPropertyNames ();
134
127
int length = names->Length ();
135
128
for (int i = 0 ; i < length; i++) {
136
129
Local<String> key = names->Get (i)->ToString (env ()->isolate ());
137
- bool has = sandbox->HasOwnProperty (key);
130
+ bool has = sandbox () ->HasOwnProperty (context, key). FromJust ( );
138
131
if (!has) {
139
132
// Could also do this like so:
140
133
//
@@ -167,7 +160,7 @@ class ContextifyContext {
167
160
clone_property_method = Local<Function>::Cast (script->Run ());
168
161
CHECK (clone_property_method->IsFunction ());
169
162
}
170
- Local<Value> args[] = { global, key, sandbox };
163
+ Local<Value> args[] = { global, key, sandbox () };
171
164
clone_property_method->Call (global, ARRAY_SIZE (args), args);
172
165
}
173
166
}
@@ -191,14 +184,13 @@ class ContextifyContext {
191
184
}
192
185
193
186
194
- Local<Context> CreateV8Context (Environment* env) {
187
+ Local<Context> CreateV8Context (Environment* env, Local<Object> sandbox_obj ) {
195
188
EscapableHandleScope scope (env->isolate ());
196
189
Local<FunctionTemplate> function_template =
197
190
FunctionTemplate::New (env->isolate ());
198
191
function_template->SetHiddenPrototype (true );
199
192
200
- Local<Object> sandbox = PersistentToLocal (env->isolate (), sandbox_);
201
- function_template->SetClassName (sandbox->GetConstructorName ());
193
+ function_template->SetClassName (sandbox_obj->GetConstructorName ());
202
194
203
195
Local<ObjectTemplate> object_template =
204
196
function_template->InstanceTemplate ();
@@ -215,6 +207,7 @@ class ContextifyContext {
215
207
216
208
CHECK (!ctx.IsEmpty ());
217
209
ctx->SetSecurityToken (env->context ()->GetSecurityToken ());
210
+ ctx->SetEmbedderData (kSandboxObjectIndex , sandbox_obj);
218
211
219
212
env->AssignToContext (ctx);
220
213
@@ -309,16 +302,11 @@ class ContextifyContext {
309
302
}
310
303
311
304
312
- template <class T , Kind kind >
305
+ template <class T >
313
306
static void WeakCallback (const WeakCallbackData<T, ContextifyContext>& data) {
314
307
ContextifyContext* context = data.GetParameter ();
315
- if (kind == kSandbox )
316
- context->sandbox_ .ClearWeak ();
317
- else
318
- context->context_ .ClearWeak ();
319
-
320
- if (--context->references_ == 0 )
321
- delete context;
308
+ context->context_ .ClearWeak ();
309
+ delete context;
322
310
}
323
311
324
312
@@ -340,26 +328,23 @@ class ContextifyContext {
340
328
static void GlobalPropertyGetterCallback (
341
329
Local<Name> property,
342
330
const PropertyCallbackInfo<Value>& args) {
343
- Isolate* isolate = args.GetIsolate ();
344
-
345
331
ContextifyContext* ctx =
346
332
Unwrap<ContextifyContext>(args.Data ().As <Object>());
347
333
348
334
// Stil initializing
349
335
if (ctx->context_ .IsEmpty ())
350
336
return ;
351
337
352
- Local<Object> sandbox = PersistentToLocal (isolate, ctx->sandbox_ );
353
338
MaybeLocal<Value> maybe_rv =
354
- sandbox->GetRealNamedProperty (ctx->context (), property);
339
+ ctx-> sandbox () ->GetRealNamedProperty (ctx->context (), property);
355
340
if (maybe_rv.IsEmpty ()) {
356
341
maybe_rv =
357
342
ctx->global_proxy ()->GetRealNamedProperty (ctx->context (), property);
358
343
}
359
344
360
345
Local<Value> rv;
361
346
if (maybe_rv.ToLocal (&rv)) {
362
- if (rv == ctx->sandbox_ )
347
+ if (rv == ctx->sandbox () )
363
348
rv = ctx->global_proxy ();
364
349
365
350
args.GetReturnValue ().Set (rv);
@@ -371,34 +356,30 @@ class ContextifyContext {
371
356
Local<Name> property,
372
357
Local<Value> value,
373
358
const PropertyCallbackInfo<Value>& args) {
374
- Isolate* isolate = args.GetIsolate ();
375
-
376
359
ContextifyContext* ctx =
377
360
Unwrap<ContextifyContext>(args.Data ().As <Object>());
378
361
379
362
// Stil initializing
380
363
if (ctx->context_ .IsEmpty ())
381
364
return ;
382
365
383
- PersistentToLocal (isolate, ctx->sandbox_ )->Set (property, value);
366
+ ctx->sandbox ( )->Set (property, value);
384
367
}
385
368
386
369
387
370
static void GlobalPropertyQueryCallback (
388
371
Local<Name> property,
389
372
const PropertyCallbackInfo<Integer>& args) {
390
- Isolate* isolate = args.GetIsolate ();
391
-
392
373
ContextifyContext* ctx =
393
374
Unwrap<ContextifyContext>(args.Data ().As <Object>());
394
375
395
376
// Stil initializing
396
377
if (ctx->context_ .IsEmpty ())
397
378
return ;
398
379
399
- Local<Object> sandbox = PersistentToLocal (isolate, ctx->sandbox_ );
400
380
Maybe<PropertyAttribute> maybe_prop_attr =
401
- sandbox->GetRealNamedPropertyAttributes (ctx->context (), property);
381
+ ctx->sandbox ()->GetRealNamedPropertyAttributes (ctx->context (),
382
+ property);
402
383
403
384
if (maybe_prop_attr.IsNothing ()) {
404
385
maybe_prop_attr =
@@ -416,18 +397,14 @@ class ContextifyContext {
416
397
static void GlobalPropertyDeleterCallback (
417
398
Local<Name> property,
418
399
const PropertyCallbackInfo<Boolean >& args) {
419
- Isolate* isolate = args.GetIsolate ();
420
-
421
400
ContextifyContext* ctx =
422
401
Unwrap<ContextifyContext>(args.Data ().As <Object>());
423
402
424
403
// Stil initializing
425
404
if (ctx->context_ .IsEmpty ())
426
405
return ;
427
406
428
- Local<Object> sandbox = PersistentToLocal (isolate, ctx->sandbox_ );
429
-
430
- Maybe<bool > success = sandbox->Delete (ctx->context (), property);
407
+ Maybe<bool > success = ctx->sandbox ()->Delete (ctx->context (), property);
431
408
432
409
if (success.IsJust ())
433
410
args.GetReturnValue ().Set (success.FromJust ());
@@ -443,8 +420,7 @@ class ContextifyContext {
443
420
if (ctx->context_ .IsEmpty ())
444
421
return ;
445
422
446
- Local<Object> sandbox = PersistentToLocal (args.GetIsolate (), ctx->sandbox_ );
447
- args.GetReturnValue ().Set (sandbox->GetPropertyNames ());
423
+ args.GetReturnValue ().Set (ctx->sandbox ()->GetPropertyNames ());
448
424
}
449
425
};
450
426
0 commit comments