10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch/*
20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Redistribution and use in source and binary forms, with or without
50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * modification, are permitted provided that the following conditions are
60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * met:
70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *     * Redistributions of source code must retain the above copyright
90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * notice, this list of conditions and the following disclaimer.
100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *     * Redistributions in binary form must reproduce the above
110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * copyright notice, this list of conditions and the following disclaimer
120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * in the documentation and/or other materials provided with the
130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * distribution.
140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *     * Neither the name of Google Inc. nor the names of its
150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * contributors may be used to endorse or promote products derived from
160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * this software without specific prior written permission.
170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch */
300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "config.h"
320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8Proxy.h"
330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "CSSMutableStyleDeclaration.h"
3506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "CachedMetadata.h"
36231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "DateExtension.h"
370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "DocumentLoader.h"
38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "Frame.h"
390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "FrameLoaderClient.h"
404a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch#include "IDBDatabaseException.h"
41e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "IDBFactoryBackendInterface.h"
42e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "IDBPendingTransactionMonitor.h"
43a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "InspectorInstrumentation.h"
44231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "Page.h"
45231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "PageGroup.h"
463eb2fab210a9ae636c55b30b23bb53b130d1efb6Steve Block#include "PlatformBridge.h"
470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "ScriptController.h"
48dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "Settings.h"
49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "StorageNamespace.h"
500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8Binding.h"
51d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "V8BindingState.h"
520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8Collection.h"
535e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#include "V8DOMCoreException.h"
540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8DOMMap.h"
550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8DOMWindow.h"
565e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#include "V8EventException.h"
57e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "V8FileException.h"
580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8HiddenPropertyName.h"
59d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "V8IsolatedContext.h"
605e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#include "V8RangeException.h"
6106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "V8SQLException.h"
625e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#include "V8XMLHttpRequestException.h"
635e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#include "V8XPathException.h"
64dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "WorkerContext.h"
65cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "WorkerContextExecutionProxy.h"
660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
674a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch#if ENABLE(INDEXED_DATABASE)
684a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch#include "V8IDBDatabaseException.h"
694a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch#endif
704a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
71dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if ENABLE(SVG)
72dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "V8SVGException.h"
73dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
74dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
75bc7b84de3fd863c500a8169fd00dca3811cadbb3Steve Block#include <algorithm>
76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <stdio.h>
77bc7b84de3fd863c500a8169fd00dca3811cadbb3Steve Block#include <utility>
780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/Assertions.h>
790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/OwnArrayPtr.h>
8006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include <wtf/OwnPtr.h>
810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/StdLibExtras.h>
82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <wtf/StringExtras.h>
830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/UnusedParam.h>
84a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include <wtf/text/StringConcatenate.h>
850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochnamespace WebCore {
870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// Static list of registered extensions
89231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockV8Extensions V8Proxy::m_extensions;
900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
91643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid batchConfigureAttributes(v8::Handle<v8::ObjectTemplate> instance,
92643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                              v8::Handle<v8::ObjectTemplate> proto,
93643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                              const BatchedAttribute* attributes,
94643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                              size_t attributeCount)
950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
96cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    for (size_t i = 0; i < attributeCount; ++i)
97cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        configureAttribute(instance, proto, attributes[i]);
980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
100643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid batchConfigureCallbacks(v8::Handle<v8::ObjectTemplate> proto,
101643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                             v8::Handle<v8::Signature> signature,
102643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                             v8::PropertyAttribute attributes,
103643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                             const BatchedCallback* callbacks,
104643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                             size_t callbackCount)
105643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
106643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    for (size_t i = 0; i < callbackCount; ++i) {
107643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        proto->Set(v8::String::New(callbacks[i].name),
108643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                   v8::FunctionTemplate::New(callbacks[i].callback,
109643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                             v8::Handle<v8::Value>(),
110643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                             signature),
111643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                   attributes);
112643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
113643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
114643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
115643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid batchConfigureConstants(v8::Handle<v8::FunctionTemplate> functionDescriptor,
116643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                             v8::Handle<v8::ObjectTemplate> proto,
117643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                             const BatchedConstant* constants,
118643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                             size_t constantCount)
1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    for (size_t i = 0; i < constantCount; ++i) {
1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        const BatchedConstant* constant = &constants[i];
1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        functionDescriptor->Set(v8::String::New(constant->name), v8::Integer::New(constant->value), v8::ReadOnly);
1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        proto->Set(v8::String::New(constant->name), v8::Integer::New(constant->value), v8::ReadOnly);
1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochtypedef HashMap<Node*, v8::Object*> DOMNodeMap;
1280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochtypedef HashMap<void*, v8::Object*> DOMObjectMap;
1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochtypedef HashMap<int, v8::FunctionTemplate*> FunctionTemplateMap;
1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool AllowAllocation::m_current = false;
1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
133ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochstatic void addMessageToConsole(Page* page, const String& message, const String& sourceID, unsigned lineNumber)
134ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{
135ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    ASSERT(page);
136ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    Console* console = page->mainFrame()->domWindow()->console();
137ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    console->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message, lineNumber, sourceID);
138ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch}
139ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid logInfo(Frame* frame, const String& message, const String& url)
1410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    Page* page = frame->page();
1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!page)
1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
145ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    addMessageToConsole(page, message, url, 0);
1460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
148ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid V8Proxy::reportUnsafeAccessTo(Frame* target)
1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(target);
1510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    Document* targetDocument = target->document();
1520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!targetDocument)
1530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
1540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    Frame* source = V8Proxy::retrieveFrameForEnteredContext();
1562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!source)
1572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
1582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    Page* page = source->page();
1592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!page)
1602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    Document* sourceDocument = source->document();
1632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!sourceDocument)
1642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return; // Ignore error if the source document is gone.
1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // FIXME: This error message should contain more specifics of why the same
1670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // origin check has failed.
168a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    String str = makeString("Unsafe JavaScript attempt to access frame with URL ", targetDocument->url().string(),
169a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                            " from frame with URL ", sourceDocument->url().string(), ". Domains, protocols and ports must match.\n");
1700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Build a console message with fake source ID and line number.
1720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    const String kSourceID = "";
1730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    const int kLineNumber = 1;
1740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
175ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    // NOTE: Safari prints the message in the target page, but it seems like
176ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    // it should be in the source page. Even for delayed messages, we put it in
177ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    // the source page.
1782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    addMessageToConsole(page, str, kSourceID, kLineNumber);
1790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void handleFatalErrorInV8()
1820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // FIXME: We temporarily deal with V8 internal error situations
1840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // such as out-of-memory by crashing the renderer.
1850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    CRASH();
1860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockV8Proxy::V8Proxy(Frame* frame)
189cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    : m_frame(frame)
190d0825bca7fe65beaee391d30da42e937db621564Steve Block    , m_windowShell(V8DOMWindowShell::create(frame))
191cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    , m_inlineCode(false)
192cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    , m_timerCallback(false)
193cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    , m_recursion(0)
194cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
195cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
196231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochV8Proxy::~V8Proxy()
1980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    clearForClose();
200d0825bca7fe65beaee391d30da42e937db621564Steve Block    windowShell()->destroyGlobal();
2010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2031dc835977a4eb41ef79490200c176352bae43cc1Russell Brennerv8::Handle<v8::Script> V8Proxy::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition0& scriptStartPosition, v8::ScriptData* scriptData)
2040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    const uint16_t* fileNameString = fromWebCoreString(fileName);
2060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Handle<v8::String> name = v8::String::New(fileNameString, fileName.length());
2076b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    v8::Handle<v8::Integer> line = v8::Integer::New(scriptStartPosition.m_line.zeroBasedInt());
2086b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    v8::Handle<v8::Integer> column = v8::Integer::New(scriptStartPosition.m_column.zeroBasedInt());
2096b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    v8::ScriptOrigin origin(name, line, column);
21006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    v8::Handle<v8::Script> script = v8::Script::Compile(code, &origin, scriptData);
2110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return script;
2120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool V8Proxy::handleOutOfMemory()
2150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Local<v8::Context> context = v8::Context::GetCurrent();
2170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!context->HasOutOfMemoryException())
2190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return false;
2200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Warning, error, disable JS for this frame?
2220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    Frame* frame = V8Proxy::retrieveFrame(context);
2230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    V8Proxy* proxy = V8Proxy::retrieve(frame);
2250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (proxy) {
2260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Clean m_context, and event handlers.
2270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        proxy->clearForClose();
2280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
229d0825bca7fe65beaee391d30da42e937db621564Steve Block        proxy->windowShell()->destroyGlobal();
2300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2325b74a25b9145efeca2665ff63c586182e701ddbdBen Murdoch#if PLATFORM(CHROMIUM)
2333eb2fab210a9ae636c55b30b23bb53b130d1efb6Steve Block    PlatformBridge::notifyJSOutOfMemory(frame);
2345b74a25b9145efeca2665ff63c586182e701ddbdBen Murdoch#endif
235ba51ea61f184429a046b2a212fcc905083a360feSteve Block
2360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Disable JS.
2370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    Settings* settings = frame->settings();
2380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(settings);
2390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    settings->setJavaScriptEnabled(false);
2400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return true;
2420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
244231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid V8Proxy::evaluateInIsolatedWorld(int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup)
2450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
246d0825bca7fe65beaee391d30da42e937db621564Steve Block    // FIXME: This will need to get reorganized once we have a windowShell for the isolated world.
247d0825bca7fe65beaee391d30da42e937db621564Steve Block    windowShell()->initContextIfNeeded();
248231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
249231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    v8::HandleScope handleScope;
250d0825bca7fe65beaee391d30da42e937db621564Steve Block    V8IsolatedContext* isolatedContext = 0;
251231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
252231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (worldID > 0) {
253231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        IsolatedWorldMap::iterator iter = m_isolatedWorlds.find(worldID);
254231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (iter != m_isolatedWorlds.end()) {
255d0825bca7fe65beaee391d30da42e937db621564Steve Block            isolatedContext = iter->second;
256231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else {
257d0825bca7fe65beaee391d30da42e937db621564Steve Block            isolatedContext = new V8IsolatedContext(this, extensionGroup);
258d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (isolatedContext->context().IsEmpty()) {
259d0825bca7fe65beaee391d30da42e937db621564Steve Block                delete isolatedContext;
260643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return;
261643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
262643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
263d0825bca7fe65beaee391d30da42e937db621564Steve Block            // FIXME: We should change this to using window shells to match JSC.
264d0825bca7fe65beaee391d30da42e937db621564Steve Block            m_isolatedWorlds.set(worldID, isolatedContext);
265cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
266cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            // Setup context id for JS debugger.
267d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!setInjectedScriptContextDebugId(isolatedContext->context())) {
268643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                m_isolatedWorlds.take(worldID);
269d0825bca7fe65beaee391d30da42e937db621564Steve Block                delete isolatedContext;
270643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return;
271643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
272231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
273231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    } else {
274d0825bca7fe65beaee391d30da42e937db621564Steve Block        isolatedContext = new V8IsolatedContext(this, extensionGroup);
275d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (isolatedContext->context().IsEmpty()) {
276d0825bca7fe65beaee391d30da42e937db621564Steve Block            delete isolatedContext;
277643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return;
278643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
279231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
280231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
281d0825bca7fe65beaee391d30da42e937db621564Steve Block    v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolatedContext->context());
282231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    v8::Context::Scope context_scope(context);
283231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    for (size_t i = 0; i < sources.size(); ++i)
284231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block      evaluate(sources[i], 0);
285231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
286231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (worldID == 0)
287d0825bca7fe65beaee391d30da42e937db621564Steve Block      isolatedContext->destroy();
2880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
290643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool V8Proxy::setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContext)
291cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
292cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    // Setup context id for JS debugger.
293cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    v8::Context::Scope contextScope(targetContext);
294d0825bca7fe65beaee391d30da42e937db621564Steve Block    v8::Handle<v8::Context> context = windowShell()->context();
295d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (context.IsEmpty())
296643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return false;
297d0825bca7fe65beaee391d30da42e937db621564Steve Block    int debugId = contextDebugId(context);
298cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
299643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    char buffer[32];
300643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (debugId == -1)
301643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        snprintf(buffer, sizeof(buffer), "injected");
302643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    else
303643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        snprintf(buffer, sizeof(buffer), "injected,%d", debugId);
304643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    targetContext->SetData(v8::String::New(buffer));
305643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
306643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return true;
307cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
308cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
30906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian MonsenPassOwnPtr<v8::ScriptData> V8Proxy::precompileScript(v8::Handle<v8::String> code, CachedScript* cachedScript)
31006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
31106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    // A pseudo-randomly chosen ID used to store and retrieve V8 ScriptData from
31206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    // the CachedScript. If the format changes, this ID should be changed too.
31306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    static const unsigned dataTypeID = 0xECC13BD7;
31406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
31506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    // Very small scripts are not worth the effort to preparse.
31606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    static const int minPreparseLength = 1024;
31706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
31806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    if (!cachedScript || code->Length() < minPreparseLength)
31906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        return 0;
32006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
32106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    CachedMetadata* cachedMetadata = cachedScript->cachedMetadata(dataTypeID);
32206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    if (cachedMetadata)
32306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        return v8::ScriptData::New(cachedMetadata->data(), cachedMetadata->size());
32406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
32506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    OwnPtr<v8::ScriptData> scriptData(v8::ScriptData::PreCompile(code));
32606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    cachedScript->setCachedMetadata(dataTypeID, scriptData->Data(), scriptData->Length());
32706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
32806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return scriptData.release();
32906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
33006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
331ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockbool V8Proxy::executingScript() const
332ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
333ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    return m_recursion;
334ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
335ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
3360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Local<v8::Value> V8Proxy::evaluate(const ScriptSourceCode& source, Node* node)
3370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
3380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(v8::Context::InContext());
3390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
340643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    V8GCController::checkMemoryUsage();
341643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
342a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willEvaluateScript(m_frame, source.url().isNull() ? String() : source.url().string(), source.startLine());
343643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
3440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Local<v8::Value> result;
3450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
346231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Isolate exceptions that occur when compiling and executing
347231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // the code. These exceptions should not interfere with
348231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // javascript code we might evaluate from C++ when returning
349231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // from here.
3500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        v8::TryCatch tryCatch;
3510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        tryCatch.SetVerbose(true);
3520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
353231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Compile the script.
354231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        v8::Local<v8::String> code = v8ExternalString(source.source());
3553f252f84468859d129a8c6a9302412d2e6e5a3faSteve Block#if PLATFORM(CHROMIUM)
3563eb2fab210a9ae636c55b30b23bb53b130d1efb6Steve Block        PlatformBridge::traceEventBegin("v8.compile", node, "");
3573f252f84468859d129a8c6a9302412d2e6e5a3faSteve Block#endif
35806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        OwnPtr<v8::ScriptData> scriptData = precompileScript(code, source.cachedScript());
359231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
360231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at
361231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // 1, whereas v8 starts at 0.
3626b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        v8::Handle<v8::Script> script = compileScript(code, source.url(), WTF::toZeroBasedTextPosition(source.startPosition()), scriptData.get());
3633f252f84468859d129a8c6a9302412d2e6e5a3faSteve Block#if PLATFORM(CHROMIUM)
3643eb2fab210a9ae636c55b30b23bb53b130d1efb6Steve Block        PlatformBridge::traceEventEnd("v8.compile", node, "");
365231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3663eb2fab210a9ae636c55b30b23bb53b130d1efb6Steve Block        PlatformBridge::traceEventBegin("v8.run", node, "");
3673f252f84468859d129a8c6a9302412d2e6e5a3faSteve Block#endif
3680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Set inlineCode to true for <a href="javascript:doSomething()">
3690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // and false for <script>doSomething</script>. We make a rough guess at
3700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // this based on whether the script source has a URL.
3710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        result = runScript(script, source.url().string().isNull());
3720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
3733eb2fab210a9ae636c55b30b23bb53b130d1efb6Steve Block#if PLATFORM(CHROMIUM)
3743eb2fab210a9ae636c55b30b23bb53b130d1efb6Steve Block    PlatformBridge::traceEventEnd("v8.run", node, "");
3753eb2fab210a9ae636c55b30b23bb53b130d1efb6Steve Block#endif
376643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
377a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    InspectorInstrumentation::didEvaluateScript(cookie);
378643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
3790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return result;
3800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
3810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Local<v8::Value> V8Proxy::runScript(v8::Handle<v8::Script> script, bool isInlineCode)
3830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
3840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (script.IsEmpty())
3850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return notHandledByInterceptor();
3860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
387643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    V8GCController::checkMemoryUsage();
3880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Compute the source string and prevent against infinite recursion.
3890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (m_recursion >= kMaxRecursionDepth) {
3900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        v8::Local<v8::String> code = v8ExternalString("throw RangeError('Recursion too deep')");
3910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // FIXME: Ideally, we should be able to re-use the origin of the
3920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // script passed to us as the argument instead of using an empty string
3930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // and 0 baseLine.
3946b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        script = compileScript(code, "", TextPosition0::minimumPosition());
3950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
3960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (handleOutOfMemory())
3980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ASSERT(script.IsEmpty());
3990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (script.IsEmpty())
4010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return notHandledByInterceptor();
4020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Save the previous value of the inlineCode flag and update the flag for
4040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // the duration of the script invocation.
4050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    bool previousInlineCode = inlineCode();
4060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    setInlineCode(isInlineCode);
4070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Run the script and keep track of the current recursion depth.
4090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Local<v8::Value> result;
4102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    v8::TryCatch tryCatch;
4112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    tryCatch.SetVerbose(true);
4120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
4130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // See comment in V8Proxy::callFunction.
4140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        m_frame->keepAlive();
4150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
416231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_recursion++;
4170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        result = script->Run();
4180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        m_recursion--;
4190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
4200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
421231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Release the storage mutex if applicable.
422e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    didLeaveScriptContext();
423231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
4240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (handleOutOfMemory())
4250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ASSERT(result.IsEmpty());
4260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Handle V8 internal error situation (Out-of-memory).
4282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (tryCatch.HasCaught()) {
4292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        ASSERT(result.IsEmpty());
4302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return notHandledByInterceptor();
4312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
4322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
4330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (result.IsEmpty())
4340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return notHandledByInterceptor();
4350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Restore inlineCode flag.
4370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    setInlineCode(previousInlineCode);
4380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (v8::V8::IsDead())
4400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        handleFatalErrorInV8();
4410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return result;
4430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
4440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[])
4460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
447643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    V8GCController::checkMemoryUsage();
4480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Local<v8::Value> result;
4490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
450231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (m_recursion >= kMaxRecursionDepth) {
451231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            v8::Local<v8::String> code = v8::String::New("throw new RangeError('Maximum call stack size exceeded.')");
452231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (code.IsEmpty())
453231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                return result;
454231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            v8::Local<v8::Script> script = v8::Script::Compile(code);
455231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (script.IsEmpty())
456231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                return result;
457231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            script->Run();
458231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return result;
459231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
460231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
4610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Evaluating the JavaScript could cause the frame to be deallocated,
4620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // so we start the keep alive timer here.
4630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Frame::keepAlive method adds the ref count of the frame and sets a
4640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // timer to decrease the ref count. It assumes that the current JavaScript
4650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // execution finishs before firing the timer.
4660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        m_frame->keepAlive();
4670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
468a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        InspectorInstrumentationCookie cookie;
469a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (InspectorInstrumentation::hasFrontends()) {
470a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            v8::ScriptOrigin origin = function->GetScriptOrigin();
471a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            String resourceName("undefined");
472a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            int lineNumber = 1;
473a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!origin.ResourceName().IsEmpty()) {
474a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                resourceName = toWebCoreString(origin.ResourceName());
475a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                lineNumber = function->GetScriptLineNumber() + 1;
476a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            }
477a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            cookie = InspectorInstrumentation::willCallFunction(m_frame, resourceName, lineNumber);
47821939df44de1705786c545cd1bf519d47250322dBen Murdoch        }
479dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
480231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_recursion++;
4810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        result = function->Call(receiver, argc, args);
482231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_recursion--;
483dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
484a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        InspectorInstrumentation::didCallFunction(cookie);
4850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
4860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
487231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Release the storage mutex if applicable.
488e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    didLeaveScriptContext();
489231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
4900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (v8::V8::IsDead())
4910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        handleFatalErrorInV8();
4920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return result;
4940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
4950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
496dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockv8::Local<v8::Value> V8Proxy::callFunctionWithoutFrame(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[])
497dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
498dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    V8GCController::checkMemoryUsage();
499dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    v8::Local<v8::Value> result = function->Call(receiver, argc, args);
500dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
501dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (v8::V8::IsDead())
502dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        handleFatalErrorInV8();
503dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
504dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return result;
505dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
506dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
5070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Local<v8::Value> V8Proxy::newInstance(v8::Handle<v8::Function> constructor, int argc, v8::Handle<v8::Value> args[])
5080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
5090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // No artificial limitations on the depth of recursion, see comment in
5100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // V8Proxy::callFunction.
5110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Local<v8::Value> result;
5120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
5130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // See comment in V8Proxy::callFunction.
5140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        m_frame->keepAlive();
5150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        result = constructor->NewInstance(argc, args);
5170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
5180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (v8::V8::IsDead())
5200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        handleFatalErrorInV8();
5210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return result;
5230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
5240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochDOMWindow* V8Proxy::retrieveWindow(v8::Handle<v8::Context> context)
5260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
5270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Handle<v8::Object> global = context->Global();
5280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(!global.IsEmpty());
5298a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    global = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), global);
5300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(!global.IsEmpty());
531d0825bca7fe65beaee391d30da42e937db621564Steve Block    return V8DOMWindow::toNative(global);
5320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
5330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochFrame* V8Proxy::retrieveFrame(v8::Handle<v8::Context> context)
5350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
536231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    DOMWindow* window = retrieveWindow(context);
537231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    Frame* frame = window->frame();
538231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (frame && frame->domWindow() == window)
539231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return frame;
540231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // We return 0 here because |context| is detached from the Frame.  If we
541231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // did return |frame| we could get in trouble because the frame could be
542231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // navigated to another security origin.
543231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return 0;
5440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
5450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochFrame* V8Proxy::retrieveFrameForEnteredContext()
5470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
5480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Handle<v8::Context> context = v8::Context::GetEntered();
5490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (context.IsEmpty())
5500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return 0;
5510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return retrieveFrame(context);
5520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
5530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochFrame* V8Proxy::retrieveFrameForCurrentContext()
5550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
5560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Handle<v8::Context> context = v8::Context::GetCurrent();
5570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (context.IsEmpty())
5580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return 0;
5590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return retrieveFrame(context);
5600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
5610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochFrame* V8Proxy::retrieveFrameForCallingContext()
5630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
5640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Handle<v8::Context> context = v8::Context::GetCalling();
5650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (context.IsEmpty())
5660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return 0;
5670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return retrieveFrame(context);
5680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
5690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochV8Proxy* V8Proxy::retrieve()
5710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
5720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    DOMWindow* window = retrieveWindow(currentContext());
5730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(window);
5740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return retrieve(window->frame());
5750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
5760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochV8Proxy* V8Proxy::retrieve(Frame* frame)
5780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
5790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!frame)
5800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return 0;
581dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return frame->script()->canExecuteScripts(NotAboutToExecuteScript) ? frame->script()->proxy() : 0;
5820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
5830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochV8Proxy* V8Proxy::retrieve(ScriptExecutionContext* context)
5850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
586d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (!context || !context->isDocument())
5870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return 0;
5880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return retrieve(static_cast<Document*>(context)->frame());
5890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
5900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid V8Proxy::disconnectFrame()
5920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
5930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
5940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
595e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid V8Proxy::didLeaveScriptContext()
596231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
597e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    Page* page = m_frame->page();
598e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (!page)
599e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        return;
600da73cf3d4a061de38a3910c675cd9b6f0a43f220Steve Block#if ENABLE(INDEXED_DATABASE)
601e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    // If we've just left a script context and indexed database has been
602e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    // instantiated, we must let its transaction coordinator know so it can terminate
603e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    // any not-yet-started transactions.
604bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    IDBPendingTransactionMonitor::abortPendingTransactions();
605da73cf3d4a061de38a3910c675cd9b6f0a43f220Steve Block#endif // ENABLE(INDEXED_DATABASE)
606231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // If we've just left a top level script context and local storage has been
607231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // instantiated, we must ensure that any storage locks have been freed.
608231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Per http://dev.w3.org/html5/spec/Overview.html#storage-mutex
609231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (m_recursion != 0)
610231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
611231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (page->group().hasLocalStorage())
612231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        page->group().localStorage()->unlock();
613231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
614231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
615231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid V8Proxy::resetIsolatedWorlds()
616231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
617231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    for (IsolatedWorldMap::iterator iter = m_isolatedWorlds.begin();
618231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block         iter != m_isolatedWorlds.end(); ++iter) {
619231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        iter->second->destroy();
620231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
621231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_isolatedWorlds.clear();
622231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
623231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
6240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid V8Proxy::clearForClose()
6250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
626231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    resetIsolatedWorlds();
627d0825bca7fe65beaee391d30da42e937db621564Steve Block    windowShell()->clearForClose();
6280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
6290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid V8Proxy::clearForNavigation()
6310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
632231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    resetIsolatedWorlds();
633d0825bca7fe65beaee391d30da42e937db621564Steve Block    windowShell()->clearForNavigation();
6340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
6350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid V8Proxy::setDOMException(int exceptionCode)
6370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
6380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (exceptionCode <= 0)
6390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
6400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ExceptionCodeDescription description;
6420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    getExceptionCodeDescription(exceptionCode, description);
6430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Handle<v8::Value> exception;
6450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    switch (description.type) {
6460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    case DOMExceptionType:
6475e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        exception = toV8(DOMCoreException::create(description));
6480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        break;
6490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    case RangeExceptionType:
6505e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        exception = toV8(RangeException::create(description));
6510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        break;
6520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    case EventExceptionType:
6535e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        exception = toV8(EventException::create(description));
6540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        break;
6550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    case XMLHttpRequestExceptionType:
6565e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        exception = toV8(XMLHttpRequestException::create(description));
6570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        break;
6580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if ENABLE(SVG)
6590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    case SVGExceptionType:
6605e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        exception = toV8(SVGException::create(description));
6610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        break;
6620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
6630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if ENABLE(XPATH)
6640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    case XPathExceptionType:
6655e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        exception = toV8(XPathException::create(description));
6660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        break;
6670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
66806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#if ENABLE(DATABASE)
66906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    case SQLExceptionType:
67006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        exception = toV8(SQLException::create(description));
67106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        break;
67206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#endif
673e14391e94c850b8bd03680c23b38978db68687a8John Reck#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM)
674e14391e94c850b8bd03680c23b38978db68687a8John Reck    case FileExceptionType:
675e14391e94c850b8bd03680c23b38978db68687a8John Reck        exception = toV8(FileException::create(description));
676e14391e94c850b8bd03680c23b38978db68687a8John Reck        break;
677e14391e94c850b8bd03680c23b38978db68687a8John Reck#endif
6784a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch#if ENABLE(INDEXED_DATABASE)
6794a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    case IDBDatabaseExceptionType:
6804a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        exception = toV8(IDBDatabaseException::create(description));
6814a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        break;
6824a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch#endif
683dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    default:
684dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT_NOT_REACHED();
6850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
6860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
687dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!exception.IsEmpty())
688dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        v8::ThrowException(exception);
6890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
6900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Handle<v8::Value> V8Proxy::throwError(ErrorType type, const char* message)
6920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
6930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    switch (type) {
6940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    case RangeError:
6950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return v8::ThrowException(v8::Exception::RangeError(v8String(message)));
6960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    case ReferenceError:
6970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return v8::ThrowException(v8::Exception::ReferenceError(v8String(message)));
6980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    case SyntaxError:
6990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return v8::ThrowException(v8::Exception::SyntaxError(v8String(message)));
7000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    case TypeError:
7010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return v8::ThrowException(v8::Exception::TypeError(v8String(message)));
7020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    case GeneralError:
7030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return v8::ThrowException(v8::Exception::Error(v8String(message)));
7040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    default:
7050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ASSERT_NOT_REACHED();
7060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return notHandledByInterceptor();
7070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
7080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
7090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
71006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenv8::Handle<v8::Value> V8Proxy::throwTypeError()
71106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
71206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return throwError(TypeError, "Type error");
71306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
71406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
71506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenv8::Handle<v8::Value> V8Proxy::throwSyntaxError()
71606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
71706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return throwError(SyntaxError, "Syntax error");
71806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
71906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
7200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Local<v8::Context> V8Proxy::context(Frame* frame)
7210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
7220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Local<v8::Context> context = V8Proxy::mainWorldContext(frame);
7230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (context.IsEmpty())
7240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return v8::Local<v8::Context>();
7250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
726d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (V8IsolatedContext* isolatedContext = V8IsolatedContext::getEntered()) {
727d0825bca7fe65beaee391d30da42e937db621564Steve Block        context = v8::Local<v8::Context>::New(isolatedContext->context());
7280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (frame != V8Proxy::retrieveFrame(context))
7290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return v8::Local<v8::Context>();
7300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
7310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return context;
7330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
7340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
735cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockv8::Local<v8::Context> V8Proxy::context()
736231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
737d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (V8IsolatedContext* isolatedContext = V8IsolatedContext::getEntered()) {
738d0825bca7fe65beaee391d30da42e937db621564Steve Block        RefPtr<SharedPersistent<v8::Context> > context = isolatedContext->sharedContext();
739cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        if (m_frame != V8Proxy::retrieveFrame(context->get()))
740cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            return v8::Local<v8::Context>();
741cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        return v8::Local<v8::Context>::New(context->get());
742231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
743643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return mainWorldContext();
744643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
745643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
746643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockv8::Local<v8::Context> V8Proxy::mainWorldContext()
747643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
748d0825bca7fe65beaee391d30da42e937db621564Steve Block    windowShell()->initContextIfNeeded();
749d0825bca7fe65beaee391d30da42e937db621564Steve Block    return v8::Local<v8::Context>::New(windowShell()->context());
750231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
751231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
7520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Local<v8::Context> V8Proxy::mainWorldContext(Frame* frame)
7530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
7540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    V8Proxy* proxy = retrieve(frame);
7550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!proxy)
7560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return v8::Local<v8::Context>();
7570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
758643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return proxy->mainWorldContext();
7590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
7600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Local<v8::Context> V8Proxy::currentContext()
7620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
7630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return v8::Context::GetCurrent();
7640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
7650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochv8::Handle<v8::Value> V8Proxy::checkNewLegal(const v8::Arguments& args)
7670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
7680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!AllowAllocation::m_current)
7690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return throwError(TypeError, "Illegal constructor");
7700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return args.This();
7720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
7730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
774231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid V8Proxy::registerExtensionWithV8(v8::Extension* extension)
775231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
7760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // If the extension exists in our list, it was already registered with V8.
777231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!registeredExtensionWithV8(extension))
778231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        v8::RegisterExtension(extension);
779231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
780231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
781231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool V8Proxy::registeredExtensionWithV8(v8::Extension* extension)
782231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
783231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    for (size_t i = 0; i < m_extensions.size(); ++i) {
784a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (m_extensions[i] == extension)
785231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return true;
7860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
7870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
788231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return false;
7890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
7900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
791bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid V8Proxy::registerExtension(v8::Extension* extension)
792bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
793bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    registerExtensionWithV8(extension);
794a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_extensions.append(extension);
7950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
7960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool V8Proxy::setContextDebugId(int debugId)
7980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
7990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(debugId > 0);
8000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::HandleScope scope;
801d0825bca7fe65beaee391d30da42e937db621564Steve Block    v8::Handle<v8::Context> context = windowShell()->context();
802d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (context.IsEmpty())
803d0825bca7fe65beaee391d30da42e937db621564Steve Block        return false;
804d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (!context->GetData()->IsUndefined())
8050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return false;
8060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
807d0825bca7fe65beaee391d30da42e937db621564Steve Block    v8::Context::Scope contextScope(context);
808643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
809643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    char buffer[32];
810643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    snprintf(buffer, sizeof(buffer), "page,%d", debugId);
811d0825bca7fe65beaee391d30da42e937db621564Steve Block    context->SetData(v8::String::New(buffer));
812643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
8130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return true;
8140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
8150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochint V8Proxy::contextDebugId(v8::Handle<v8::Context> context)
8170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
8180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::HandleScope scope;
819643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!context->GetData()->IsString())
8200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return -1;
821643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    v8::String::AsciiValue ascii(context->GetData());
822643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    char* comma = strnstr(*ascii, ",", ascii.length());
823643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!comma)
824643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return -1;
825643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return atoi(comma + 1);
8260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
8270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
828643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockv8::Local<v8::Context> toV8Context(ScriptExecutionContext* context, const WorldContextHandle& worldContext)
829cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
830cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (context->isDocument()) {
831cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        if (V8Proxy* proxy = V8Proxy::retrieve(context))
832643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return worldContext.adjustedContext(proxy);
833c5e067fc0c6f7b1a0e1ed53743857cac5ff48a81Steve Block#if ENABLE(WORKERS)
834cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    } else if (context->isWorkerContext()) {
835cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        if (WorkerContextExecutionProxy* proxy = static_cast<WorkerContext*>(context)->script()->proxy())
836cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            return proxy->context();
837c5e067fc0c6f7b1a0e1ed53743857cac5ff48a81Steve Block#endif
838cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    }
839cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return v8::Local<v8::Context>();
840cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
841cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
8420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}  // namespace WebCore
843