1 /* 2 * Copyright (C) 2009 Google Inc. All rights reserved. 3 * Copyright (C) 2012 Ericsson AB. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following disclaimer 13 * in the documentation and/or other materials provided with the 14 * distribution. 15 * * Neither the name of Google Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef V8Binding_h 33 #define V8Binding_h 34 35 #include "bindings/v8/DOMWrapperWorld.h" 36 #include "bindings/v8/V8BindingMacros.h" 37 #include "bindings/v8/V8PerIsolateData.h" 38 #include "bindings/v8/V8StringResource.h" 39 #include "bindings/v8/V8ThrowException.h" 40 #include "bindings/v8/V8ValueCache.h" 41 #include "wtf/MathExtras.h" 42 #include "wtf/text/AtomicString.h" 43 #include <v8.h> 44 45 namespace WebCore { 46 47 class DOMStringList; 48 class DOMWindow; 49 class Document; 50 class Frame; 51 class NodeFilter; 52 class ScriptExecutionContext; 53 class ScriptWrappable; 54 class XPathNSResolver; 55 56 const int kMaxRecursionDepth = 22; 57 58 // Schedule a DOM exception to be thrown, if the exception code is different 59 // from zero. 60 v8::Handle<v8::Value> setDOMException(int, v8::Isolate*); 61 v8::Handle<v8::Value> setDOMException(int, const String&, v8::Isolate*); 62 63 // Schedule a JavaScript error to be thrown. 64 v8::Handle<v8::Value> throwError(V8ErrorType, const String&, v8::Isolate*); 65 66 // Schedule a JavaScript error to be thrown. 67 v8::Handle<v8::Value> throwError(v8::Handle<v8::Value>); 68 69 // A helper for throwing JavaScript TypeError. 70 v8::Handle<v8::Value> throwTypeError(v8::Isolate*); 71 v8::Handle<v8::Value> throwTypeError(const String&, v8::Isolate*); 72 73 // A helper for throwing JavaScript TypeError for not enough arguments. 74 v8::Handle<v8::Value> throwNotEnoughArgumentsError(v8::Isolate*); 75 76 v8::ArrayBuffer::Allocator* v8ArrayBufferAllocator(); 77 78 v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value>, uint32_t& length, v8::Isolate*); 79 80 inline v8::Handle<v8::Value> argumentOrNull(const v8::FunctionCallbackInfo<v8::Value>& args, int index) 81 { 82 return index >= args.Length() ? v8::Local<v8::Value>() : args[index]; 83 } 84 85 // Since v8::Null(isolate) crashes if we pass a null isolate, 86 // we need to use v8NullWithCheck(isolate) if an isolate can be null. 87 // 88 // FIXME: Remove all null isolates from V8 bindings, and remove v8NullWithCheck(isolate). 89 inline v8::Handle<v8::Value> v8NullWithCheck(v8::Isolate* isolate) 90 { 91 return isolate ? v8::Null(isolate) : v8::Null(); 92 } 93 94 template<typename CallbackInfo, typename V> 95 inline void v8SetReturnValue(const CallbackInfo& args, V v) 96 { 97 args.GetReturnValue().Set(v); 98 } 99 100 template<typename CallbackInfo> 101 inline void v8SetReturnValueBool(const CallbackInfo& args, bool v) 102 { 103 args.GetReturnValue().Set(v); 104 } 105 106 template<typename CallbackInfo> 107 inline void v8SetReturnValueInt(const CallbackInfo& args, int v) 108 { 109 args.GetReturnValue().Set(v); 110 } 111 112 template<typename CallbackInfo> 113 inline void v8SetReturnValueUnsigned(const CallbackInfo& args, unsigned v) 114 { 115 args.GetReturnValue().Set(v); 116 } 117 118 template<typename CallbackInfo> 119 inline void v8SetReturnValueNull(const CallbackInfo& args) 120 { 121 args.GetReturnValue().SetNull(); 122 } 123 124 template<typename CallbackInfo> 125 inline void v8SetReturnValueUndefined(const CallbackInfo& args) 126 { 127 args.GetReturnValue().SetUndefined(); 128 } 129 130 template<typename CallbackInfo> 131 inline void v8SetReturnValueEmptyString(const CallbackInfo& args) 132 { 133 args.GetReturnValue().SetEmptyString(); 134 } 135 136 template <class CallbackInfo> 137 inline void v8SetReturnValueString(const CallbackInfo& info, const String& string, v8::Isolate* isolate) 138 { 139 if (string.isNull()) { 140 v8SetReturnValueEmptyString(info); 141 return; 142 } 143 V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl()); 144 } 145 146 template <class CallbackInfo> 147 inline void v8SetReturnValueStringOrNull(const CallbackInfo& info, const String& string, v8::Isolate* isolate) 148 { 149 if (string.isNull()) { 150 v8SetReturnValueNull(info); 151 return; 152 } 153 V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl()); 154 } 155 156 template <class CallbackInfo> 157 inline void v8SetReturnValueStringOrUndefined(const CallbackInfo& info, const String& string, v8::Isolate* isolate) 158 { 159 if (string.isNull()) { 160 v8SetReturnValueUndefined(info); 161 return; 162 } 163 V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl()); 164 } 165 166 // Convert v8 types to a WTF::String. If the V8 string is not already 167 // an external string then it is transformed into an external string at this 168 // point to avoid repeated conversions. 169 // 170 // FIXME: Replace all the call sites with V8TRYCATCH_FOR_V8STRINGRESOURCE(). 171 // Using this method will lead to a wrong behavior, because you cannot stop the 172 // execution when an exception is thrown inside stringResource.prepare(). 173 inline String toWebCoreString(v8::Handle<v8::Value> value) 174 { 175 V8StringResource<> stringResource(value); 176 if (!stringResource.prepare()) 177 return String(); 178 return stringResource; 179 } 180 181 // FIXME: See the above comment. 182 inline String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value) 183 { 184 V8StringResource<WithNullCheck> stringResource(value); 185 if (!stringResource.prepare()) 186 return String(); 187 return stringResource; 188 } 189 190 // FIXME: See the above comment. 191 inline String toWebCoreStringWithUndefinedOrNullCheck(v8::Handle<v8::Value> value) 192 { 193 V8StringResource<WithUndefinedOrNullCheck> stringResource(value); 194 if (!stringResource.prepare()) 195 return String(); 196 return stringResource; 197 } 198 199 // FIXME: See the above comment. 200 inline AtomicString toWebCoreAtomicString(v8::Handle<v8::Value> value) 201 { 202 V8StringResource<> stringResource(value); 203 if (!stringResource.prepare()) 204 return AtomicString(); 205 return stringResource; 206 } 207 208 // FIXME: See the above comment. 209 inline AtomicString toWebCoreAtomicStringWithNullCheck(v8::Handle<v8::Value> value) 210 { 211 V8StringResource<WithNullCheck> stringResource(value); 212 if (!stringResource.prepare()) 213 return AtomicString(); 214 return stringResource; 215 } 216 217 // Convert a string to a V8 string. 218 // Return a V8 external string that shares the underlying buffer with the given 219 // WebCore string. The reference counting mechanism is used to keep the 220 // underlying buffer alive while the string is still live in the V8 engine. 221 inline v8::Handle<v8::String> v8String(const String& string, v8::Isolate* isolate) 222 { 223 if (string.isNull()) 224 return v8::String::Empty(isolate); 225 return V8PerIsolateData::from(isolate)->stringCache()->v8ExternalString(string.impl(), isolate); 226 } 227 228 inline v8::Handle<v8::Value> v8Undefined() 229 { 230 return v8::Handle<v8::Value>(); 231 } 232 233 template <class T> 234 struct V8ValueTraits { 235 static inline v8::Handle<v8::Value> arrayV8Value(const T& value, v8::Isolate* isolate) 236 { 237 return toV8(WTF::getPtr(value), v8::Handle<v8::Object>(), isolate); 238 } 239 }; 240 241 template<> 242 struct V8ValueTraits<String> { 243 static inline v8::Handle<v8::Value> arrayV8Value(const String& value, v8::Isolate* isolate) 244 { 245 return v8String(value, isolate); 246 } 247 }; 248 249 template<> 250 struct V8ValueTraits<unsigned> { 251 static inline v8::Handle<v8::Value> arrayV8Value(const unsigned& value, v8::Isolate* isolate) 252 { 253 return v8::Integer::NewFromUnsigned(value, isolate); 254 } 255 }; 256 257 template<> 258 struct V8ValueTraits<unsigned long> { 259 static inline v8::Handle<v8::Value> arrayV8Value(const unsigned long& value, v8::Isolate* isolate) 260 { 261 return v8::Integer::NewFromUnsigned(value, isolate); 262 } 263 }; 264 265 template<> 266 struct V8ValueTraits<float> { 267 static inline v8::Handle<v8::Value> arrayV8Value(const float& value, v8::Isolate*) 268 { 269 return v8::Number::New(value); 270 } 271 }; 272 273 template<> 274 struct V8ValueTraits<double> { 275 static inline v8::Handle<v8::Value> arrayV8Value(const double& value, v8::Isolate*) 276 { 277 return v8::Number::New(value); 278 } 279 }; 280 281 template<typename T, size_t inlineCapacity> 282 v8::Handle<v8::Value> v8Array(const Vector<T, inlineCapacity>& iterator, v8::Isolate* isolate) 283 { 284 v8::Local<v8::Array> result = v8::Array::New(iterator.size()); 285 int index = 0; 286 typename Vector<T, inlineCapacity>::const_iterator end = iterator.end(); 287 typedef V8ValueTraits<T> TraitsType; 288 for (typename Vector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter) 289 result->Set(v8::Integer::New(index++, isolate), TraitsType::arrayV8Value(*iter, isolate)); 290 return result; 291 } 292 293 v8::Handle<v8::Value> v8Array(PassRefPtr<DOMStringList>, v8::Isolate*); 294 295 // Conversion flags, used in toIntXX/toUIntXX. 296 enum IntegerConversionConfiguration { 297 NormalConversion, 298 EnforceRange, 299 // FIXME: Implement Clamp 300 }; 301 302 // Convert a value to a 8-bit signed integer. The conversion fails if the 303 // value cannot be converted to a number or the range violated per WebIDL: 304 // http://www.w3.org/TR/WebIDL/#es-byte 305 int8_t toInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok); 306 inline int8_t toInt8(v8::Handle<v8::Value> value, bool& ok) { return toInt8(value, NormalConversion, ok); } 307 308 // Convert a value to a 8-bit integer assuming the conversion cannot fail. 309 inline int8_t toInt8(v8::Handle<v8::Value> value) 310 { 311 bool ok; 312 return toInt8(value, NormalConversion, ok); 313 } 314 315 // Convert a value to a 8-bit unsigned integer. The conversion fails if the 316 // value cannot be converted to a number or the range violated per WebIDL: 317 // http://www.w3.org/TR/WebIDL/#es-octet 318 uint8_t toUInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok); 319 inline uint8_t toUInt8(v8::Handle<v8::Value> value, bool& ok) { return toUInt8(value, NormalConversion, ok); } 320 321 // Convert a value to a 8-bit unsigned integer assuming the conversion cannot fail. 322 inline uint8_t toUInt8(v8::Handle<v8::Value> value) 323 { 324 bool ok; 325 return toUInt8(value, NormalConversion, ok); 326 } 327 328 // Convert a value to a 32-bit signed integer. The conversion fails if the 329 // value cannot be converted to a number or the range violated per WebIDL: 330 // http://www.w3.org/TR/WebIDL/#es-long 331 int32_t toInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok); 332 inline int32_t toInt32(v8::Handle<v8::Value> value, bool& ok) { return toInt32(value, NormalConversion, ok); } 333 334 // Convert a value to a 32-bit integer assuming the conversion cannot fail. 335 inline int32_t toInt32(v8::Handle<v8::Value> value) 336 { 337 bool ok; 338 return toInt32(value, NormalConversion, ok); 339 } 340 341 // Convert a value to a 32-bit unsigned integer. The conversion fails if the 342 // value cannot be converted to a number or the range violated per WebIDL: 343 // http://www.w3.org/TR/WebIDL/#es-unsigned-long 344 uint32_t toUInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok); 345 inline uint32_t toUInt32(v8::Handle<v8::Value> value, bool& ok) { return toUInt32(value, NormalConversion, ok); } 346 347 // Convert a value to a 32-bit unsigned integer assuming the conversion cannot fail. 348 inline uint32_t toUInt32(v8::Handle<v8::Value> value) 349 { 350 bool ok; 351 return toUInt32(value, NormalConversion, ok); 352 } 353 354 // Convert a value to a 64-bit signed integer. The conversion fails if the 355 // value cannot be converted to a number or the range violated per WebIDL: 356 // http://www.w3.org/TR/WebIDL/#es-long-long 357 int64_t toInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok); 358 359 // Convert a value to a 64-bit integer assuming the conversion cannot fail. 360 inline int64_t toInt64(v8::Handle<v8::Value> value) 361 { 362 bool ok; 363 return toInt64(value, NormalConversion, ok); 364 } 365 366 // Convert a value to a 64-bit unsigned integer. The conversion fails if the 367 // value cannot be converted to a number or the range violated per WebIDL: 368 // http://www.w3.org/TR/WebIDL/#es-unsigned-long-long 369 uint64_t toUInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok); 370 371 // Convert a value to a 64-bit unsigned integer assuming the conversion cannot fail. 372 inline uint64_t toUInt64(v8::Handle<v8::Value> value) 373 { 374 bool ok; 375 return toUInt64(value, NormalConversion, ok); 376 } 377 378 inline float toFloat(v8::Local<v8::Value> value) 379 { 380 return static_cast<float>(value->NumberValue()); 381 } 382 383 WrapperWorldType worldType(v8::Isolate*); 384 WrapperWorldType worldTypeInMainThread(v8::Isolate*); 385 386 DOMWrapperWorld* isolatedWorldForIsolate(v8::Isolate*); 387 388 template<class T> struct NativeValueTraits; 389 390 template<> 391 struct NativeValueTraits<String> { 392 static inline String nativeValue(const v8::Handle<v8::Value>& value) 393 { 394 return toWebCoreString(value); 395 } 396 }; 397 398 template<> 399 struct NativeValueTraits<unsigned> { 400 static inline unsigned nativeValue(const v8::Handle<v8::Value>& value) 401 { 402 return toUInt32(value); 403 } 404 }; 405 406 template<> 407 struct NativeValueTraits<float> { 408 static inline float nativeValue(const v8::Handle<v8::Value>& value) 409 { 410 return static_cast<float>(value->NumberValue()); 411 } 412 }; 413 414 template<> 415 struct NativeValueTraits<double> { 416 static inline double nativeValue(const v8::Handle<v8::Value>& value) 417 { 418 return static_cast<double>(value->NumberValue()); 419 } 420 }; 421 422 // Converts a JavaScript value to an array as per the Web IDL specification: 423 // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array 424 template <class T, class V8T> 425 Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, v8::Isolate* isolate, bool* success = 0) 426 { 427 if (success) 428 *success = true; 429 430 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); 431 uint32_t length = 0; 432 if (value->IsArray()) 433 length = v8::Local<v8::Array>::Cast(v8Value)->Length(); 434 else if (toV8Sequence(value, length, isolate).IsEmpty()) 435 return Vector<RefPtr<T> >(); 436 437 Vector<RefPtr<T> > result; 438 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); 439 for (uint32_t i = 0; i < length; ++i) { 440 v8::Handle<v8::Value> element = object->Get(i); 441 442 if (V8T::HasInstance(element, isolate, worldType(isolate))) { 443 v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast(element); 444 result.append(V8T::toNative(elementObject)); 445 } else { 446 if (success) 447 *success = false; 448 throwTypeError("Invalid Array element type", isolate); 449 return Vector<RefPtr<T> >(); 450 } 451 } 452 return result; 453 } 454 455 // Converts a JavaScript value to an array as per the Web IDL specification: 456 // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array 457 template <class T> 458 Vector<T> toNativeArray(v8::Handle<v8::Value> value, v8::Isolate* isolate) 459 { 460 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); 461 uint32_t length = 0; 462 if (value->IsArray()) 463 length = v8::Local<v8::Array>::Cast(v8Value)->Length(); 464 else if (toV8Sequence(value, length, isolate).IsEmpty()) 465 return Vector<T>(); 466 467 Vector<T> result; 468 typedef NativeValueTraits<T> TraitsType; 469 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); 470 for (uint32_t i = 0; i < length; ++i) 471 result.append(TraitsType::nativeValue(object->Get(i))); 472 return result; 473 } 474 475 template <class T> 476 Vector<T> toNativeArguments(const v8::FunctionCallbackInfo<v8::Value>& args, int startIndex) 477 { 478 ASSERT(startIndex <= args.Length()); 479 Vector<T> result; 480 typedef NativeValueTraits<T> TraitsType; 481 int length = args.Length(); 482 for (int i = startIndex; i < length; ++i) 483 result.append(TraitsType::nativeValue(args[i])); 484 return result; 485 } 486 487 Vector<v8::Handle<v8::Value> > toVectorOfArguments(const v8::FunctionCallbackInfo<v8::Value>& args); 488 489 // Validates that the passed object is a sequence type per WebIDL spec 490 // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-sequence 491 inline v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value> value, uint32_t& length, v8::Isolate* isolate) 492 { 493 // Attempt converting to a sequence if the value is not already an array but is 494 // any kind of object except for a native Date object or a native RegExp object. 495 ASSERT(!value->IsArray()); 496 // FIXME: Do we really need to special case Date and RegExp object? 497 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22806 498 if (!value->IsObject() || value->IsDate() || value->IsRegExp()) { 499 throwTypeError(isolate); 500 return v8Undefined(); 501 } 502 503 v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); 504 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); 505 506 // FIXME: The specification states that the length property should be used as fallback, if value 507 // is not a platform object that supports indexed properties. If it supports indexed properties, 508 // length should actually be one greater than values maximum indexed property index. 509 V8TRYCATCH(v8::Local<v8::Value>, lengthValue, object->Get(v8::String::NewSymbol("length"))); 510 511 if (lengthValue->IsUndefined() || lengthValue->IsNull()) { 512 throwTypeError(isolate); 513 return v8Undefined(); 514 } 515 516 V8TRYCATCH(uint32_t, sequenceLength, lengthValue->Int32Value()); 517 length = sequenceLength; 518 519 return v8Value; 520 } 521 522 PassRefPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value>, v8::Isolate*); 523 524 inline bool isUndefinedOrNull(v8::Handle<v8::Value> value) 525 { 526 return value->IsNull() || value->IsUndefined(); 527 } 528 529 // Returns true if the provided object is to be considered a 'host object', as used in the 530 // HTML5 structured clone algorithm. 531 inline bool isHostObject(v8::Handle<v8::Object> object) 532 { 533 // If the object has any internal fields, then we won't be able to serialize or deserialize 534 // them; conveniently, this is also a quick way to detect DOM wrapper objects, because 535 // the mechanism for these relies on data stored in these fields. We should 536 // catch external array data as a special case. 537 return object->InternalFieldCount() || object->HasIndexedPropertiesInExternalArrayData(); 538 } 539 540 inline v8::Handle<v8::Boolean> v8Boolean(bool value) 541 { 542 return value ? v8::True() : v8::False(); 543 } 544 545 inline v8::Handle<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) 546 { 547 return value ? v8::True(isolate) : v8::False(isolate); 548 } 549 550 // Since v8Boolean(value, isolate) crashes if we pass a null isolate, 551 // we need to use v8BooleanWithCheck(value, isolate) if an isolate can be null. 552 // 553 // FIXME: Remove all null isolates from V8 bindings, and remove v8BooleanWithCheck(value, isolate). 554 inline v8::Handle<v8::Boolean> v8BooleanWithCheck(bool value, v8::Isolate* isolate) 555 { 556 return isolate ? v8Boolean(value, isolate) : v8Boolean(value); 557 } 558 559 inline double toWebCoreDate(v8::Handle<v8::Value> object) 560 { 561 return (object->IsDate() || object->IsNumber()) ? object->NumberValue() : std::numeric_limits<double>::quiet_NaN(); 562 } 563 564 inline v8::Handle<v8::Value> v8DateOrNull(double value, v8::Isolate* isolate) 565 { 566 ASSERT(isolate); 567 return std::isfinite(value) ? v8::Date::New(value) : v8NullWithCheck(isolate); 568 } 569 570 v8::Handle<v8::FunctionTemplate> createRawTemplate(v8::Isolate*); 571 572 PassRefPtr<DOMStringList> toDOMStringList(v8::Handle<v8::Value>, v8::Isolate*); 573 PassRefPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>, v8::Isolate*); 574 575 v8::Handle<v8::Object> toInnerGlobalObject(v8::Handle<v8::Context>); 576 DOMWindow* toDOMWindow(v8::Handle<v8::Context>); 577 ScriptExecutionContext* toScriptExecutionContext(v8::Handle<v8::Context>); 578 579 DOMWindow* activeDOMWindow(); 580 DOMWindow* firstDOMWindow(); 581 Document* currentDocument(); 582 583 // Returns the context associated with a ScriptExecutionContext. 584 v8::Local<v8::Context> toV8Context(ScriptExecutionContext*, DOMWrapperWorld*); 585 586 // Returns the frame object of the window object associated with 587 // a context, if the window is currently being displayed in the Frame. 588 Frame* toFrameIfNotDetached(v8::Handle<v8::Context>); 589 590 inline DOMWrapperWorld* isolatedWorldForEnteredContext() 591 { 592 v8::Handle<v8::Context> context = v8::Context::GetEntered(); 593 if (context.IsEmpty()) 594 return 0; 595 return DOMWrapperWorld::isolatedWorld(context); 596 } 597 598 // FIXME: This will be soon embedded in the generated code. 599 template<class Collection> static void indexedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) 600 { 601 Collection* collection = reinterpret_cast<Collection*>(info.Holder()->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex)); 602 int length = collection->length(); 603 v8::Handle<v8::Array> properties = v8::Array::New(length); 604 for (int i = 0; i < length; ++i) { 605 // FIXME: Do we need to check that the item function returns a non-null value for this index? 606 v8::Handle<v8::Integer> integer = v8::Integer::New(i, info.GetIsolate()); 607 properties->Set(integer, integer); 608 } 609 v8SetReturnValue(info, properties); 610 } 611 612 // If the current context causes out of memory, JavaScript setting 613 // is disabled and it returns true. 614 bool handleOutOfMemory(); 615 // FIXME: This should receive an Isolate. 616 v8::Local<v8::Value> handleMaxRecursionDepthExceeded(); 617 618 void crashIfV8IsDead(); 619 620 template <class T> 621 v8::Handle<T> unsafeHandleFromRawValue(const T* value) 622 { 623 const v8::Handle<T>* handle = reinterpret_cast<const v8::Handle<T>*>(&value); 624 return *handle; 625 } 626 627 // Attaches |environment| to |function| and returns it. 628 inline v8::Local<v8::Function> createClosure(v8::FunctionCallback function, v8::Handle<v8::Value> environment) 629 { 630 return v8::FunctionTemplate::New(function, environment)->GetFunction(); 631 } 632 633 v8::Local<v8::Value> getHiddenValueFromMainWorldWrapper(v8::Isolate*, ScriptWrappable*, v8::Handle<v8::String> key); 634 635 } // namespace WebCore 636 637 #endif // V8Binding_h 638