2 * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
32 #include "bindings/v8/V8Binding.h"
34 #include "V8Element.h"
35 #include "V8NodeFilter.h"
37 #include "V8WorkerGlobalScope.h"
38 #include "V8XPathNSResolver.h"
39 #include "bindings/v8/ScriptController.h"
40 #include "bindings/v8/V8BindingMacros.h"
41 #include "bindings/v8/V8NodeFilterCondition.h"
42 #include "bindings/v8/V8ObjectConstructor.h"
43 #include "bindings/v8/V8WindowShell.h"
44 #include "bindings/v8/WorkerScriptController.h"
45 #include "bindings/v8/custom/V8CustomXPathNSResolver.h"
46 #include "core/dom/Element.h"
47 #include "core/dom/NodeFilter.h"
48 #include "core/dom/QualifiedName.h"
49 #include "core/inspector/BindingVisitors.h"
50 #include "core/loader/FrameLoader.h"
51 #include "core/loader/FrameLoaderClient.h"
52 #include "core/frame/Frame.h"
53 #include "core/frame/Settings.h"
54 #include "core/workers/WorkerGlobalScope.h"
55 #include "core/xml/XPathNSResolver.h"
56 #include "gin/public/isolate_holder.h"
57 #include "wtf/ArrayBufferContents.h"
58 #include "wtf/MainThread.h"
59 #include "wtf/MathExtras.h"
60 #include "wtf/StdLibExtras.h"
61 #include "wtf/Threading.h"
62 #include "wtf/text/AtomicString.h"
63 #include "wtf/text/CString.h"
64 #include "wtf/text/StringBuffer.h"
65 #include "wtf/text/StringHash.h"
66 #include "wtf/text/WTFString.h"
70 v8::Handle<v8::Value> setDOMException(int exceptionCode, v8::Isolate* isolate)
72 // FIXME: pass in an ExceptionState instead for better creationContext.
73 return V8ThrowException::throwDOMException(exceptionCode, v8::Handle<v8::Object>(), isolate);
76 v8::Handle<v8::Value> setDOMException(int exceptionCode, const String& message, v8::Isolate* isolate)
78 return V8ThrowException::throwDOMException(exceptionCode, message, v8::Handle<v8::Object>(), isolate);
81 v8::Handle<v8::Value> throwError(V8ErrorType errorType, const String& message, v8::Isolate* isolate)
83 return V8ThrowException::throwError(errorType, message, isolate);
86 v8::Handle<v8::Value> throwError(v8::Handle<v8::Value> exception, v8::Isolate* isolate)
88 return V8ThrowException::throwError(exception, isolate);
91 v8::Handle<v8::Value> throwTypeError(const String& message, v8::Isolate* isolate)
93 return V8ThrowException::throwTypeError(message, isolate);
96 class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
97 virtual void* Allocate(size_t size) OVERRIDE
100 WTF::ArrayBufferContents::allocateMemory(size, WTF::ArrayBufferContents::ZeroInitialize, data);
104 virtual void* AllocateUninitialized(size_t size) OVERRIDE
107 WTF::ArrayBufferContents::allocateMemory(size, WTF::ArrayBufferContents::DontInitialize, data);
111 virtual void Free(void* data, size_t size) OVERRIDE
113 WTF::ArrayBufferContents::freeMemory(data, size);
117 v8::ArrayBuffer::Allocator* v8ArrayBufferAllocator()
119 DEFINE_STATIC_LOCAL(ArrayBufferAllocator, arrayBufferAllocator, ());
120 return &arrayBufferAllocator;
123 PassRefPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value> callback, v8::Isolate* isolate)
125 RefPtr<NodeFilter> filter = NodeFilter::create();
127 // FIXME: Should pass in appropriate creationContext
128 v8::Handle<v8::Object> filterWrapper = toV8(filter, v8::Handle<v8::Object>(), isolate).As<v8::Object>();
130 RefPtr<NodeFilterCondition> condition = V8NodeFilterCondition::create(callback, filterWrapper, isolate);
131 filter->setCondition(condition.release());
133 return filter.release();
136 DOMWindow* toNativeDOMWindow(v8::Handle<v8::Value> value, v8::Isolate* isolate)
138 if (value.IsEmpty() || !value->IsObject())
141 v8::Handle<v8::Object> global = v8::Handle<v8::Object>::Cast(value);
142 v8::Handle<v8::Object> windowWrapper = global->FindInstanceInPrototypeChain(V8Window::domTemplate(isolate, worldType(isolate)));
143 if (windowWrapper.IsEmpty())
145 return V8Window::toNative(windowWrapper);
148 const int32_t kMaxInt32 = 0x7fffffff;
149 const int32_t kMinInt32 = -kMaxInt32 - 1;
150 const uint32_t kMaxUInt32 = 0xffffffff;
151 const int64_t kJSMaxInteger = 0x20000000000000LL - 1; // 2^53 - 1, maximum uniquely representable integer in ECMAScript.
153 static double enforceRange(double x, double minimum, double maximum, const char* typeName, ExceptionState& exceptionState)
155 if (std::isnan(x) || std::isinf(x)) {
156 exceptionState.throwTypeError("Value is" + String(std::isinf(x) ? " infinite and" : "") + " not of type '" + String(typeName) + "'.");
160 if (x < minimum || x > maximum) {
161 exceptionState.throwTypeError("Value is outside the '" + String(typeName) + "' value range.");
167 template <typename T>
168 struct IntTypeLimits {
172 struct IntTypeLimits<int8_t> {
173 static const int8_t minValue = -128;
174 static const int8_t maxValue = 127;
175 static const unsigned numberOfValues = 256; // 2^8
179 struct IntTypeLimits<uint8_t> {
180 static const uint8_t maxValue = 255;
181 static const unsigned numberOfValues = 256; // 2^8
185 struct IntTypeLimits<int16_t> {
186 static const short minValue = -32768;
187 static const short maxValue = 32767;
188 static const unsigned numberOfValues = 65536; // 2^16
192 struct IntTypeLimits<uint16_t> {
193 static const unsigned short maxValue = 65535;
194 static const unsigned numberOfValues = 65536; // 2^16
197 template <typename T>
198 static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, const char* typeName, ExceptionState& exceptionState)
200 typedef IntTypeLimits<T> LimitsTrait;
202 // Fast case. The value is already a 32-bit integer in the right range.
203 if (value->IsInt32()) {
204 int32_t result = value->Int32Value();
205 if (result >= LimitsTrait::minValue && result <= LimitsTrait::maxValue)
206 return static_cast<T>(result);
207 if (configuration == EnforceRange) {
208 exceptionState.throwTypeError("Value is outside the '" + String(typeName) + "' value range.");
211 result %= LimitsTrait::numberOfValues;
212 return static_cast<T>(result > LimitsTrait::maxValue ? result - LimitsTrait::numberOfValues : result);
215 // Can the value be converted to a number?
216 V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
217 if (numberObject.IsEmpty()) {
218 exceptionState.throwTypeError("Not convertible to a number value (of type '" + String(typeName) + "'.");
222 if (configuration == EnforceRange)
223 return enforceRange(numberObject->Value(), LimitsTrait::minValue, LimitsTrait::maxValue, typeName, exceptionState);
225 double numberValue = numberObject->Value();
226 if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue)
229 numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numberValue));
230 numberValue = fmod(numberValue, LimitsTrait::numberOfValues);
232 return static_cast<T>(numberValue > LimitsTrait::maxValue ? numberValue - LimitsTrait::numberOfValues : numberValue);
235 template <typename T>
236 static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, const char* typeName, ExceptionState& exceptionState)
238 typedef IntTypeLimits<T> LimitsTrait;
240 // Fast case. The value is a 32-bit signed integer - possibly positive?
241 if (value->IsInt32()) {
242 int32_t result = value->Int32Value();
243 if (result >= 0 && result <= LimitsTrait::maxValue)
244 return static_cast<T>(result);
245 if (configuration == EnforceRange) {
246 exceptionState.throwTypeError("Value is outside the '" + String(typeName) + "' value range.");
249 return static_cast<T>(result);
252 // Can the value be converted to a number?
253 V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
254 if (numberObject.IsEmpty()) {
255 exceptionState.throwTypeError("Not convertible to a number value (of type '" + String(typeName) + "'.");
259 if (configuration == EnforceRange)
260 return enforceRange(numberObject->Value(), 0, LimitsTrait::maxValue, typeName, exceptionState);
262 // Does the value convert to nan or to an infinity?
263 double numberValue = numberObject->Value();
264 if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue)
267 if (configuration == Clamp)
268 return clampTo<T>(numberObject->Value());
270 numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numberValue));
271 return static_cast<T>(fmod(numberValue, LimitsTrait::numberOfValues));
274 int8_t toInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
276 return toSmallerInt<int8_t>(value, configuration, "byte", exceptionState);
279 int8_t toInt8(v8::Handle<v8::Value> value)
281 NonThrowableExceptionState exceptionState;
282 return toInt8(value, NormalConversion, exceptionState);
285 uint8_t toUInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
287 return toSmallerUInt<uint8_t>(value, configuration, "octet", exceptionState);
290 uint8_t toUInt8(v8::Handle<v8::Value> value)
292 NonThrowableExceptionState exceptionState;
293 return toUInt8(value, NormalConversion, exceptionState);
296 int16_t toInt16(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
298 return toSmallerInt<int16_t>(value, configuration, "short", exceptionState);
301 int16_t toInt16(v8::Handle<v8::Value> value)
303 NonThrowableExceptionState exceptionState;
304 return toInt16(value, NormalConversion, exceptionState);
307 uint16_t toUInt16(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
309 return toSmallerUInt<uint16_t>(value, configuration, "unsigned short", exceptionState);
312 uint16_t toUInt16(v8::Handle<v8::Value> value)
314 NonThrowableExceptionState exceptionState;
315 return toUInt16(value, NormalConversion, exceptionState);
318 int32_t toInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
320 // Fast case. The value is already a 32-bit integer.
321 if (value->IsInt32())
322 return value->Int32Value();
324 // Can the value be converted to a number?
325 V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
326 if (numberObject.IsEmpty()) {
327 exceptionState.throwTypeError("Not convertible to a number value (of type 'long'.)");
331 if (configuration == EnforceRange)
332 return enforceRange(numberObject->Value(), kMinInt32, kMaxInt32, "long", exceptionState);
334 // Does the value convert to nan or to an infinity?
335 double numberValue = numberObject->Value();
336 if (std::isnan(numberValue) || std::isinf(numberValue))
339 if (configuration == Clamp)
340 return clampTo<int32_t>(numberObject->Value());
342 V8TRYCATCH_EXCEPTION_RETURN(int32_t, result, numberObject->Int32Value(), exceptionState, 0);
346 int32_t toInt32(v8::Handle<v8::Value> value)
348 NonThrowableExceptionState exceptionState;
349 return toInt32(value, NormalConversion, exceptionState);
352 uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
354 // Fast case. The value is already a 32-bit unsigned integer.
355 if (value->IsUint32())
356 return value->Uint32Value();
358 // Fast case. The value is a 32-bit signed integer - possibly positive?
359 if (value->IsInt32()) {
360 int32_t result = value->Int32Value();
363 if (configuration == EnforceRange) {
364 exceptionState.throwTypeError("Value is outside the 'unsigned long' value range.");
370 // Can the value be converted to a number?
371 V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
372 if (numberObject.IsEmpty()) {
373 exceptionState.throwTypeError("Not convertible to a number value (of type 'unsigned long'.)");
377 if (configuration == EnforceRange)
378 return enforceRange(numberObject->Value(), 0, kMaxUInt32, "unsigned long", exceptionState);
380 // Does the value convert to nan or to an infinity?
381 double numberValue = numberObject->Value();
382 if (std::isnan(numberValue) || std::isinf(numberValue))
385 if (configuration == Clamp)
386 return clampTo<uint32_t>(numberObject->Value());
388 V8TRYCATCH_RETURN(uint32_t, result, numberObject->Uint32Value(), 0);
392 uint32_t toUInt32(v8::Handle<v8::Value> value)
394 NonThrowableExceptionState exceptionState;
395 return toUInt32(value, NormalConversion, exceptionState);
398 int64_t toInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
400 // Fast case. The value is a 32-bit integer.
401 if (value->IsInt32())
402 return value->Int32Value();
404 // Can the value be converted to a number?
405 V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
406 if (numberObject.IsEmpty()) {
407 exceptionState.throwTypeError("Not convertible to a number value (of type 'long long'.)");
411 double x = numberObject->Value();
413 if (configuration == EnforceRange)
414 return enforceRange(x, -kJSMaxInteger, kJSMaxInteger, "long long", exceptionState);
416 // Does the value convert to nan or to an infinity?
417 if (std::isnan(x) || std::isinf(x))
420 // NaNs and +/-Infinity should be 0, otherwise modulo 2^64.
421 unsigned long long integer;
422 doubleToInteger(x, integer);
426 int64_t toInt64(v8::Handle<v8::Value> value)
428 NonThrowableExceptionState exceptionState;
429 return toInt64(value, NormalConversion, exceptionState);
432 uint64_t toUInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
434 // Fast case. The value is a 32-bit unsigned integer.
435 if (value->IsUint32())
436 return value->Uint32Value();
438 // Fast case. The value is a 32-bit integer.
439 if (value->IsInt32()) {
440 int32_t result = value->Int32Value();
443 if (configuration == EnforceRange) {
444 exceptionState.throwTypeError("Value is outside the 'unsigned long long' value range.");
450 // Can the value be converted to a number?
451 V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
452 if (numberObject.IsEmpty()) {
453 exceptionState.throwTypeError("Not convertible to a number value (of type 'unsigned long long'.)");
457 double x = numberObject->Value();
459 if (configuration == EnforceRange)
460 return enforceRange(x, 0, kJSMaxInteger, "unsigned long long", exceptionState);
462 // Does the value convert to nan or to an infinity?
463 if (std::isnan(x) || std::isinf(x))
466 // NaNs and +/-Infinity should be 0, otherwise modulo 2^64.
467 unsigned long long integer;
468 doubleToInteger(x, integer);
472 uint64_t toUInt64(v8::Handle<v8::Value> value)
474 NonThrowableExceptionState exceptionState;
475 return toUInt64(value, NormalConversion, exceptionState);
478 float toFloat(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
480 V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
481 return numberObject->NumberValue();
484 PassRefPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value> value, v8::Isolate* isolate)
486 RefPtr<XPathNSResolver> resolver;
487 if (V8XPathNSResolver::hasInstance(value, isolate))
488 resolver = V8XPathNSResolver::toNative(v8::Handle<v8::Object>::Cast(value));
489 else if (value->IsObject())
490 resolver = V8CustomXPathNSResolver::create(value->ToObject(), isolate);
494 v8::Handle<v8::Object> toInnerGlobalObject(v8::Handle<v8::Context> context)
496 return v8::Handle<v8::Object>::Cast(context->Global()->GetPrototype());
499 DOMWindow* toDOMWindow(v8::Handle<v8::Context> context)
501 v8::Handle<v8::Object> global = context->Global();
502 ASSERT(!global.IsEmpty());
503 v8::Handle<v8::Object> window = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), MainWorld));
504 if (!window.IsEmpty())
505 return V8Window::toNative(window);
506 window = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), IsolatedWorld));
507 ASSERT(!window.IsEmpty());
508 return V8Window::toNative(window);
511 ExecutionContext* toExecutionContext(v8::Handle<v8::Context> context)
513 v8::Handle<v8::Object> global = context->Global();
514 v8::Handle<v8::Object> windowWrapper = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), MainWorld));
515 if (!windowWrapper.IsEmpty())
516 return V8Window::toNative(windowWrapper)->executionContext();
517 windowWrapper = global->FindInstanceInPrototypeChain(V8Window::domTemplate(context->GetIsolate(), IsolatedWorld));
518 if (!windowWrapper.IsEmpty())
519 return V8Window::toNative(windowWrapper)->executionContext();
520 v8::Handle<v8::Object> workerWrapper = global->FindInstanceInPrototypeChain(V8WorkerGlobalScope::domTemplate(context->GetIsolate(), WorkerWorld));
521 if (!workerWrapper.IsEmpty())
522 return V8WorkerGlobalScope::toNative(workerWrapper)->executionContext();
523 // FIXME: Is this line of code reachable?
527 DOMWindow* activeDOMWindow()
529 v8::Handle<v8::Context> context = v8::Isolate::GetCurrent()->GetCallingContext();
530 if (context.IsEmpty()) {
531 // Unfortunately, when processing script from a plug-in, we might not
532 // have a calling context. In those cases, we fall back to the
534 context = v8::Isolate::GetCurrent()->GetEnteredContext();
536 return toDOMWindow(context);
539 ExecutionContext* activeExecutionContext()
541 v8::Handle<v8::Context> context = v8::Isolate::GetCurrent()->GetCallingContext();
542 if (context.IsEmpty()) {
543 // Unfortunately, when processing script from a plug-in, we might not
544 // have a calling context. In those cases, we fall back to the
546 context = v8::Isolate::GetCurrent()->GetEnteredContext();
548 return toExecutionContext(context);
551 DOMWindow* firstDOMWindow()
553 return toDOMWindow(v8::Isolate::GetCurrent()->GetEnteredContext());
556 Document* currentDocument()
558 return toDOMWindow(v8::Isolate::GetCurrent()->GetCurrentContext())->document();
561 Frame* toFrameIfNotDetached(v8::Handle<v8::Context> context)
563 DOMWindow* window = toDOMWindow(context);
564 if (window->isCurrentlyDisplayedInFrame())
565 return window->frame();
566 // We return 0 here because |context| is detached from the Frame. If we
567 // did return |frame| we could get in trouble because the frame could be
568 // navigated to another security origin.
572 v8::Local<v8::Context> toV8Context(ExecutionContext* context, DOMWrapperWorld* world)
574 if (context->isDocument()) {
576 if (Frame* frame = toDocument(context)->frame())
577 return frame->script().windowShell(world)->context();
578 } else if (context->isWorkerGlobalScope()) {
580 if (WorkerScriptController* script = toWorkerGlobalScope(context)->script())
581 return script->context();
583 return v8::Local<v8::Context>();
586 bool handleOutOfMemory()
588 v8::Local<v8::Context> context = v8::Isolate::GetCurrent()->GetCurrentContext();
590 if (!context->HasOutOfMemoryException())
593 // Warning, error, disable JS for this frame?
594 Frame* frame = toFrameIfNotDetached(context);
598 frame->script().clearForOutOfMemory();
599 frame->loader().client()->didExhaustMemoryAvailableForScript();
601 if (Settings* settings = frame->settings())
602 settings->setScriptEnabled(false);
607 v8::Local<v8::Value> handleMaxRecursionDepthExceeded(v8::Isolate* isolate)
609 throwError(v8RangeError, "Maximum call stack size exceeded.", isolate);
610 return v8::Local<v8::Value>();
613 void crashIfV8IsDead()
615 if (v8::V8::IsDead()) {
616 // FIXME: We temporarily deal with V8 internal error situations
617 // such as out-of-memory by crashing the renderer.
622 WrapperWorldType worldType(v8::Isolate* isolate)
624 V8PerIsolateData* data = V8PerIsolateData::from(isolate);
625 if (!data->workerDOMDataStore())
626 return worldTypeInMainThread(isolate);
630 WrapperWorldType worldTypeInMainThread(v8::Isolate* isolate)
632 if (!DOMWrapperWorld::isolatedWorldsExist())
634 ASSERT(!isolate->GetEnteredContext().IsEmpty());
635 DOMWrapperWorld* isolatedWorld = DOMWrapperWorld::isolatedWorld(isolate->GetEnteredContext());
637 return IsolatedWorld;
641 DOMWrapperWorld* isolatedWorldForIsolate(v8::Isolate* isolate)
643 V8PerIsolateData* data = V8PerIsolateData::from(isolate);
644 if (data->workerDOMDataStore())
646 if (!DOMWrapperWorld::isolatedWorldsExist())
648 ASSERT(isolate->InContext());
649 return DOMWrapperWorld::isolatedWorld(isolate->GetCurrentContext());
652 v8::Local<v8::Value> getHiddenValue(v8::Isolate* isolate, v8::Handle<v8::Object> object, const char* key)
654 return getHiddenValue(isolate, object, v8AtomicString(isolate, key));
657 v8::Local<v8::Value> getHiddenValue(v8::Isolate* isolate, v8::Handle<v8::Object> object, v8::Handle<v8::String> key)
659 return object->GetHiddenValue(key);
662 bool setHiddenValue(v8::Isolate* isolate, v8::Handle<v8::Object> object, const char* key, v8::Handle<v8::Value> value)
664 return setHiddenValue(isolate, object, v8AtomicString(isolate, key), value);
667 bool setHiddenValue(v8::Isolate* isolate, v8::Handle<v8::Object> object, v8::Handle<v8::String> key, v8::Handle<v8::Value> value)
669 return object->SetHiddenValue(key, value);
672 bool deleteHiddenValue(v8::Isolate* isolate, v8::Handle<v8::Object> object, const char* key)
674 return deleteHiddenValue(isolate, object, v8AtomicString(isolate, key));
677 bool deleteHiddenValue(v8::Isolate* isolate, v8::Handle<v8::Object> object, v8::Handle<v8::String> key)
679 return object->DeleteHiddenValue(key);
682 v8::Local<v8::Value> getHiddenValueFromMainWorldWrapper(v8::Isolate* isolate, ScriptWrappable* wrappable, const char* key)
684 return getHiddenValueFromMainWorldWrapper(isolate, wrappable, v8AtomicString(isolate, key));
687 v8::Local<v8::Value> getHiddenValueFromMainWorldWrapper(v8::Isolate* isolate, ScriptWrappable* wrappable, v8::Handle<v8::String> key)
689 v8::Local<v8::Object> wrapper = wrappable->newLocalWrapper(isolate);
690 return wrapper.IsEmpty() ? v8::Local<v8::Value>() : getHiddenValue(isolate, wrapper, key);
693 static gin::IsolateHolder* mainIsolateHolder = 0;
695 v8::Isolate* mainThreadIsolate()
697 ASSERT(mainIsolateHolder);
698 ASSERT(isMainThread());
699 return mainIsolateHolder->isolate();
702 void setMainThreadIsolate(v8::Isolate* isolate)
704 ASSERT(!mainIsolateHolder || !isolate);
705 ASSERT(isMainThread());
707 mainIsolateHolder = new gin::IsolateHolder(isolate);
709 delete mainIsolateHolder;
710 mainIsolateHolder = 0;
714 v8::Isolate* toIsolate(ExecutionContext* context)
716 if (context && context->isDocument())
717 return mainThreadIsolate();
718 return v8::Isolate::GetCurrent();
721 v8::Isolate* toIsolate(Frame* frame)
723 return frame->script().isolate();
726 } // namespace WebCore