@@ -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(key);
132+ bool has = sandbox() ->HasOwnProperty(context, key).FromJust( );
140133 if (!has) {
141134 // Could also do this like so:
142135 //
@@ -169,7 +162,7 @@ class ContextifyContext {
169162 clone_property_method = Local<Function>::Cast(script->Run());
170163 CHECK(clone_property_method->IsFunction());
171164 }
172- Local<Value> args[] = { global, key, sandbox };
165+ Local<Value> args[] = { global, key, sandbox() };
173166 clone_property_method->Call(global, ARRAY_SIZE(args), args);
174167 }
175168 }
@@ -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
@@ -311,16 +304,11 @@ class ContextifyContext {
311304 }
312305
313306
314- template <class T, Kind kind >
307+ template <class T>
315308 static void WeakCallback(const WeakCallbackData<T, ContextifyContext>& data) {
316309 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;
324312 }
325313
326314
@@ -342,26 +330,23 @@ class ContextifyContext {
342330 static void GlobalPropertyGetterCallback(
343331 Local<Name> property,
344332 const PropertyCallbackInfo<Value>& args) {
345- Isolate* isolate = args.GetIsolate();
346-
347333 ContextifyContext* ctx =
348334 Unwrap<ContextifyContext>(args.Data().As<Object>());
349335
350336 // Stil initializing
351337 if (ctx->context_.IsEmpty())
352338 return;
353339
354- Local<Object> sandbox = PersistentToLocal(isolate, ctx->sandbox_);
355340 MaybeLocal<Value> maybe_rv =
356- sandbox->GetRealNamedProperty(ctx->context(), property);
341+ ctx-> sandbox() ->GetRealNamedProperty(ctx->context(), property);
357342 if (maybe_rv.IsEmpty()) {
358343 maybe_rv =
359344 ctx->global_proxy()->GetRealNamedProperty(ctx->context(), property);
360345 }
361346
362347 Local<Value> rv;
363348 if (maybe_rv.ToLocal(&rv)) {
364- if (rv == ctx->sandbox_ )
349+ if (rv == ctx->sandbox() )
365350 rv = ctx->global_proxy();
366351
367352 args.GetReturnValue().Set(rv);
@@ -373,34 +358,30 @@ class ContextifyContext {
373358 Local<Name> property,
374359 Local<Value> value,
375360 const PropertyCallbackInfo<Value>& args) {
376- Isolate* isolate = args.GetIsolate();
377-
378361 ContextifyContext* ctx =
379362 Unwrap<ContextifyContext>(args.Data().As<Object>());
380363
381364 // Stil initializing
382365 if (ctx->context_.IsEmpty())
383366 return;
384367
385- PersistentToLocal(isolate, ctx->sandbox_ )->Set(property, value);
368+ ctx->sandbox( )->Set(property, value);
386369 }
387370
388371
389372 static void GlobalPropertyQueryCallback(
390373 Local<Name> property,
391374 const PropertyCallbackInfo<Integer>& args) {
392- Isolate* isolate = args.GetIsolate();
393-
394375 ContextifyContext* ctx =
395376 Unwrap<ContextifyContext>(args.Data().As<Object>());
396377
397378 // Stil initializing
398379 if (ctx->context_.IsEmpty())
399380 return;
400381
401- Local<Object> sandbox = PersistentToLocal(isolate, ctx->sandbox_);
402382 Maybe<PropertyAttribute> maybe_prop_attr =
403- sandbox->GetRealNamedPropertyAttributes(ctx->context(), property);
383+ ctx->sandbox()->GetRealNamedPropertyAttributes(ctx->context(),
384+ property);
404385
405386 if (maybe_prop_attr.IsNothing()) {
406387 maybe_prop_attr =
@@ -418,18 +399,14 @@ class ContextifyContext {
418399 static void GlobalPropertyDeleterCallback(
419400 Local<Name> property,
420401 const PropertyCallbackInfo<Boolean>& args) {
421- Isolate* isolate = args.GetIsolate();
422-
423402 ContextifyContext* ctx =
424403 Unwrap<ContextifyContext>(args.Data().As<Object>());
425404
426405 // Stil initializing
427406 if (ctx->context_.IsEmpty())
428407 return;
429408
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);
433410
434411 if (success.IsJust())
435412 args.GetReturnValue().Set(success.FromJust());
@@ -445,8 +422,7 @@ class ContextifyContext {
445422 if (ctx->context_.IsEmpty())
446423 return;
447424
448- Local<Object> sandbox = PersistentToLocal(args.GetIsolate(), ctx->sandbox_);
449- args.GetReturnValue().Set(sandbox->GetPropertyNames());
425+ args.GetReturnValue().Set(ctx->sandbox()->GetPropertyNames());
450426 }
451427};
452428
0 commit comments