• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "config.h"
32 #include "bindings/v8/V8Binding.h"
33 
34 #include "V8Element.h"
35 #include "V8NodeFilter.h"
36 #include "V8Window.h"
37 #include "V8WorkerGlobalScope.h"
38 #include "V8XPathNSResolver.h"
39 #include "bindings/v8/ScriptController.h"
40 #include "bindings/v8/V8NodeFilterCondition.h"
41 #include "bindings/v8/V8ObjectConstructor.h"
42 #include "bindings/v8/V8WindowShell.h"
43 #include "bindings/v8/WorkerScriptController.h"
44 #include "bindings/v8/custom/V8CustomXPathNSResolver.h"
45 #include "core/dom/Element.h"
46 #include "core/dom/NodeFilter.h"
47 #include "core/dom/QualifiedName.h"
48 #include "core/inspector/BindingVisitors.h"
49 #include "core/loader/FrameLoader.h"
50 #include "core/loader/FrameLoaderClient.h"
51 #include "core/frame/Frame.h"
52 #include "core/frame/Settings.h"
53 #include "core/workers/WorkerGlobalScope.h"
54 #include "core/xml/XPathNSResolver.h"
55 #include "gin/public/isolate_holder.h"
56 #include "wtf/ArrayBufferContents.h"
57 #include "wtf/MainThread.h"
58 #include "wtf/MathExtras.h"
59 #include "wtf/StdLibExtras.h"
60 #include "wtf/Threading.h"
61 #include "wtf/text/AtomicString.h"
62 #include "wtf/text/CString.h"
63 #include "wtf/text/StringBuffer.h"
64 #include "wtf/text/StringHash.h"
65 #include "wtf/text/WTFString.h"
66 
67 namespace WebCore {
68 
setDOMException(int exceptionCode,v8::Isolate * isolate)69 v8::Handle<v8::Value> setDOMException(int exceptionCode, v8::Isolate* isolate)
70 {
71     // FIXME: pass in an ExceptionState instead for better creationContext.
72     return V8ThrowException::throwDOMException(exceptionCode, v8::Handle<v8::Object>(), isolate);
73 }
74 
setDOMException(int exceptionCode,const String & message,v8::Isolate * isolate)75 v8::Handle<v8::Value> setDOMException(int exceptionCode, const String& message, v8::Isolate* isolate)
76 {
77     return V8ThrowException::throwDOMException(exceptionCode, message, v8::Handle<v8::Object>(), isolate);
78 }
79 
throwError(V8ErrorType errorType,const String & message,v8::Isolate * isolate)80 v8::Handle<v8::Value> throwError(V8ErrorType errorType, const String& message, v8::Isolate* isolate)
81 {
82     return V8ThrowException::throwError(errorType, message, isolate);
83 }
84 
throwError(v8::Handle<v8::Value> exception,v8::Isolate * isolate)85 v8::Handle<v8::Value> throwError(v8::Handle<v8::Value> exception, v8::Isolate* isolate)
86 {
87     return V8ThrowException::throwError(exception, isolate);
88 }
89 
throwUninformativeAndGenericTypeError(v8::Isolate * isolate)90 v8::Handle<v8::Value> throwUninformativeAndGenericTypeError(v8::Isolate* isolate)
91 {
92     return V8ThrowException::throwTypeError(String(), isolate);
93 }
94 
throwTypeError(const String & message,v8::Isolate * isolate)95 v8::Handle<v8::Value> throwTypeError(const String& message, v8::Isolate* isolate)
96 {
97     return V8ThrowException::throwTypeError(message, isolate);
98 }
99 
100 class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
Allocate(size_t size)101     virtual void* Allocate(size_t size) OVERRIDE
102     {
103         void* data;
104         WTF::ArrayBufferContents::allocateMemory(size, WTF::ArrayBufferContents::ZeroInitialize, data);
105         return data;
106     }
107 
AllocateUninitialized(size_t size)108     virtual void* AllocateUninitialized(size_t size) OVERRIDE
109     {
110         void* data;
111         WTF::ArrayBufferContents::allocateMemory(size, WTF::ArrayBufferContents::DontInitialize, data);
112         return data;
113     }
114 
Free(void * data,size_t size)115     virtual void Free(void* data, size_t size) OVERRIDE
116     {
117         WTF::ArrayBufferContents::freeMemory(data, size);
118     }
119 };
120 
v8ArrayBufferAllocator()121 v8::ArrayBuffer::Allocator* v8ArrayBufferAllocator()
122 {
123     DEFINE_STATIC_LOCAL(ArrayBufferAllocator, arrayBufferAllocator, ());
124     return &arrayBufferAllocator;
125 }
126 
toNodeFilter(v8::Handle<v8::Value> callback,v8::Isolate * isolate)127 PassRefPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value> callback, v8::Isolate* isolate)
128 {
129     RefPtr<NodeFilter> filter = NodeFilter::create();
130 
131     // FIXME: Should pass in appropriate creationContext
132     v8::Handle<v8::Object> filterWrapper = toV8(filter, v8::Handle<v8::Object>(), isolate).As<v8::Object>();
133 
134     RefPtr<NodeFilterCondition> condition = V8NodeFilterCondition::create(callback, filterWrapper, isolate);
135     filter->setCondition(condition.release());
136 
137     return filter.release();
138 }
139 
140 const int32_t kMaxInt32 = 0x7fffffff;
141 const int32_t kMinInt32 = -kMaxInt32 - 1;
142 const uint32_t kMaxUInt32 = 0xffffffff;
143 const int64_t kJSMaxInteger = 0x20000000000000LL - 1; // 2^53 - 1, maximum integer exactly representable in ECMAScript.
144 
enforceRange(double x,double minimum,double maximum,bool & ok)145 static double enforceRange(double x, double minimum, double maximum, bool& ok)
146 {
147     if (std::isnan(x) || std::isinf(x)) {
148         ok = false;
149         return 0;
150     }
151     x = trunc(x);
152     if (x < minimum || x > maximum) {
153         ok = false;
154         return 0;
155     }
156     return x;
157 }
158 
159 template <typename T>
160 struct IntTypeLimits {
161 };
162 
163 template <>
164 struct IntTypeLimits<int8_t> {
165     static const int8_t minValue = -128;
166     static const int8_t maxValue = 127;
167     static const unsigned numberOfValues = 256; // 2^8
168 };
169 
170 template <>
171 struct IntTypeLimits<uint8_t> {
172     static const uint8_t maxValue = 255;
173     static const unsigned numberOfValues = 256; // 2^8
174 };
175 
176 template <>
177 struct IntTypeLimits<int16_t> {
178     static const short minValue = -32768;
179     static const short maxValue = 32767;
180     static const unsigned numberOfValues = 65536; // 2^16
181 };
182 
183 template <>
184 struct IntTypeLimits<uint16_t> {
185     static const unsigned short maxValue = 65535;
186     static const unsigned numberOfValues = 65536; // 2^16
187 };
188 
189 template <typename T>
toSmallerInt(v8::Handle<v8::Value> value,IntegerConversionConfiguration configuration,bool & ok)190 static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
191 {
192     typedef IntTypeLimits<T> LimitsTrait;
193     ok = true;
194 
195     // Fast case. The value is already a 32-bit integer in the right range.
196     if (value->IsInt32()) {
197         int32_t result = value->Int32Value();
198         if (result >= LimitsTrait::minValue && result <= LimitsTrait::maxValue)
199             return static_cast<T>(result);
200         if (configuration == EnforceRange) {
201             ok = false;
202             return 0;
203         }
204         result %= LimitsTrait::numberOfValues;
205         return static_cast<T>(result > LimitsTrait::maxValue ? result - LimitsTrait::numberOfValues : result);
206     }
207 
208     // Can the value be converted to a number?
209     v8::Local<v8::Number> numberObject = value->ToNumber();
210     if (numberObject.IsEmpty()) {
211         ok = false;
212         return 0;
213     }
214 
215     if (configuration == EnforceRange)
216         return enforceRange(numberObject->Value(), LimitsTrait::minValue, LimitsTrait::maxValue, ok);
217 
218     double numberValue = numberObject->Value();
219     if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue)
220         return 0;
221 
222     numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numberValue));
223     numberValue = fmod(numberValue, LimitsTrait::numberOfValues);
224 
225     return static_cast<T>(numberValue > LimitsTrait::maxValue ? numberValue - LimitsTrait::numberOfValues : numberValue);
226 }
227 
228 template <typename T>
toSmallerUInt(v8::Handle<v8::Value> value,IntegerConversionConfiguration configuration,bool & ok)229 static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
230 {
231     typedef IntTypeLimits<T> LimitsTrait;
232     ok = true;
233 
234     // Fast case. The value is a 32-bit signed integer - possibly positive?
235     if (value->IsInt32()) {
236         int32_t result = value->Int32Value();
237         if (result >= 0 && result <= LimitsTrait::maxValue)
238             return static_cast<T>(result);
239         if (configuration == EnforceRange) {
240             ok = false;
241             return 0;
242         }
243         return static_cast<T>(result);
244     }
245 
246     // Can the value be converted to a number?
247     v8::Local<v8::Number> numberObject = value->ToNumber();
248     if (numberObject.IsEmpty()) {
249         ok = false;
250         return 0;
251     }
252 
253     if (configuration == EnforceRange)
254         return enforceRange(numberObject->Value(), 0, LimitsTrait::maxValue, ok);
255 
256     // Does the value convert to nan or to an infinity?
257     double numberValue = numberObject->Value();
258     if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue)
259         return 0;
260 
261     if (configuration == Clamp)
262         return clampTo<T>(numberObject->Value());
263 
264     numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numberValue));
265     return static_cast<T>(fmod(numberValue, LimitsTrait::numberOfValues));
266 }
267 
toInt8(v8::Handle<v8::Value> value,IntegerConversionConfiguration configuration,bool & ok)268 int8_t toInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
269 {
270     return toSmallerInt<int8_t>(value, configuration, ok);
271 }
272 
toUInt8(v8::Handle<v8::Value> value,IntegerConversionConfiguration configuration,bool & ok)273 uint8_t toUInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
274 {
275     return toSmallerUInt<uint8_t>(value, configuration, ok);
276 }
277 
toInt16(v8::Handle<v8::Value> value,IntegerConversionConfiguration configuration,bool & ok)278 int16_t toInt16(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
279 {
280     return toSmallerInt<int16_t>(value, configuration, ok);
281 }
282 
toUInt16(v8::Handle<v8::Value> value,IntegerConversionConfiguration configuration,bool & ok)283 uint16_t toUInt16(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
284 {
285     return toSmallerUInt<uint16_t>(value, configuration, ok);
286 }
287 
toInt32(v8::Handle<v8::Value> value,IntegerConversionConfiguration configuration,bool & ok)288 int32_t toInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
289 {
290     ok = true;
291 
292     // Fast case. The value is already a 32-bit integer.
293     if (value->IsInt32())
294         return value->Int32Value();
295 
296     // Can the value be converted to a number?
297     ok = false;
298     V8TRYCATCH_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), 0);
299     if (numberObject.IsEmpty()) {
300         return 0;
301     }
302     ok = true;
303 
304     if (configuration == EnforceRange)
305         return enforceRange(numberObject->Value(), kMinInt32, kMaxInt32, ok);
306 
307     // Does the value convert to nan or to an infinity?
308     double numberValue = numberObject->Value();
309     if (std::isnan(numberValue) || std::isinf(numberValue))
310         return 0;
311 
312     if (configuration == Clamp)
313         return clampTo<int32_t>(numberObject->Value());
314 
315     V8TRYCATCH_RETURN(int32_t, result, numberObject->Int32Value(), 0);
316     return result;
317 }
318 
toUInt32(v8::Handle<v8::Value> value,IntegerConversionConfiguration configuration,bool & ok)319 uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
320 {
321     ok = true;
322 
323     // Fast case. The value is already a 32-bit unsigned integer.
324     if (value->IsUint32())
325         return value->Uint32Value();
326 
327     // Fast case. The value is a 32-bit signed integer - possibly positive?
328     if (value->IsInt32()) {
329         int32_t result = value->Int32Value();
330         if (result >= 0)
331             return result;
332         if (configuration == EnforceRange) {
333             ok = false;
334             return 0;
335         }
336         return result;
337     }
338 
339     // Can the value be converted to a number?
340     ok = false;
341     V8TRYCATCH_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), 0);
342     if (numberObject.IsEmpty()) {
343         return 0;
344     }
345     ok = true;
346 
347     if (configuration == EnforceRange)
348         return enforceRange(numberObject->Value(), 0, kMaxUInt32, ok);
349 
350     // Does the value convert to nan or to an infinity?
351     double numberValue = numberObject->Value();
352     if (std::isnan(numberValue) || std::isinf(numberValue))
353         return 0;
354 
355     if (configuration == Clamp)
356         return clampTo<uint32_t>(numberObject->Value());
357 
358     V8TRYCATCH_RETURN(uint32_t, result, numberObject->Uint32Value(), 0);
359     return result;
360 }
361 
toInt64(v8::Handle<v8::Value> value,IntegerConversionConfiguration configuration,bool & ok)362 int64_t toInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
363 {
364     ok = true;
365 
366     // Fast case. The value is a 32-bit integer.
367     if (value->IsInt32())
368         return value->Int32Value();
369 
370     // Can the value be converted to a number?
371     v8::Local<v8::Number> numberObject = value->ToNumber();
372     if (numberObject.IsEmpty()) {
373         ok = false;
374         return 0;
375     }
376 
377     double x = numberObject->Value();
378 
379     if (configuration == EnforceRange)
380         return enforceRange(x, -kJSMaxInteger, kJSMaxInteger, ok);
381 
382     // Does the value convert to nan or to an infinity?
383     if (std::isnan(x) || std::isinf(x))
384         return 0;
385 
386     // NaNs and +/-Infinity should be 0, otherwise modulo 2^64.
387     unsigned long long integer;
388     doubleToInteger(x, integer);
389     return integer;
390 }
391 
toUInt64(v8::Handle<v8::Value> value,IntegerConversionConfiguration configuration,bool & ok)392 uint64_t toUInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
393 {
394     ok = true;
395 
396     // Fast case. The value is a 32-bit unsigned integer.
397     if (value->IsUint32())
398         return value->Uint32Value();
399 
400     // Fast case. The value is a 32-bit integer.
401     if (value->IsInt32()) {
402         int32_t result = value->Int32Value();
403         if (result >= 0)
404             return result;
405         if (configuration == EnforceRange) {
406             ok = false;
407             return 0;
408         }
409         return result;
410     }
411 
412     // Can the value be converted to a number?
413     v8::Local<v8::Number> numberObject = value->ToNumber();
414     if (numberObject.IsEmpty()) {
415         ok = false;
416         return 0;
417     }
418 
419     double x = numberObject->Value();
420 
421     if (configuration == EnforceRange)
422         return enforceRange(x, 0, kJSMaxInteger, ok);
423 
424     // Does the value convert to nan or to an infinity?
425     if (std::isnan(x) || std::isinf(x))
426         return 0;
427 
428     // NaNs and +/-Infinity should be 0, otherwise modulo 2^64.
429     unsigned long long integer;
430     doubleToInteger(x, integer);
431     return integer;
432 }
433 
createRawTemplate(v8::Isolate * isolate)434 v8::Handle<v8::FunctionTemplate> createRawTemplate(v8::Isolate* isolate)
435 {
436     v8::EscapableHandleScope scope(isolate);
437     v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(isolate, V8ObjectConstructor::isValidConstructorMode);
438     return scope.Escape(result);
439 }
440 
toXPathNSResolver(v8::Handle<v8::Value> value,v8::Isolate * isolate)441 PassRefPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value> value, v8::Isolate* isolate)
442 {
443     RefPtr<XPathNSResolver> resolver;
444     if (V8XPathNSResolver::hasInstance(value, isolate, worldType(isolate)))
445         resolver = V8XPathNSResolver::toNative(v8::Handle<v8::Object>::Cast(value));
446     else if (value->IsObject())
447         resolver = V8CustomXPathNSResolver::create(value->ToObject(), isolate);
448     return resolver;
449 }
450 
toInnerGlobalObject(v8::Handle<v8::Context> context)451 v8::Handle<v8::Object> toInnerGlobalObject(v8::Handle<v8::Context> context)
452 {
453     return v8::Handle<v8::Object>::Cast(context->Global()->GetPrototype());
454 }
455 
toDOMWindow(v8::Handle<v8::Context> context)456 DOMWindow* toDOMWindow(v8::Handle<v8::Context> context)
457 {
458     v8::Handle<v8::Object> global = context->Global();
459     ASSERT(!global.IsEmpty());
460     v8::Handle<v8::Object> window = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), MainWorld));
461     if (!window.IsEmpty())
462         return V8Window::toNative(window);
463     window = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), IsolatedWorld));
464     ASSERT(!window.IsEmpty());
465     return V8Window::toNative(window);
466 }
467 
toExecutionContext(v8::Handle<v8::Context> context)468 ExecutionContext* toExecutionContext(v8::Handle<v8::Context> context)
469 {
470     v8::Handle<v8::Object> global = context->Global();
471     v8::Handle<v8::Object> windowWrapper = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), MainWorld));
472     if (!windowWrapper.IsEmpty())
473         return V8Window::toNative(windowWrapper)->executionContext();
474     windowWrapper = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), IsolatedWorld));
475     if (!windowWrapper.IsEmpty())
476         return V8Window::toNative(windowWrapper)->executionContext();
477     v8::Handle<v8::Object> workerWrapper = global->FindInstanceInPrototypeChain(V8WorkerGlobalScope::domTemplate(context->GetIsolate(), WorkerWorld));
478     if (!workerWrapper.IsEmpty())
479         return V8WorkerGlobalScope::toNative(workerWrapper)->executionContext();
480     // FIXME: Is this line of code reachable?
481     return 0;
482 }
483 
activeDOMWindow()484 DOMWindow* activeDOMWindow()
485 {
486     v8::Handle<v8::Context> context = v8::Isolate::GetCurrent()->GetCallingContext();
487     if (context.IsEmpty()) {
488         // Unfortunately, when processing script from a plug-in, we might not
489         // have a calling context. In those cases, we fall back to the
490         // entered context.
491         context = v8::Isolate::GetCurrent()->GetEnteredContext();
492     }
493     return toDOMWindow(context);
494 }
495 
activeExecutionContext()496 ExecutionContext* activeExecutionContext()
497 {
498     v8::Handle<v8::Context> context = v8::Isolate::GetCurrent()->GetCallingContext();
499     if (context.IsEmpty()) {
500         // Unfortunately, when processing script from a plug-in, we might not
501         // have a calling context. In those cases, we fall back to the
502         // entered context.
503         context = v8::Isolate::GetCurrent()->GetEnteredContext();
504     }
505     return toExecutionContext(context);
506 }
507 
firstDOMWindow()508 DOMWindow* firstDOMWindow()
509 {
510     return toDOMWindow(v8::Isolate::GetCurrent()->GetEnteredContext());
511 }
512 
currentDocument()513 Document* currentDocument()
514 {
515     return toDOMWindow(v8::Isolate::GetCurrent()->GetCurrentContext())->document();
516 }
517 
toFrameIfNotDetached(v8::Handle<v8::Context> context)518 Frame* toFrameIfNotDetached(v8::Handle<v8::Context> context)
519 {
520     DOMWindow* window = toDOMWindow(context);
521     if (window->isCurrentlyDisplayedInFrame())
522         return window->frame();
523     // We return 0 here because |context| is detached from the Frame. If we
524     // did return |frame| we could get in trouble because the frame could be
525     // navigated to another security origin.
526     return 0;
527 }
528 
toV8Context(ExecutionContext * context,DOMWrapperWorld * world)529 v8::Local<v8::Context> toV8Context(ExecutionContext* context, DOMWrapperWorld* world)
530 {
531     if (context->isDocument()) {
532         ASSERT(world);
533         if (Frame* frame = toDocument(context)->frame())
534             return frame->script().windowShell(world)->context();
535     } else if (context->isWorkerGlobalScope()) {
536         ASSERT(!world);
537         if (WorkerScriptController* script = toWorkerGlobalScope(context)->script())
538             return script->context();
539     }
540     return v8::Local<v8::Context>();
541 }
542 
handleOutOfMemory()543 bool handleOutOfMemory()
544 {
545     v8::Local<v8::Context> context = v8::Isolate::GetCurrent()->GetCurrentContext();
546 
547     if (!context->HasOutOfMemoryException())
548         return false;
549 
550     // Warning, error, disable JS for this frame?
551     Frame* frame = toFrameIfNotDetached(context);
552     if (!frame)
553         return true;
554 
555     frame->script().clearForOutOfMemory();
556     frame->loader().client()->didExhaustMemoryAvailableForScript();
557 
558     if (Settings* settings = frame->settings())
559         settings->setScriptEnabled(false);
560 
561     return true;
562 }
563 
handleMaxRecursionDepthExceeded(v8::Isolate * isolate)564 v8::Local<v8::Value> handleMaxRecursionDepthExceeded(v8::Isolate* isolate)
565 {
566     throwError(v8RangeError, "Maximum call stack size exceeded.", isolate);
567     return v8::Local<v8::Value>();
568 }
569 
crashIfV8IsDead()570 void crashIfV8IsDead()
571 {
572     if (v8::V8::IsDead()) {
573         // FIXME: We temporarily deal with V8 internal error situations
574         // such as out-of-memory by crashing the renderer.
575         CRASH();
576     }
577 }
578 
worldType(v8::Isolate * isolate)579 WrapperWorldType worldType(v8::Isolate* isolate)
580 {
581     V8PerIsolateData* data = V8PerIsolateData::from(isolate);
582     if (!data->workerDOMDataStore())
583         return worldTypeInMainThread(isolate);
584     return WorkerWorld;
585 }
586 
worldTypeInMainThread(v8::Isolate * isolate)587 WrapperWorldType worldTypeInMainThread(v8::Isolate* isolate)
588 {
589     if (!DOMWrapperWorld::isolatedWorldsExist())
590         return MainWorld;
591     ASSERT(!isolate->GetEnteredContext().IsEmpty());
592     DOMWrapperWorld* isolatedWorld = DOMWrapperWorld::isolatedWorld(isolate->GetEnteredContext());
593     if (isolatedWorld)
594         return IsolatedWorld;
595     return MainWorld;
596 }
597 
isolatedWorldForIsolate(v8::Isolate * isolate)598 DOMWrapperWorld* isolatedWorldForIsolate(v8::Isolate* isolate)
599 {
600     V8PerIsolateData* data = V8PerIsolateData::from(isolate);
601     if (data->workerDOMDataStore())
602         return 0;
603     if (!DOMWrapperWorld::isolatedWorldsExist())
604         return 0;
605     ASSERT(isolate->InContext());
606     return DOMWrapperWorld::isolatedWorld(isolate->GetCurrentContext());
607 }
608 
getHiddenValueFromMainWorldWrapper(v8::Isolate * isolate,ScriptWrappable * wrappable,v8::Handle<v8::String> key)609 v8::Local<v8::Value> getHiddenValueFromMainWorldWrapper(v8::Isolate* isolate, ScriptWrappable* wrappable, v8::Handle<v8::String> key)
610 {
611     v8::Local<v8::Object> wrapper = wrappable->newLocalWrapper(isolate);
612     return wrapper.IsEmpty() ? v8::Local<v8::Value>() : wrapper->GetHiddenValue(key);
613 }
614 
615 static gin::IsolateHolder* mainIsolateHolder = 0;
616 
mainThreadIsolate()617 v8::Isolate* mainThreadIsolate()
618 {
619     ASSERT(mainIsolateHolder);
620     ASSERT(isMainThread());
621     return mainIsolateHolder->isolate();
622 }
623 
setMainThreadIsolate(v8::Isolate * isolate)624 void setMainThreadIsolate(v8::Isolate* isolate)
625 {
626     ASSERT(!mainIsolateHolder || !isolate);
627     ASSERT(isMainThread());
628     if (isolate) {
629         mainIsolateHolder = new gin::IsolateHolder(isolate);
630     } else {
631         delete mainIsolateHolder;
632         mainIsolateHolder = 0;
633     }
634 }
635 
toIsolate(ExecutionContext * context)636 v8::Isolate* toIsolate(ExecutionContext* context)
637 {
638     if (context && context->isDocument())
639         return mainThreadIsolate();
640     return v8::Isolate::GetCurrent();
641 }
642 
toIsolate(Frame * frame)643 v8::Isolate* toIsolate(Frame* frame)
644 {
645     return frame->script().isolate();
646 }
647 
648 } // namespace WebCore
649