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