@@ -50,40 +50,29 @@ using v8::WeakCallbackData;
5050
5151class ContextifyContext {
5252 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 };
5756
5857 Environment* const env_;
59- Persistent<Object> sandbox_;
6058 Persistent<Context> context_;
61- int references_;
6259
6360 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);
7465
7566 // Allocation failure or maximum call stack size reached
7667 if (context_.IsEmpty ())
7768 return ;
78- context_.SetWeak (this , WeakCallback<Context, kContext >);
69+ context_.SetWeak (this , WeakCallback<Context>);
7970 context_.MarkIndependent ();
80- references_++;
8171 }
8272
8373
8474 ~ContextifyContext () {
8575 context_.Reset ();
86- sandbox_.Reset ();
8776 }
8877
8978
@@ -101,6 +90,11 @@ class ContextifyContext {
10190 return context ()->Global ();
10291 }
10392
93+
94+ inline Local<Object> sandbox () const {
95+ return Local<Object>::Cast (context ()->GetEmbedderData (kSandboxObjectIndex ));
96+ }
97+
10498 // XXX(isaacs): This function only exists because of a shortcoming of
10599 // the V8 SetNamedPropertyHandler function.
106100 //
@@ -128,15 +122,14 @@ class ContextifyContext {
128122 Local<Context> context = PersistentToLocal (env ()->isolate (), context_);
129123 Local<Object> global =
130124 context->Global ()->GetPrototype ()->ToObject (env ()->isolate ());
131- Local<Object> sandbox = PersistentToLocal (env ()->isolate (), sandbox_);
132125
133126 Local<Function> clone_property_method;
134127
135128 Local<Array> names = global->GetOwnPropertyNames ();
136129 int length = names->Length ();
137130 for (int i = 0 ; i < length; i++) {
138131 Local<String> key = names->Get (i)->ToString (env ()->isolate ());
139- bool has = sandbox->HasOwnProperty (context, key).FromJust ();
132+ bool has = sandbox () ->HasOwnProperty (context, key).FromJust ();
140133 if (!has) {
141134 // Could also do this like so:
142135 //
@@ -168,7 +161,7 @@ class ContextifyContext {
168161 clone_property_method = Local<Function>::Cast (script->Run ());
169162 CHECK (clone_property_method->IsFunction ());
170163 }
171- Local<Value> args[] = { global, key, sandbox };
164+ Local<Value> args[] = { global, key, sandbox () };
172165 clone_property_method->Call (global, ARRAY_SIZE (args), args);
173166 }
174167 }
@@ -193,14 +186,13 @@ class ContextifyContext {
193186 }
194187
195188
196- Local<Context> CreateV8Context (Environment* env) {
189+ Local<Context> CreateV8Context (Environment* env, Local<Object> sandbox_obj ) {
197190 EscapableHandleScope scope (env->isolate ());
198191 Local<FunctionTemplate> function_template =
199192 FunctionTemplate::New (env->isolate ());
200193 function_template->SetHiddenPrototype (true );
201194
202- Local<Object> sandbox = PersistentToLocal (env->isolate (), sandbox_);
203- function_template->SetClassName (sandbox->GetConstructorName ());
195+ function_template->SetClassName (sandbox_obj->GetConstructorName ());
204196
205197 Local<ObjectTemplate> object_template =
206198 function_template->InstanceTemplate ();
@@ -217,6 +209,7 @@ class ContextifyContext {
217209
218210 CHECK (!ctx.IsEmpty ());
219211 ctx->SetSecurityToken (env->context ()->GetSecurityToken ());
212+ ctx->SetEmbedderData (kSandboxObjectIndex , sandbox_obj);
220213
221214 env->AssignToContext (ctx);
222215
@@ -312,16 +305,11 @@ class ContextifyContext {
312305 }
313306
314307
315- template <class T , Kind kind >
308+ template <class T >
316309 static void WeakCallback (const WeakCallbackData<T, ContextifyContext>& data) {
317310 ContextifyContext* context = data.GetParameter ();
318- if (kind == kSandbox )
319- context->sandbox_ .ClearWeak ();
320- else
321- context->context_ .ClearWeak ();
322-
323- if (--context->references_ == 0 )
324- delete context;
311+ context->context_ .ClearWeak ();
312+ delete context;
325313 }
326314
327315
@@ -343,26 +331,23 @@ class ContextifyContext {
343331 static void GlobalPropertyGetterCallback (
344332 Local<Name> property,
345333 const PropertyCallbackInfo<Value>& args) {
346- Isolate* isolate = args.GetIsolate ();
347-
348334 ContextifyContext* ctx =
349335 Unwrap<ContextifyContext>(args.Data ().As <Object>());
350336
351337 // Stil initializing
352338 if (ctx->context_ .IsEmpty ())
353339 return ;
354340
355- Local<Object> sandbox = PersistentToLocal (isolate, ctx->sandbox_ );
356341 MaybeLocal<Value> maybe_rv =
357- sandbox->GetRealNamedProperty (ctx->context (), property);
342+ ctx-> sandbox () ->GetRealNamedProperty (ctx->context (), property);
358343 if (maybe_rv.IsEmpty ()) {
359344 maybe_rv =
360345 ctx->global_proxy ()->GetRealNamedProperty (ctx->context (), property);
361346 }
362347
363348 Local<Value> rv;
364349 if (maybe_rv.ToLocal (&rv)) {
365- if (rv == ctx->sandbox_ )
350+ if (rv == ctx->sandbox () )
366351 rv = ctx->global_proxy ();
367352
368353 args.GetReturnValue ().Set (rv);
@@ -374,34 +359,30 @@ class ContextifyContext {
374359 Local<Name> property,
375360 Local<Value> value,
376361 const PropertyCallbackInfo<Value>& args) {
377- Isolate* isolate = args.GetIsolate ();
378-
379362 ContextifyContext* ctx =
380363 Unwrap<ContextifyContext>(args.Data ().As <Object>());
381364
382365 // Stil initializing
383366 if (ctx->context_ .IsEmpty ())
384367 return ;
385368
386- PersistentToLocal (isolate, ctx->sandbox_ )->Set (property, value);
369+ ctx->sandbox ( )->Set (property, value);
387370 }
388371
389372
390373 static void GlobalPropertyQueryCallback (
391374 Local<Name> property,
392375 const PropertyCallbackInfo<Integer>& args) {
393- Isolate* isolate = args.GetIsolate ();
394-
395376 ContextifyContext* ctx =
396377 Unwrap<ContextifyContext>(args.Data ().As <Object>());
397378
398379 // Stil initializing
399380 if (ctx->context_ .IsEmpty ())
400381 return ;
401382
402- Local<Object> sandbox = PersistentToLocal (isolate, ctx->sandbox_ );
403383 Maybe<PropertyAttribute> maybe_prop_attr =
404- sandbox->GetRealNamedPropertyAttributes (ctx->context (), property);
384+ ctx->sandbox ()->GetRealNamedPropertyAttributes (ctx->context (),
385+ property);
405386
406387 if (maybe_prop_attr.IsNothing ()) {
407388 maybe_prop_attr =
@@ -419,18 +400,14 @@ class ContextifyContext {
419400 static void GlobalPropertyDeleterCallback (
420401 Local<Name> property,
421402 const PropertyCallbackInfo<Boolean>& args) {
422- Isolate* isolate = args.GetIsolate ();
423-
424403 ContextifyContext* ctx =
425404 Unwrap<ContextifyContext>(args.Data ().As <Object>());
426405
427406 // Stil initializing
428407 if (ctx->context_ .IsEmpty ())
429408 return ;
430409
431- Local<Object> sandbox = PersistentToLocal (isolate, ctx->sandbox_ );
432-
433- Maybe<bool > success = sandbox->Delete (ctx->context (), property);
410+ Maybe<bool > success = ctx->sandbox ()->Delete (ctx->context (), property);
434411
435412 if (success.IsJust ())
436413 args.GetReturnValue ().Set (success.FromJust ());
@@ -446,8 +423,7 @@ class ContextifyContext {
446423 if (ctx->context_ .IsEmpty ())
447424 return ;
448425
449- Local<Object> sandbox = PersistentToLocal (args.GetIsolate (), ctx->sandbox_ );
450- args.GetReturnValue ().Set (sandbox->GetPropertyNames ());
426+ args.GetReturnValue ().Set (ctx->sandbox ()->GetPropertyNames ());
451427 }
452428};
453429
0 commit comments