JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, NakedPtr<Exception>& returnedException) { VM& vm = exec->vm(); JSLockHolder lock(vm); auto scope = DECLARE_CATCH_SCOPE(vm); RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable()); RELEASE_ASSERT(!vm.isCollectorBusyOnCurrentThread()); CodeProfiling profile(source); ProgramExecutable* program = ProgramExecutable::create(exec, source); ASSERT(scope.exception() || program); if (!program) { returnedException = scope.exception(); scope.clearException(); return jsUndefined(); } if (!thisValue || thisValue.isUndefinedOrNull()) thisValue = exec->vmEntryGlobalObject(); JSObject* thisObj = jsCast<JSObject*>(thisValue.toThis(exec, NotStrictMode)); JSValue result = exec->interpreter()->execute(program, exec, thisObj); if (scope.exception()) { returnedException = scope.exception(); scope.clearException(); return jsUndefined(); } RELEASE_ASSERT(result); return result; }
bool NPJSObject::removeProperty(NPIdentifier propertyName) { IdentifierRep* identifierRep = static_cast<IdentifierRep*>(propertyName); ExecState* exec = m_objectMap->globalExec(); if (!exec) return false; VM& vm = exec->vm(); JSLockHolder lock(vm); auto scope = DECLARE_CATCH_SCOPE(vm); if (identifierRep->isString()) { Identifier identifier = identifierFromIdentifierRep(exec, identifierRep); if (!m_jsObject->hasProperty(exec, identifier)) { scope.clearException(); return false; } m_jsObject->methodTable()->deleteProperty(m_jsObject.get(), exec, identifier); } else { if (!m_jsObject->hasProperty(exec, identifierRep->number())) { scope.clearException(); return false; } m_jsObject->methodTable()->deletePropertyByIndex(m_jsObject.get(), exec, identifierRep->number()); } scope.clearException(); return true; }
// Evaluate some JavaScript code in the scope of this frame. JSValue DebuggerCallFrame::evaluateWithScopeExtension(const String& script, JSObject* scopeExtensionObject, NakedPtr<Exception>& exception) { ASSERT(isValid()); CallFrame* callFrame = m_validMachineFrame; if (!callFrame) return jsUndefined(); VM& vm = callFrame->vm(); JSLockHolder lock(vm); auto catchScope = DECLARE_CATCH_SCOPE(vm); CodeBlock* codeBlock = nullptr; if (isTailDeleted()) codeBlock = m_shadowChickenFrame.codeBlock; else codeBlock = callFrame->codeBlock(); if (!codeBlock) return jsUndefined(); DebuggerEvalEnabler evalEnabler(callFrame); EvalContextType evalContextType; if (isFunctionParseMode(codeBlock->unlinkedCodeBlock()->parseMode())) evalContextType = EvalContextType::FunctionEvalContext; else if (codeBlock->unlinkedCodeBlock()->codeType() == EvalCode) evalContextType = codeBlock->unlinkedCodeBlock()->evalContextType(); else evalContextType = EvalContextType::None; VariableEnvironment variablesUnderTDZ; JSScope::collectClosureVariablesUnderTDZ(scope()->jsScope(), variablesUnderTDZ); EvalExecutable* eval = DirectEvalExecutable::create(callFrame, makeSource(script), codeBlock->isStrictMode(), codeBlock->unlinkedCodeBlock()->derivedContextType(), codeBlock->unlinkedCodeBlock()->isArrowFunction(), evalContextType, &variablesUnderTDZ); if (UNLIKELY(catchScope.exception())) { exception = catchScope.exception(); catchScope.clearException(); return jsUndefined(); } JSGlobalObject* globalObject = callFrame->vmEntryGlobalObject(); if (scopeExtensionObject) { JSScope* ignoredPreviousScope = globalObject->globalScope(); globalObject->setGlobalScopeExtension(JSWithScope::create(vm, globalObject, scopeExtensionObject, ignoredPreviousScope)); } JSValue thisValue = this->thisValue(); JSValue result = vm.interpreter->execute(eval, callFrame, thisValue, scope()->jsScope()); if (UNLIKELY(catchScope.exception())) { exception = catchScope.exception(); catchScope.clearException(); } if (scopeExtensionObject) globalObject->clearGlobalScopeExtension(); ASSERT(result); return result; }
bool NPJSObject::construct(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) { ExecState* exec = m_objectMap->globalExec(); if (!exec) return false; VM& vm = exec->vm(); JSLockHolder lock(vm); auto scope = DECLARE_CATCH_SCOPE(vm); ConstructData constructData; ConstructType constructType = getConstructData(m_jsObject.get(), constructData); if (constructType == ConstructType::None) return false; // Convert the passed in arguments. MarkedArgumentBuffer argumentList; for (uint32_t i = 0; i < argumentCount; ++i) argumentList.append(m_objectMap->convertNPVariantToJSValue(exec, m_objectMap->globalObject(), arguments[i])); JSValue value = JSC::construct(exec, m_jsObject.get(), constructType, constructData, argumentList); // Convert and return the new object. m_objectMap->convertJSValueToNPVariant(exec, value, *result); scope.clearException(); return true; }
void JSGlobalObjectInspectorController::reportAPIException(ExecState* exec, Exception* exception) { VM& vm = exec->vm(); if (isTerminatedExecutionException(vm, exception)) return; auto scope = DECLARE_CATCH_SCOPE(vm); ErrorHandlingScope errorScope(vm); Ref<ScriptCallStack> callStack = createScriptCallStackFromException(exec, exception, ScriptCallStack::maxCallStackSizeToCapture); if (includesNativeCallStackWhenReportingExceptions()) appendAPIBacktrace(callStack.get()); // FIXME: <http://webkit.org/b/115087> Web Inspector: Should not evaluate JavaScript handling exceptions // If this is a custom exception object, call toString on it to try and get a nice string representation for the exception. String errorMessage = exception->value().toWTFString(exec); scope.clearException(); if (JSGlobalObjectConsoleClient::logToSystemConsole()) { if (callStack->size()) { const ScriptCallFrame& callFrame = callStack->at(0); ConsoleClient::printConsoleMessage(MessageSource::JS, MessageType::Log, MessageLevel::Error, errorMessage, callFrame.sourceURL(), callFrame.lineNumber(), callFrame.columnNumber()); } else ConsoleClient::printConsoleMessage(MessageSource::JS, MessageType::Log, MessageLevel::Error, errorMessage, String(), 0, 0); } m_consoleAgent->addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::JS, MessageType::Log, MessageLevel::Error, errorMessage, WTFMove(callStack))); }
static bool extractSourceInformationFromException(JSC::ExecState* exec, JSObject* exceptionObject, int* lineNumber, int* columnNumber, String* sourceURL) { VM& vm = exec->vm(); auto scope = DECLARE_CATCH_SCOPE(vm); // FIXME: <http://webkit.org/b/115087> Web Inspector: Should not need to evaluate JavaScript handling exceptions JSValue lineValue = exceptionObject->getDirect(vm, Identifier::fromString(exec, "line")); JSValue columnValue = exceptionObject->getDirect(vm, Identifier::fromString(exec, "column")); JSValue sourceURLValue = exceptionObject->getDirect(vm, Identifier::fromString(exec, "sourceURL")); bool result = false; if (lineValue && lineValue.isNumber() && sourceURLValue && sourceURLValue.isString()) { *lineNumber = int(lineValue.toNumber(exec)); *columnNumber = columnValue && columnValue.isNumber() ? int(columnValue.toNumber(exec)) : 0; *sourceURL = sourceURLValue.toWTFString(exec); result = true; } else if (ErrorInstance* error = jsDynamicCast<ErrorInstance*>(vm, exceptionObject)) { unsigned unsignedLine; unsigned unsignedColumn; result = getLineColumnAndSource(error->stackTrace(), unsignedLine, unsignedColumn, *sourceURL); *lineNumber = static_cast<int>(unsignedLine); *columnNumber = static_cast<int>(unsignedColumn); } if (sourceURL->isEmpty()) *sourceURL = "undefined"_s; scope.clearException(); return result; }
void ExceptionState::setException(v8::Handle<v8::Value> exception) { // FIXME: Assert that exception is not empty? if (exception.IsEmpty()) { clearException(); return; } m_exception.set(m_isolate, exception); }
static JSInternalPromise* rejectPromise(ExecState* exec, JSGlobalObject* globalObject) { VM& vm = exec->vm(); auto scope = DECLARE_CATCH_SCOPE(vm); ASSERT(scope.exception()); JSValue exception = scope.exception()->value(); scope.clearException(); JSInternalPromiseDeferred* deferred = JSInternalPromiseDeferred::create(exec, globalObject); deferred->reject(exec, exception); return deferred->promise(); }
static void pull(JNIEnv *env, const utf16string &server, jobject notify) { invokeNotify(env, notify, "PULL_STARTED", nullptr); utf16string url = server + "/_lowla/changes?seq=" + SysGetProperty("sequence", "0"); jbyteArray response = doHttp(env, url, nullptr); if (env->ExceptionCheck()) { jstring msg = clearException(env); invokeNotify(env, notify, "PULL_ENDED", nullptr); invokeNotify(env, notify, "ERROR", msg); return; } const char *json = (const char *)env->GetByteArrayElements(response, nullptr); CLowlaDBBson::ptr responseBson = lowladb_json_to_bson(json, env->GetArrayLength(response)); env->ReleaseByteArrayElements(response, (jbyte *)json, 0); if (responseBson) { CLowlaDBPullData::ptr pd = lowladb_parse_syncer_response(responseBson->data()); bool keepGoing = pullChunk(env, server, pd, notify); while (keepGoing && !env->ExceptionCheck()) { keepGoing = pullChunk(env, server, pd, notify); } if (env->ExceptionCheck()) { jstring msg = clearException(env); invokeNotify(env, notify, "PULL_ENDED", nullptr); invokeNotify(env, notify, "ERROR", msg); } else { invokeNotify(env, notify, "PULL_ENDED", nullptr); invokeNotify(env, notify, "OK", nullptr); } } else { invokeNotify(env, notify, "PULL_ENDED", nullptr); invokeNotify(env, notify, "ERROR", env->NewStringUTF("Unable to parse syncer response")); } }
bool Database::save(const char* filename) const { auto scope = DECLARE_CATCH_SCOPE(m_vm); auto out = FilePrintStream::open(filename, "w"); if (!out) return false; String data = toJSON(); if (UNLIKELY(scope.exception())) { scope.clearException(); return false; } out->print(data); return true; }
std::ostream& HTTPClientSession::sendRequest(HTTPRequest& request) { clearException(); _pResponseStream = 0; bool keepAlive = getKeepAlive(); // 检查是否需要重新建立链接 if ((connected() && !keepAlive) || mustReconnect()) { close(); _mustReconnect = false; } try { if (!connected()) reconnect(); if (!keepAlive) request.setKeepAlive(false); if (!request.has(HTTPRequest::HOST)) request.setHost(_host, _port); _reconnect = keepAlive; _expectResponseBody = request.getMethod() != HTTPRequest::HTTP_HEAD; if (request.getChunkedTransferEncoding()) { throw NotImplementedException("HTTPClientSession::sendRequest can't process Chunked"); } else if (request.hasContentLength()) { CountingOutputStream cs; request.write(cs); _pRequestStream.reset(new HTTPFixedLengthOutputStream(*this, request.getContentLength() + cs.chars())); request.write(*_pRequestStream); } else if ((request.getMethod() != HTTPRequest::HTTP_PUT && request.getMethod() != HTTPRequest::HTTP_POST) || request.has(HTTPRequest::UPGRADE)) { throw NotImplementedException("HTTPClientSession::sendRequest can't process hasUpGrade"); } else { throw NotImplementedException("HTTPClientSession::sendRequest can't process Normal"); } _lastRequest.update(); return *_pRequestStream; } catch (Exception&) { close(); throw; } }
void iteratorClose(ExecState* exec, IterationRecord iterationRecord) { VM& vm = exec->vm(); auto throwScope = DECLARE_THROW_SCOPE(vm); auto catchScope = DECLARE_CATCH_SCOPE(vm); Exception* exception = nullptr; if (UNLIKELY(catchScope.exception())) { exception = catchScope.exception(); catchScope.clearException(); } JSValue returnFunction = iterationRecord.iterator.get(exec, vm.propertyNames->returnKeyword); RETURN_IF_EXCEPTION(throwScope, void()); if (returnFunction.isUndefined()) { if (exception) throwException(exec, throwScope, exception); return; } CallData returnFunctionCallData; CallType returnFunctionCallType = getCallData(vm, returnFunction, returnFunctionCallData); if (returnFunctionCallType == CallType::None) { if (exception) throwException(exec, throwScope, exception); else throwTypeError(exec, throwScope); return; } MarkedArgumentBuffer returnFunctionArguments; ASSERT(!returnFunctionArguments.hasOverflowed()); JSValue innerResult = call(exec, returnFunction, returnFunctionCallType, returnFunctionCallData, iterationRecord.iterator, returnFunctionArguments); if (exception) { throwException(exec, throwScope, exception); return; } RETURN_IF_EXCEPTION(throwScope, void()); if (!innerResult.isObject()) { throwTypeError(exec, throwScope, "Iterator result interface is not an object."_s); return; } }
void printException() { ExecEnv *ee = getExecEnv(); Object *exception = ee->exception; if(exception != NULL) { MethodBlock *mb = lookupMethod(exception->class, SYMBOL(printStackTrace), SYMBOL(___V)); clearException(); executeMethod(exception, mb); /* If we're really low on memory we might have been able to throw * OutOfMemory, but then been unable to print any part of it! In * this case the VM just seems to stop... */ if(ee->exception) { jam_fprintf(stderr, "Exception occurred while printing exception (%s)...\n", CLASS_CB(ee->exception->class)->name); jam_fprintf(stderr, "Original exception was %s\n", CLASS_CB(exception->class)->name); }
EncodedJSValue JSC_HOST_CALL webAssemblyCompileFunc(ExecState* exec) { VM& vm = exec->vm(); auto catchScope = DECLARE_CATCH_SCOPE(vm); JSPromiseDeferred* promise = JSPromiseDeferred::create(exec, exec->lexicalGlobalObject()); RETURN_IF_EXCEPTION(catchScope, encodedJSValue()); // FIXME: Make this truly asynchronous: // https://bugs.webkit.org/show_bug.cgi?id=166016 JSValue module = WebAssemblyModuleConstructor::createModule(exec, exec->lexicalGlobalObject()->WebAssemblyModuleStructure()); if (Exception* exception = catchScope.exception()) { catchScope.clearException(); promise->reject(exec, exception); return JSValue::encode(promise->promise()); } promise->resolve(exec, module); return JSValue::encode(promise->promise()); }
static bool push(JNIEnv *env, const utf16string &server, jobject notify) { invokeNotify(env, notify, "PUSH_STARTED", nullptr); CLowlaDBPushData::ptr pd = lowladb_collect_push_data(); while (!pd->isComplete() && !env->ExceptionCheck()) { pushChunk(env, server, pd, notify); } // If there's a pending exception, we need to clear it before we can notify PUSH_ENDED if (env->ExceptionCheck()) { jstring msg = clearException(env); invokeNotify(env, notify, "PUSH_ENDED", nullptr); invokeNotify(env, notify, "ERROR", msg); return false; } else { invokeNotify(env, notify, "PUSH_ENDED", nullptr); return true; } }
bool NPJSObject::hasMethod(NPIdentifier methodName) { IdentifierRep* identifierRep = static_cast<IdentifierRep*>(methodName); if (!identifierRep->isString()) return false; ExecState* exec = m_objectMap->globalExec(); if (!exec) return false; VM& vm = exec->vm(); JSLockHolder lock(vm); auto scope = DECLARE_CATCH_SCOPE(vm); JSValue value = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep)); scope.clearException(); CallData callData; return getCallData(value, callData) != CallType::None; }
JSInternalPromise* JSModuleLoader::fetch(ExecState* exec, JSValue key, JSValue scriptFetcher) { if (Options::dumpModuleLoadingState()) dataLog("Loader [fetch] ", printableModuleKey(exec, key), "\n"); JSGlobalObject* globalObject = exec->lexicalGlobalObject(); VM& vm = globalObject->vm(); auto scope = DECLARE_CATCH_SCOPE(vm); if (globalObject->globalObjectMethodTable()->moduleLoaderFetch) return globalObject->globalObjectMethodTable()->moduleLoaderFetch(globalObject, exec, this, key, scriptFetcher); JSInternalPromiseDeferred* deferred = JSInternalPromiseDeferred::create(exec, globalObject); String moduleKey = key.toWTFString(exec); if (UNLIKELY(scope.exception())) { JSValue exception = scope.exception()->value(); scope.clearException(); deferred->reject(exec, exception); return deferred->promise(); } deferred->reject(exec, createError(exec, makeString("Could not open the module '", moduleKey, "'."))); return deferred->promise(); }
bool NPJSObject::hasProperty(NPIdentifier identifier) { IdentifierRep* identifierRep = static_cast<IdentifierRep*>(identifier); ExecState* exec = m_objectMap->globalExec(); if (!exec) return false; VM& vm = exec->vm(); JSLockHolder lock(vm); auto scope = DECLARE_CATCH_SCOPE(vm); bool result; if (identifierRep->isString()) result = m_jsObject->hasProperty(exec, identifierFromIdentifierRep(exec, identifierRep)); else result = m_jsObject->hasProperty(exec, identifierRep->number()); scope.clearException(); return result; }
bool NPJSObject::getProperty(NPIdentifier propertyName, NPVariant* result) { IdentifierRep* identifierRep = static_cast<IdentifierRep*>(propertyName); ExecState* exec = m_objectMap->globalExec(); if (!exec) return false; VM& vm = exec->vm(); JSLockHolder lock(vm); auto scope = DECLARE_CATCH_SCOPE(vm); JSValue jsResult; if (identifierRep->isString()) jsResult = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep)); else jsResult = m_jsObject->get(exec, identifierRep->number()); m_objectMap->convertJSValueToNPVariant(exec, jsResult, *result); scope.clearException(); return true; }
bool NPJSObject::setProperty(NPIdentifier propertyName, const NPVariant* value) { IdentifierRep* identifierRep = static_cast<IdentifierRep*>(propertyName); ExecState* exec = m_objectMap->globalExec(); if (!exec) return false; VM& vm = exec->vm(); JSLockHolder lock(vm); auto scope = DECLARE_CATCH_SCOPE(vm); JSValue jsValue = m_objectMap->convertNPVariantToJSValue(exec, m_objectMap->globalObject(), *value); if (identifierRep->isString()) { PutPropertySlot slot(m_jsObject.get()); m_jsObject->methodTable()->put(m_jsObject.get(), exec, identifierFromIdentifierRep(exec, identifierRep), jsValue, slot); } else m_jsObject->methodTable()->putByIndex(m_jsObject.get(), exec, identifierRep->number(), jsValue, false); scope.clearException(); return true; }
void makeDisposeCallback(Instance* instance) { se::Object* seObj = nullptr; auto iter = se::NativePtrToObjectMap::find(instance); if (iter != se::NativePtrToObjectMap::end()) { // Save se::Object pointer for being used in cleanup method. seObj = iter->second; // Unmap native and js object since native object was destroyed. // Otherwise, it may trigger 'assertion' in se::Object::setPrivateData // later since native obj is already released and the new native object // may be assigned with the same address. se::NativePtrToObjectMap::erase(iter); } else { return; } auto cleanup = [seObj]() { auto se = se::ScriptEngine::getInstance(); if (!se->isValid() || se->isInCleanup()) return; se::AutoHandleScope hs; se->clearException(); // The mapping of native object & se::Object was cleared in above code. // The private data (native object) may be a different object associated // with other se::Object. Therefore, don't clear the mapping again. seObj->clearPrivateData(false); seObj->unroot(); seObj->decRef(); }; if (!se::ScriptEngine::getInstance()->isGarbageCollecting()) { cleanup(); } else { CleanupTask::pushTaskToAutoReleasePool(cleanup); } }
JSInternalPromise* JSModuleLoader::importModule(ExecState* exec, JSString* moduleName, const SourceOrigin& referrer) { if (Options::dumpModuleLoadingState()) dataLog("Loader [import] ", printableModuleKey(exec, moduleName), "\n"); auto* globalObject = exec->lexicalGlobalObject(); VM& vm = globalObject->vm(); auto scope = DECLARE_CATCH_SCOPE(vm); if (globalObject->globalObjectMethodTable()->moduleLoaderImportModule) return globalObject->globalObjectMethodTable()->moduleLoaderImportModule(globalObject, exec, this, moduleName, referrer); auto* deferred = JSInternalPromiseDeferred::create(exec, globalObject); auto moduleNameString = moduleName->value(exec); if (UNLIKELY(scope.exception())) { JSValue exception = scope.exception()->value(); scope.clearException(); deferred->reject(exec, exception); return deferred->promise(); } deferred->reject(exec, createError(exec, makeString("Could not import the module '", moduleNameString, "'."))); return deferred->promise(); }
bool NPJSObject::invoke(ExecState* exec, JSGlobalObject* globalObject, JSValue function, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) { VM& vm = exec->vm(); auto scope = DECLARE_CATCH_SCOPE(vm); CallData callData; CallType callType = getCallData(function, callData); if (callType == CallType::None) return false; // Convert the passed in arguments. MarkedArgumentBuffer argumentList; for (uint32_t i = 0; i < argumentCount; ++i) argumentList.append(m_objectMap->convertNPVariantToJSValue(exec, globalObject, arguments[i])); JSValue value = JSC::call(exec, function, callType, callData, m_jsObject.get(), argumentList); // Convert and return the result of the function call. m_objectMap->convertJSValueToNPVariant(exec, value, *result); scope.clearException(); return true; }
void detachThread(Thread *thread) { Object *group, *excep; //ExecEnv *ee = thread->ee; //Object *jThread = ee->thread; Object *jThread = thread->thread; Object *vmthread = (Object*)INST_DATA(jThread)[vmthread_offset]; /* Get the thread's group */ group = (Object *)INST_DATA(jThread)[group_offset]; /* If there's an uncaught exception, call uncaughtException on the thread's exception handler, or the thread's group if this is unset */ if((excep = exceptionOccurred())) { FieldBlock *fb = findField(thread_class, SYMBOL(exceptionHandler), SYMBOL(sig_java_lang_Thread_UncaughtExceptionHandler)); Object *thread_handler = fb == NULL ? NULL : (Object *)INST_DATA(jThread)[fb->offset]; Object *handler = thread_handler == NULL ? group : thread_handler; MethodBlock *uncaught_exp = lookupMethod(handler->classobj, SYMBOL(uncaughtException), SYMBOL(_java_lang_Thread_java_lang_Throwable__V)); if(uncaught_exp) { clearException(); DummyFrame dummy; executeMethod(&dummy, handler, uncaught_exp, jThread, excep); } else printException(); } /* remove thread from thread group */ DummyFrame dummy; executeMethod(&dummy, group, (CLASS_CB(group->classobj))->method_table[rmveThrd_mtbl_idx], jThread); /* set VMThread ref in Thread object to null - operations after this point will result in an IllegalThreadStateException */ INST_DATA(jThread)[vmthread_offset] = 0; /* Remove thread from the ID map hash table */ deleteThreadFromHash(thread); /* Disable suspend to protect lock operation */ disableSuspend(thread); /* Grab global lock, and update thread structures protected by it (thread list, thread ID and number of daemon threads) */ pthread_mutex_lock(&lock); /* remove from thread list... */ if((thread->prev->next = thread->next)) thread->next->prev = thread->prev; /* One less live thread */ threads_count--; /* Recycle the thread's thread ID */ freeThreadID(thread->id); /* Handle daemon thread status */ if(!INST_DATA(jThread)[daemon_offset]) non_daemon_thrds--; pthread_mutex_unlock(&lock); /* notify any threads waiting on VMThread object - these are joining this thread */ objectLock(vmthread); objectNotifyAll(vmthread); objectUnlock(vmthread); /* It is safe to free the thread's ExecEnv and stack now as these are only used within the thread. It is _not_ safe to free the native thread structure as another thread may be concurrently accessing it. However, they must have a reference to the VMThread -- therefore, it is safe to free during GC when the VMThread is determined to be no longer reachable. */ // sysFree(ee->stack); //sysFree(ee); /* If no more daemon threads notify the main thread (which may be waiting to exit VM). Note, this is not protected by lock, but main thread checks again */ if(non_daemon_thrds == 0) { /* No need to bother with disabling suspension * around lock, as we're no longer on thread list */ pthread_mutex_lock(&exit_lock); pthread_cond_signal(&exit_cv); pthread_mutex_unlock(&exit_lock); } TRACE("Thread 0x%x id: %d detached from VM\n", thread, thread->id); }
ScriptPromise ExceptionState::reject(ScriptState* scriptState) { ScriptPromise promise = ScriptPromise::reject(scriptState, m_exception.newLocal(scriptState->isolate())); clearException(); return promise; }
JNIEnv* MethodResultJni::jniInit(JNIEnv *env) { RAWTRACE3("%s - env: 0x%.8x, functions: 0x%.8x", __FUNCTION__, env, env->functions); if(env && !s_methodResultClass) { String exceptionMessage; s_methodResultClass = getJNIClass(RHODES_JAVA_CLASS_METHODRESULT); if(!s_methodResultClass) { RAWLOG_ERROR1("Failed to find java class: %s", METHOD_RESULT_CLASS); s_methodResultClass = 0; return NULL; } RAWTRACE("<init>"); s_midMethodResult = env->GetMethodID(s_methodResultClass, "<init>", "(Z)V"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get %s constructor: $s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("getJson"); s_midGetJson = env->GetMethodID(s_methodResultClass, "getJson", "()Ljava/lang/String;"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get method %s.getJson: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("getResultType"); s_midGetResultType = env->GetMethodID(s_methodResultClass, "getResultType", "()I"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get method %s.getResultType: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("reset"); s_midReset = env->GetMethodID(s_methodResultClass, "reset", "()V"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get method %s.reset: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("mBooleanResult"); s_fidBoolean = env->GetFieldID(s_methodResultClass, "mBooleanResult", "Z"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get field %s.mBooleanResult: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("mIntegerResult"); s_fidInteger = env->GetFieldID(s_methodResultClass, "mIntegerResult", "I"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get field %s.mIntegerResult: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("mDoubleResult"); s_fidDouble = env->GetFieldID(s_methodResultClass, "mDoubleResult", "D"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get fiekd %s.mDoubleResult: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("mStrResult"); s_fidString = env->GetFieldID(s_methodResultClass, "mStrResult", "Ljava/lang/String;"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get field %s.mStrResult: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("mListResult"); s_fidList = env->GetFieldID(s_methodResultClass, "mListResult", "Ljava/util/List;"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get field %s.mListResult: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("mMapResult"); s_fidMap = env->GetFieldID(s_methodResultClass, "mMapResult", "Ljava/util/Map;"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get field %s.mMapResult: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("mStrCallback"); s_fidStrCallback = env->GetFieldID(s_methodResultClass, "mStrCallback", "Ljava/lang/String;"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get field %s.mStrCallback: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("mStrCallbackData"); s_fidStrCallbackData = env->GetFieldID(s_methodResultClass, "mStrCallbackData", "Ljava/lang/String;"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get %s.mStrCallbackData field: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("mResultParamName"); s_fidResultParamName = env->GetFieldID(s_methodResultClass, "mResultParamName", "Ljava/lang/String;"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get %s.mResultParamName field: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("mRubyProcCallback"); s_fidRubyProcCallback = env->GetFieldID(s_methodResultClass, "mRubyProcCallback", "J"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get field %s.mRubyProcCallback: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("mTabId"); s_fidTabId = env->GetFieldID(s_methodResultClass, "mTabId", "I"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get field %s.mTabId: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("mObjectClassPath"); s_fidObjectClassPath = env->GetFieldID(s_methodResultClass, "mObjectClassPath", "Ljava/lang/String;"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get field %s.mObjectClassPath: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE("mRubyObjectClass"); s_fidRubyObjectClass = env->GetFieldID(s_methodResultClass, "mRubyObjectClass", "J"); if(env->ExceptionCheck() == JNI_TRUE) { RAWLOG_ERROR2("Failed to get field %s.mRubyObjectClass: %s", METHOD_RESULT_CLASS, clearException(env).c_str()); s_methodResultClass = 0; return NULL; } RAWTRACE(__FUNCTION__); } return env; }
JSObject* JSLazyEventListener::initializeJSFunction(ScriptExecutionContext* executionContext) const { ASSERT(is<Document>(executionContext)); if (!executionContext) return nullptr; ASSERT(!m_code.isNull()); ASSERT(!m_eventParameterName.isNull()); if (m_code.isNull() || m_eventParameterName.isNull()) return nullptr; Document& document = downcast<Document>(*executionContext); if (!document.frame()) return nullptr; if (!document.contentSecurityPolicy()->allowInlineEventHandlers(m_sourceURL, m_sourcePosition.m_line)) return nullptr; ScriptController& script = document.frame()->script(); if (!script.canExecuteScripts(AboutToExecuteScript) || script.isPaused()) return nullptr; JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(executionContext, isolatedWorld()); if (!globalObject) return nullptr; VM& vm = globalObject->vm(); JSLockHolder lock(vm); auto scope = DECLARE_CATCH_SCOPE(vm); ExecState* exec = globalObject->globalExec(); MarkedArgumentBuffer args; args.append(jsNontrivialString(exec, m_eventParameterName)); args.append(jsStringWithCache(exec, m_code)); // We want all errors to refer back to the line on which our attribute was // declared, regardless of any newlines in our JavaScript source text. int overrideLineNumber = m_sourcePosition.m_line.oneBasedInt(); JSObject* jsFunction = constructFunctionSkippingEvalEnabledCheck( exec, exec->lexicalGlobalObject(), args, Identifier::fromString(exec, m_functionName), m_sourceURL, m_sourcePosition, overrideLineNumber); if (UNLIKELY(scope.exception())) { reportCurrentException(exec); scope.clearException(); return nullptr; } JSFunction* listenerAsFunction = jsCast<JSFunction*>(jsFunction); if (m_originalNode) { if (!wrapper()) { // Ensure that 'node' has a JavaScript wrapper to mark the event listener we're creating. // FIXME: Should pass the global object associated with the node setWrapper(vm, asObject(toJS(exec, globalObject, *m_originalNode))); } // Add the event's home element to the scope // (and the document, and the form - see JSHTMLElement::eventHandlerScope) listenerAsFunction->setScope(vm, jsCast<JSNode*>(wrapper())->pushEventHandlerScope(exec, listenerAsFunction->scope())); } return jsFunction; }
JSValue JSWebKitSubtleCrypto::unwrapKey(ExecState& state) { VM& vm = state.vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (state.argumentCount() < 5) return throwException(&state, scope, createNotEnoughArgumentsError(&state)); auto keyFormat = cryptoKeyFormatFromJSValue(state, scope, state.uncheckedArgument(0)); RETURN_IF_EXCEPTION(scope, { }); auto wrappedKeyData = cryptoOperationDataFromJSValue(state, scope, state.uncheckedArgument(1)); RETURN_IF_EXCEPTION(scope, { }); RefPtr<CryptoKey> unwrappingKey = JSCryptoKey::toWrapped(vm, state.uncheckedArgument(2)); if (!unwrappingKey) return throwTypeError(&state, scope); if (!unwrappingKey->allows(CryptoKeyUsageUnwrapKey)) { wrapped().document()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, ASCIILiteral("Key usages do not include 'unwrapKey'")); throwNotSupportedError(state, scope); return jsUndefined(); } auto unwrapAlgorithm = createAlgorithmFromJSValue(state, scope, state.uncheckedArgument(3)); RETURN_IF_EXCEPTION(scope, { }); auto unwrapAlgorithmParameters = JSCryptoAlgorithmDictionary::createParametersForDecrypt(state, scope, unwrapAlgorithm->identifier(), state.uncheckedArgument(3)); RETURN_IF_EXCEPTION(scope, { }); RefPtr<CryptoAlgorithm> unwrappedKeyAlgorithm; RefPtr<CryptoAlgorithmParametersDeprecated> unwrappedKeyAlgorithmParameters; if (!state.uncheckedArgument(4).isNull()) { unwrappedKeyAlgorithm = createAlgorithmFromJSValue(state, scope, state.uncheckedArgument(4)); RETURN_IF_EXCEPTION(scope, { }); unwrappedKeyAlgorithmParameters = JSCryptoAlgorithmDictionary::createParametersForImportKey(state, scope, unwrappedKeyAlgorithm->identifier(), state.uncheckedArgument(4)); RETURN_IF_EXCEPTION(scope, { }); } bool extractable = state.argument(5).toBoolean(&state); RETURN_IF_EXCEPTION(scope, { }); CryptoKeyUsageBitmap keyUsages = 0; if (state.argumentCount() >= 7) { keyUsages = cryptoKeyUsagesFromJSValue(state, scope, state.uncheckedArgument(6)); RETURN_IF_EXCEPTION(scope, { }); } RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow()); auto promise = wrapper->promise(); Strong<JSDOMGlobalObject> domGlobalObject(state.vm(), globalObject()); auto decryptSuccessCallback = [domGlobalObject, keyFormat, unwrappedKeyAlgorithm, unwrappedKeyAlgorithmParameters, extractable, keyUsages, wrapper](const Vector<uint8_t>& result) mutable { auto importSuccessCallback = [wrapper](CryptoKey& key) mutable { wrapper->resolve<IDLInterface<CryptoKey>>(key); }; auto importFailureCallback = [wrapper]() mutable { wrapper->reject(); // FIXME: This should reject with an Exception. }; VM& vm = domGlobalObject->vm(); auto scope = DECLARE_CATCH_SCOPE(vm); ExecState& state = *domGlobalObject->globalExec(); WebCore::importKey(state, keyFormat, std::make_pair(result.data(), result.size()), unwrappedKeyAlgorithm, unwrappedKeyAlgorithmParameters, extractable, keyUsages, WTFMove(importSuccessCallback), WTFMove(importFailureCallback)); if (UNLIKELY(scope.exception())) { // FIXME: Report exception details to console, and possibly to calling script once there is a standardized way to pass errors to WebCrypto promise reject functions. scope.clearException(); wrapper->reject(); // FIXME: This should reject with an Exception. } }; auto decryptFailureCallback = [wrapper]() mutable { wrapper->reject(); // FIXME: This should reject with an Exception. }; auto result = unwrapAlgorithm->decryptForUnwrapKey(*unwrapAlgorithmParameters, *unwrappingKey, wrappedKeyData, WTFMove(decryptSuccessCallback), WTFMove(decryptFailureCallback)); if (result.hasException()) { propagateException(state, scope, result.releaseException()); return { }; } return promise; }
void JSEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event) { ASSERT(scriptExecutionContext); if (!scriptExecutionContext || scriptExecutionContext->isJSExecutionForbidden()) return; VM& vm = scriptExecutionContext->vm(); JSLockHolder lock(vm); auto scope = DECLARE_CATCH_SCOPE(vm); // See https://dom.spec.whatwg.org/#dispatching-events spec on calling handleEvent. // "If this throws an exception, report the exception." It should not propagate the // exception. JSObject* jsFunction = this->jsFunction(scriptExecutionContext); if (!jsFunction) return; JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(scriptExecutionContext, *m_isolatedWorld); if (!globalObject) return; if (scriptExecutionContext->isDocument()) { JSDOMWindow* window = jsCast<JSDOMWindow*>(globalObject); if (!window->wrapped().isCurrentlyDisplayedInFrame()) return; if (wasCreatedFromMarkup() && !scriptExecutionContext->contentSecurityPolicy()->allowInlineEventHandlers(sourceURL(), sourcePosition().m_line)) return; // FIXME: Is this check needed for other contexts? ScriptController& script = window->wrapped().frame()->script(); if (!script.canExecuteScripts(AboutToExecuteScript) || script.isPaused()) return; } ExecState* exec = globalObject->globalExec(); JSValue handleEventFunction = jsFunction; CallData callData; CallType callType = getCallData(handleEventFunction, callData); // If jsFunction is not actually a function, see if it implements the EventListener interface and use that if (callType == CallType::None) { handleEventFunction = jsFunction->get(exec, Identifier::fromString(exec, "handleEvent")); if (UNLIKELY(scope.exception())) { auto* exception = scope.exception(); scope.clearException(); event->target()->uncaughtExceptionInEventHandler(); reportException(exec, exception); return; } callType = getCallData(handleEventFunction, callData); } if (callType != CallType::None) { Ref<JSEventListener> protectedThis(*this); MarkedArgumentBuffer args; args.append(toJS(exec, globalObject, event)); Event* savedEvent = globalObject->currentEvent(); globalObject->setCurrentEvent(event); VMEntryScope entryScope(vm, vm.entryScope ? vm.entryScope->globalObject() : globalObject); InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionCall(scriptExecutionContext, callType, callData); JSValue thisValue = handleEventFunction == jsFunction ? toJS(exec, globalObject, event->currentTarget()) : jsFunction; NakedPtr<JSC::Exception> exception; JSValue retval = scriptExecutionContext->isDocument() ? JSMainThreadExecState::profiledCall(exec, JSC::ProfilingReason::Other, handleEventFunction, callType, callData, thisValue, args, exception) : JSC::profiledCall(exec, JSC::ProfilingReason::Other, handleEventFunction, callType, callData, thisValue, args, exception); InspectorInstrumentation::didCallFunction(cookie, scriptExecutionContext); globalObject->setCurrentEvent(savedEvent); if (is<WorkerGlobalScope>(*scriptExecutionContext)) { auto scriptController = downcast<WorkerGlobalScope>(*scriptExecutionContext).script(); bool terminatorCausedException = (scope.exception() && isTerminatedExecutionException(scope.exception())); if (terminatorCausedException || scriptController->isTerminatingExecution()) scriptController->forbidExecution(); } if (exception) { event->target()->uncaughtExceptionInEventHandler(); reportException(exec, exception); } else { if (!retval.isUndefinedOrNull() && is<BeforeUnloadEvent>(*event)) downcast<BeforeUnloadEvent>(*event).setReturnValue(retval.toWTFString(exec)); if (m_isAttribute) { if (retval.isFalse()) event->preventDefault(); } } } }