/* * Copyright (C) 2008, 2009 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "V8NPUtils.h" #include "DOMWindow.h" #include "Frame.h" #include "PlatformString.h" #include "npruntime_impl.h" #include "npruntime_priv.h" #include "NPV8Object.h" #include "V8NPObject.h" #include "V8Proxy.h" namespace WebCore { void convertV8ObjectToNPVariant(v8::Local object, NPObject* owner, NPVariant* result) { VOID_TO_NPVARIANT(*result); // It is really the caller's responsibility to deal with the empty handle case because there could be different actions to // take in different contexts. ASSERT(!object.IsEmpty()); if (object.IsEmpty()) return; if (object->IsNumber()) DOUBLE_TO_NPVARIANT(object->NumberValue(), *result); else if (object->IsBoolean()) BOOLEAN_TO_NPVARIANT(object->BooleanValue(), *result); else if (object->IsNull()) NULL_TO_NPVARIANT(*result); else if (object->IsUndefined()) VOID_TO_NPVARIANT(*result); else if (object->IsString()) { v8::String::Utf8Value utf8(object); int length = utf8.length() + 1; char* utf8Chars = reinterpret_cast(malloc(length)); memcpy(utf8Chars, *utf8, length); STRINGN_TO_NPVARIANT(utf8Chars, utf8.length(), *result); } else if (object->IsObject()) { DOMWindow* window = V8Proxy::retrieveWindow(V8Proxy::currentContext()); NPObject* npobject = npCreateV8ScriptObject(0, v8::Handle::Cast(object), window); if (npobject) _NPN_RegisterObject(npobject, owner); OBJECT_TO_NPVARIANT(npobject, *result); } } v8::Handle convertNPVariantToV8Object(const NPVariant* variant, NPObject* npobject) { NPVariantType type = variant->type; switch (type) { case NPVariantType_Int32: return v8::Integer::New(NPVARIANT_TO_INT32(*variant)); case NPVariantType_Double: return v8::Number::New(NPVARIANT_TO_DOUBLE(*variant)); case NPVariantType_Bool: return NPVARIANT_TO_BOOLEAN(*variant) ? v8::True() : v8::False(); case NPVariantType_Null: return v8::Null(); case NPVariantType_Void: return v8::Undefined(); case NPVariantType_String: { NPString src = NPVARIANT_TO_STRING(*variant); return v8::String::New(src.UTF8Characters, src.UTF8Length); } case NPVariantType_Object: { NPObject* obj = NPVARIANT_TO_OBJECT(*variant); if (obj->_class == npScriptObjectClass) return reinterpret_cast(obj)->v8Object; return createV8ObjectForNPObject(obj, npobject); } default: return v8::Undefined(); } } // Helper function to create an NPN String Identifier from a v8 string. NPIdentifier getStringIdentifier(v8::Handle str) { const int kStackBufferSize = 100; int bufferLength = str->Utf8Length() + 1; if (bufferLength <= kStackBufferSize) { // Use local stack buffer to avoid heap allocations for small strings. Here we should only use the stack space for // stackBuffer when it's used, not when we use the heap. // // WriteUtf8 is guaranteed to generate a null-terminated string because bufferLength is constructed to be one greater // than the string length. char stackBuffer[kStackBufferSize]; str->WriteUtf8(stackBuffer, bufferLength); return _NPN_GetStringIdentifier(stackBuffer); } v8::String::Utf8Value utf8(str); return _NPN_GetStringIdentifier(*utf8); } struct ExceptionHandlerInfo { ExceptionHandlerInfo* previous; ExceptionHandler handler; void* data; }; static ExceptionHandlerInfo* topHandler; void pushExceptionHandler(ExceptionHandler handler, void* data) { ExceptionHandlerInfo* info = new ExceptionHandlerInfo; info->previous = topHandler; info->handler = handler; info->data = data; topHandler = info; } void popExceptionHandler() { ASSERT(topHandler); ExceptionHandlerInfo* doomed = topHandler; topHandler = topHandler->previous; delete doomed; } ExceptionCatcher::ExceptionCatcher() { if (!topHandler) m_tryCatch.SetVerbose(true); } ExceptionCatcher::~ExceptionCatcher() { if (!m_tryCatch.HasCaught()) return; if (topHandler) topHandler->handler(topHandler->data, *v8::String::Utf8Value(m_tryCatch.Exception())); } } // namespace WebCore