@@ -48,40 +48,29 @@ using v8::WeakCallbackData;
4848
4949class ContextifyContext {
5050 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 };
5554
5655 Environment* const env_;
57- Persistent<Object> sandbox_;
5856 Persistent<Context> context_;
59- int references_;
6057
6158 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);
7263
7364 // Allocation failure or maximum call stack size reached
7465 if (context_.IsEmpty ())
7566 return ;
76- context_.SetWeak (this , WeakCallback<Context, kContext >);
67+ context_.SetWeak (this , WeakCallback<Context>);
7768 context_.MarkIndependent ();
78- references_++;
7969 }
8070
8171
8272 ~ContextifyContext () {
8373 context_.Reset ();
84- sandbox_.Reset ();
8574 }
8675
8776
@@ -99,6 +88,11 @@ class ContextifyContext {
9988 return context ()->Global ();
10089 }
10190
91+
92+ inline Local<Object> sandbox () const {
93+ return Local<Object>::Cast (context ()->GetEmbedderData (kSandboxObjectIndex ));
94+ }
95+
10296 // XXX(isaacs): This function only exists because of a shortcoming of
10397 // the V8 SetNamedPropertyHandler function.
10498 //
@@ -126,15 +120,14 @@ class ContextifyContext {
126120 Local<Context> context = PersistentToLocal (env ()->isolate (), context_);
127121 Local<Object> global =
128122 context->Global ()->GetPrototype ()->ToObject (env ()->isolate ());
129- Local<Object> sandbox = PersistentToLocal (env ()->isolate (), sandbox_);
130123
131124 Local<Function> clone_property_method;
132125
133126 Local<Array> names = global->GetOwnPropertyNames ();
134127 int length = names->Length ();
135128 for (int i = 0 ; i < length; i++) {
136129 Local<String> key = names->Get (i)->ToString (env ()->isolate ());
137- bool has = sandbox->HasOwnProperty (key);
130+ bool has = sandbox () ->HasOwnProperty (context, key). FromJust ( );
138131 if (!has) {
139132 // Could also do this like so:
140133 //
@@ -167,7 +160,7 @@ class ContextifyContext {
167160 clone_property_method = Local<Function>::Cast (script->Run ());
168161 CHECK (clone_property_method->IsFunction ());
169162 }
170- Local<Value> args[] = { global, key, sandbox };
163+ Local<Value> args[] = { global, key, sandbox () };
171164 clone_property_method->Call (global, ARRAY_SIZE (args), args);
172165 }
173166 }
@@ -191,14 +184,13 @@ class ContextifyContext {
191184 }
192185
193186
194- Local<Context> CreateV8Context (Environment* env) {
187+ Local<Context> CreateV8Context (Environment* env, Local<Object> sandbox_obj ) {
195188 EscapableHandleScope scope (env->isolate ());
196189 Local<FunctionTemplate> function_template =
197190 FunctionTemplate::New (env->isolate ());
198191 function_template->SetHiddenPrototype (true );
199192
200- Local<Object> sandbox = PersistentToLocal (env->isolate (), sandbox_);
201- function_template->SetClassName (sandbox->GetConstructorName ());
193+ function_template->SetClassName (sandbox_obj->GetConstructorName ());
202194
203195 Local<ObjectTemplate> object_template =
204196 function_template->InstanceTemplate ();
@@ -215,6 +207,7 @@ class ContextifyContext {
215207
216208 CHECK (!ctx.IsEmpty ());
217209 ctx->SetSecurityToken (env->context ()->GetSecurityToken ());
210+ ctx->SetEmbedderData (kSandboxObjectIndex , sandbox_obj);
218211
219212 env->AssignToContext (ctx);
220213
@@ -309,16 +302,11 @@ class ContextifyContext {
309302 }
310303
311304
312- template <class T , Kind kind >
305+ template <class T >
313306 static void WeakCallback (const WeakCallbackData<T, ContextifyContext>& data) {
314307 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;
322310 }
323311
324312
@@ -340,26 +328,23 @@ class ContextifyContext {
340328 static void GlobalPropertyGetterCallback (
341329 Local<Name> property,
342330 const PropertyCallbackInfo<Value>& args) {
343- Isolate* isolate = args.GetIsolate ();
344-
345331 ContextifyContext* ctx =
346332 Unwrap<ContextifyContext>(args.Data ().As <Object>());
347333
348334 // Stil initializing
349335 if (ctx->context_ .IsEmpty ())
350336 return ;
351337
352- Local<Object> sandbox = PersistentToLocal (isolate, ctx->sandbox_ );
353338 MaybeLocal<Value> maybe_rv =
354- sandbox->GetRealNamedProperty (ctx->context (), property);
339+ ctx-> sandbox () ->GetRealNamedProperty (ctx->context (), property);
355340 if (maybe_rv.IsEmpty ()) {
356341 maybe_rv =
357342 ctx->global_proxy ()->GetRealNamedProperty (ctx->context (), property);
358343 }
359344
360345 Local<Value> rv;
361346 if (maybe_rv.ToLocal (&rv)) {
362- if (rv == ctx->sandbox_ )
347+ if (rv == ctx->sandbox () )
363348 rv = ctx->global_proxy ();
364349
365350 args.GetReturnValue ().Set (rv);
@@ -371,34 +356,30 @@ class ContextifyContext {
371356 Local<Name> property,
372357 Local<Value> value,
373358 const PropertyCallbackInfo<Value>& args) {
374- Isolate* isolate = args.GetIsolate ();
375-
376359 ContextifyContext* ctx =
377360 Unwrap<ContextifyContext>(args.Data ().As <Object>());
378361
379362 // Stil initializing
380363 if (ctx->context_ .IsEmpty ())
381364 return ;
382365
383- PersistentToLocal (isolate, ctx->sandbox_ )->Set (property, value);
366+ ctx->sandbox ( )->Set (property, value);
384367 }
385368
386369
387370 static void GlobalPropertyQueryCallback (
388371 Local<Name> property,
389372 const PropertyCallbackInfo<Integer>& args) {
390- Isolate* isolate = args.GetIsolate ();
391-
392373 ContextifyContext* ctx =
393374 Unwrap<ContextifyContext>(args.Data ().As <Object>());
394375
395376 // Stil initializing
396377 if (ctx->context_ .IsEmpty ())
397378 return ;
398379
399- Local<Object> sandbox = PersistentToLocal (isolate, ctx->sandbox_ );
400380 Maybe<PropertyAttribute> maybe_prop_attr =
401- sandbox->GetRealNamedPropertyAttributes (ctx->context (), property);
381+ ctx->sandbox ()->GetRealNamedPropertyAttributes (ctx->context (),
382+ property);
402383
403384 if (maybe_prop_attr.IsNothing ()) {
404385 maybe_prop_attr =
@@ -416,18 +397,14 @@ class ContextifyContext {
416397 static void GlobalPropertyDeleterCallback (
417398 Local<Name> property,
418399 const PropertyCallbackInfo<Boolean>& args) {
419- Isolate* isolate = args.GetIsolate ();
420-
421400 ContextifyContext* ctx =
422401 Unwrap<ContextifyContext>(args.Data ().As <Object>());
423402
424403 // Stil initializing
425404 if (ctx->context_ .IsEmpty ())
426405 return ;
427406
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);
431408
432409 if (success.IsJust ())
433410 args.GetReturnValue ().Set (success.FromJust ());
@@ -443,8 +420,7 @@ class ContextifyContext {
443420 if (ctx->context_ .IsEmpty ())
444421 return ;
445422
446- Local<Object> sandbox = PersistentToLocal (args.GetIsolate (), ctx->sandbox_ );
447- args.GetReturnValue ().Set (sandbox->GetPropertyNames ());
423+ args.GetReturnValue ().Set (ctx->sandbox ()->GetPropertyNames ());
448424 }
449425};
450426
0 commit comments