PassRefPtr<ScriptProfile> ScriptProfiler::stop(ScriptState* state, const String& title) { v8::HandleScope hs; const v8::CpuProfile* profile = state ? v8::CpuProfiler::StopProfiling(deprecatedV8String(title), state->context()->GetSecurityToken()) : v8::CpuProfiler::StopProfiling(deprecatedV8String(title)); return profile ? ScriptProfile::create(profile) : 0; }
ScriptValue WorkerScriptController::evaluate(const String& script, const String& fileName, const TextPosition& scriptStartPosition, WorkerContextExecutionState* state) { V8GCController::checkMemoryUsage(); v8::HandleScope handleScope; if (!initializeContextIfNeeded()) return ScriptValue(); if (!m_disableEvalPending.isEmpty()) { m_context->AllowCodeGenerationFromStrings(false); m_context->SetErrorMessageForCodeGenerationFromStrings(deprecatedV8String(m_disableEvalPending)); m_disableEvalPending = String(); } v8::Context::Scope scope(m_context.get()); v8::TryCatch block; v8::Handle<v8::String> scriptString = deprecatedV8String(script); v8::Handle<v8::Script> compiledScript = ScriptSourceCode::compileScript(scriptString, fileName, scriptStartPosition); v8::Local<v8::Value> result = ScriptRunner::runCompiledScript(compiledScript, m_workerContext); if (!block.CanContinue()) { m_workerContext->script()->forbidExecution(); return ScriptValue(); } if (block.HasCaught()) { v8::Local<v8::Message> message = block.Message(); state->hadException = true; state->errorMessage = toWebCoreString(message->Get()); state->lineNumber = message->GetLineNumber(); state->sourceURL = toWebCoreString(message->GetScriptResourceName()); if (m_workerContext->sanitizeScriptError(state->errorMessage, state->lineNumber, state->sourceURL)) state->exception = throwError(v8GeneralError, state->errorMessage.utf8().data()); else state->exception = ScriptValue(block.Exception()); block.Reset(); } else state->hadException = false; if (result.IsEmpty() || result->IsUndefined()) return ScriptValue(); return ScriptValue(result); }
bool V8RTCErrorCallback::handleEvent(const String& errorInformation) { if (!canInvokeCallback()) return true; v8::HandleScope handleScope; v8::Handle<v8::Context> v8Context = toV8Context(scriptExecutionContext(), m_worldContext); if (v8Context.IsEmpty()) return true; v8::Context::Scope scope(v8Context); v8::Handle<v8::Value> errorInformationHandle = deprecatedV8String(errorInformation); if (errorInformationHandle.IsEmpty()) { if (!isScriptControllerTerminating()) CRASH(); return true; } v8::Handle<v8::Value> argv[] = { errorInformationHandle }; bool callbackReturnValue = false; return !invokeCallback(m_callback.get(), 1, argv, callbackReturnValue, scriptExecutionContext()); }
PassRefPtr<ScriptProfile> ScriptProfiler::stop(ScriptState* state, const String& title) { v8::HandleScope hs; const v8::CpuProfile* profile = state ? v8::CpuProfiler::StopProfiling(deprecatedV8String(title), state->context()->GetSecurityToken()) : v8::CpuProfiler::StopProfiling(deprecatedV8String(title)); double idleTime = 0.0; ProfileNameIdleTimeMap* profileNameIdleTimeMap = ScriptProfiler::currentProfileNameIdleTimeMap(); ProfileNameIdleTimeMap::iterator profileIdleTime = profileNameIdleTimeMap->find(title); if (profileIdleTime != profileNameIdleTimeMap->end()) { idleTime = profileIdleTime->value * 1000.0; profileNameIdleTimeMap->remove(profileIdleTime); } return profile ? ScriptProfile::create(profile, idleTime) : 0; }
static bool get(v8::Handle<v8::Value>& object, const String& keyPathElement, v8::Handle<v8::Value>& result) { if (object->IsString() && keyPathElement == "length") { int32_t length = v8::Handle<v8::String>::Cast(object)->Length(); result = v8::Number::New(length); return true; } return object->IsObject() && getValueFrom(deprecatedV8String(keyPathElement), result); }
v8::Handle<v8::Script> ScriptSourceCode::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition& scriptStartPosition, v8::ScriptData* scriptData) { v8::Handle<v8::String> name = deprecatedV8String(fileName); v8::Handle<v8::Integer> line = deprecatedV8Integer(scriptStartPosition.m_line.zeroBasedInt()); v8::Handle<v8::Integer> column = deprecatedV8Integer(scriptStartPosition.m_column.zeroBasedInt()); v8::ScriptOrigin origin(name, line, column); v8::Handle<v8::Script> script = v8::Script::Compile(code, &origin, scriptData); return script; }
PassRefPtr<ScriptHeapSnapshot> ScriptProfiler::takeHeapSnapshot(const String& title, HeapSnapshotProgress* control) { v8::HandleScope hs; ASSERT(control); ActivityControlAdapter adapter(control); GlobalObjectNameResolver resolver; const v8::HeapSnapshot* snapshot = v8::HeapProfiler::TakeSnapshot(deprecatedV8String(title), v8::HeapSnapshot::kFull, &adapter, &resolver); return snapshot ? ScriptHeapSnapshot::create(snapshot) : 0; }
void V8DOMWindowShell::namedItemAdded(HTMLDocument* document, const AtomicString& name) { ASSERT(m_world->isMainWorld()); if (m_context.isEmpty()) return; v8::HandleScope handleScope; v8::Context::Scope contextScope(m_context.get()); ASSERT(!m_document.isEmpty()); checkDocumentWrapper(m_document.get(), document); m_document->SetAccessor(deprecatedV8String(name), getter); }
void V8DOMWindowShell::namedItemRemoved(HTMLDocument* document, const AtomicString& name) { ASSERT(m_world->isMainWorld()); if (m_context.isEmpty()) return; if (document->hasNamedItem(name.impl()) || document->hasExtraNamedItem(name.impl())) return; v8::HandleScope handleScope; v8::Context::Scope contextScope(m_context.get()); ASSERT(!m_document.isEmpty()); checkDocumentWrapper(m_document.get(), document); m_document->Delete(deprecatedV8String(name)); }
v8::Local<v8::Value> ScriptController::compileAndRunScript(const ScriptSourceCode& source) { ASSERT(v8::Context::InContext()); V8GCController::checkMemoryUsage(); InspectorInstrumentationCookie cookie = InspectorInstrumentation::willEvaluateScript(m_frame, source.url().isNull() ? String() : source.url().string(), source.startLine()); v8::Local<v8::Value> result; { // Isolate exceptions that occur when compiling and executing // the code. These exceptions should not interfere with // javascript code we might evaluate from C++ when returning // from here. v8::TryCatch tryCatch; tryCatch.SetVerbose(true); // Compile the script. v8::Handle<v8::String> code = deprecatedV8String(source.source()); #if PLATFORM(CHROMIUM) TRACE_EVENT_BEGIN0("v8", "v8.compile"); #endif OwnPtr<v8::ScriptData> scriptData = ScriptSourceCode::precompileScript(code, source.cachedScript()); // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at // 1, whereas v8 starts at 0. v8::Handle<v8::Script> script = ScriptSourceCode::compileScript(code, source.url(), source.startPosition(), scriptData.get()); #if PLATFORM(CHROMIUM) TRACE_EVENT_END0("v8", "v8.compile"); TRACE_EVENT0("v8", "v8.run"); #endif // Keep Frame (and therefore ScriptController) alive. RefPtr<Frame> protect(m_frame); result = ScriptRunner::runCompiledScript(script, m_frame->document()); ASSERT(!tryCatch.HasCaught() || result.IsEmpty()); } InspectorInstrumentation::didEvaluateScript(cookie); return result; }
static bool set(v8::Handle<v8::Value>& object, const String& keyPathElement, const v8::Handle<v8::Value>& v8Value) { return canSet(object, keyPathElement) && setValue(object, deprecatedV8String(keyPathElement), v8Value); }
// Create a new environment and setup the global object. // // The global object corresponds to a DOMWindow instance. However, to // allow properties of the JS DOMWindow instance to be shadowed, we // use a shadow object as the global object and use the JS DOMWindow // instance as the prototype for that shadow object. The JS DOMWindow // instance is undetectable from JavaScript code because the __proto__ // accessors skip that object. // // The shadow object and the DOMWindow instance are seen as one object // from JavaScript. The JavaScript object that corresponds to a // DOMWindow instance is the shadow object. When mapping a DOMWindow // instance to a V8 object, we return the shadow object. // // To implement split-window, see // 1) https://bugs.webkit.org/show_bug.cgi?id=17249 // 2) https://wiki.mozilla.org/Gecko:SplitWindow // 3) https://bugzilla.mozilla.org/show_bug.cgi?id=296639 // we need to split the shadow object further into two objects: // an outer window and an inner window. The inner window is the hidden // prototype of the outer window. The inner window is the default // global object of the context. A variable declared in the global // scope is a property of the inner window. // // The outer window sticks to a Frame, it is exposed to JavaScript // via window.window, window.self, window.parent, etc. The outer window // has a security token which is the domain. The outer window cannot // have its own properties. window.foo = 'x' is delegated to the // inner window. // // When a frame navigates to a new page, the inner window is cut off // the outer window, and the outer window identify is preserved for // the frame. However, a new inner window is created for the new page. // If there are JS code holds a closure to the old inner window, // it won't be able to reach the outer window via its global object. bool V8DOMWindowShell::initializeIfNeeded() { if (!m_context.isEmpty()) return true; v8::HandleScope handleScope; V8Initializer::initializeMainThreadIfNeeded(m_isolate); createContext(); if (m_context.isEmpty()) return false; bool isMainWorld = m_world->isMainWorld(); v8::Local<v8::Context> context = v8::Local<v8::Context>::New(m_context.get()); v8::Context::Scope contextScope(context); m_world->setIsolatedWorldField(m_context.get()); if (m_global.isEmpty()) { m_global.set(context->Global()); if (m_global.isEmpty()) { disposeContext(); return false; } } if (!isMainWorld) { V8DOMWindowShell* mainWindow = m_frame->script()->existingWindowShell(mainThreadNormalWorld()); if (mainWindow && !mainWindow->context().IsEmpty()) setInjectedScriptContextDebugId(m_context.get(), m_frame->script()->contextDebugId(mainWindow->context())); } m_perContextData = V8PerContextData::create(m_context.get()); if (!m_perContextData->init()) { disposeContext(); return false; } if (!installDOMWindow()) { disposeContext(); return false; } if (isMainWorld) { updateDocument(); setSecurityToken(); if (m_frame->document()) { ContentSecurityPolicy* csp = m_frame->document()->contentSecurityPolicy(); context->AllowCodeGenerationFromStrings(csp->allowEval(0, ContentSecurityPolicy::SuppressReport)); context->SetErrorMessageForCodeGenerationFromStrings(deprecatedV8String(csp->evalDisabledErrorMessage())); } } else { // Using the default security token means that the canAccess is always // called, which is slow. // FIXME: Use tokens where possible. This will mean keeping track of all // created contexts so that they can all be updated when the // document domain // changes. m_context->UseDefaultSecurityToken(); SecurityOrigin* origin = m_world->isolatedWorldSecurityOrigin(); if (origin && InspectorInstrumentation::hasFrontends()) { ScriptState* scriptState = ScriptState::forContext(v8::Local<v8::Context>::New(m_context.get())); InspectorInstrumentation::didCreateIsolatedContext(m_frame, scriptState, origin); } } m_frame->loader()->client()->didCreateScriptContext(m_context.get(), m_world->extensionGroup(), m_world->worldId()); return true; }