EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec) { JSValue thisValue = exec->thisValue(); if (thisValue.inherits(JSFunction::info())) { JSFunction* function = jsCast<JSFunction*>(thisValue); if (function->isHostOrBuiltinFunction()) { String name; if (JSBoundFunction* boundFunction = jsDynamicCast<JSBoundFunction*>(function)) name = boundFunction->toStringName(exec); else name = function->name(exec); return JSValue::encode(jsMakeNontrivialString(exec, "function ", name, "() {\n [native code]\n}")); } FunctionExecutable* executable = function->jsExecutable(); String functionHeader = executable->isArrowFunction() ? "" : "function "; StringView source = executable->source().provider()->getRange( executable->parametersStartOffset(), executable->parametersStartOffset() + executable->source().length()); return JSValue::encode(jsMakeNontrivialString(exec, functionHeader, function->name(exec), source)); } if (thisValue.inherits(InternalFunction::info())) { InternalFunction* function = asInternalFunction(thisValue); return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "() {\n [native code]\n}")); } return throwVMTypeError(exec); }
EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSValue thisValue = exec->thisValue(); if (thisValue.inherits(JSFunction::info())) { JSFunction* function = jsCast<JSFunction*>(thisValue); if (function->isHostOrBuiltinFunction()) { scope.release(); return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(vm), "() {\n [native code]\n}")); } FunctionExecutable* executable = function->jsExecutable(); if (executable->isClass()) { StringView classSource = executable->classSource().view(); return JSValue::encode(jsString(exec, classSource.toStringWithoutCopying())); } if (thisValue.inherits(JSAsyncFunction::info())) { String functionHeader = executable->isArrowFunction() ? "async " : "async function "; StringView source = executable->source().provider()->getRange( executable->parametersStartOffset(), executable->parametersStartOffset() + executable->source().length()); return JSValue::encode(jsMakeNontrivialString(exec, functionHeader, function->name(vm), source)); } String functionHeader = executable->isArrowFunction() ? "" : "function "; StringView source = executable->source().provider()->getRange( executable->parametersStartOffset(), executable->parametersStartOffset() + executable->source().length()); scope.release(); return JSValue::encode(jsMakeNontrivialString(exec, functionHeader, function->name(vm), source)); } if (thisValue.inherits(InternalFunction::info())) { InternalFunction* function = asInternalFunction(thisValue); scope.release(); return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(), "() {\n [native code]\n}")); } if (thisValue.isObject()) { JSObject* object = asObject(thisValue); if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) { CallData callData; if (object->methodTable(vm)->getCallData(object, callData) != CallType::None) { if (auto* classInfo = object->classInfo()) { scope.release(); return JSValue::encode(jsMakeNontrivialString(exec, "function ", classInfo->className, "() {\n [native code]\n}")); } } } } return throwVMTypeError(exec, scope); }
JSValue JSInjectedScriptHost::functionDetails(ExecState* exec) { if (exec->argumentCount() < 1) return jsUndefined(); JSValue value = exec->argument(0); if (!value.asCell()->inherits(&JSFunction::s_info)) return jsUndefined(); JSFunction* function = jsCast<JSFunction*>(value); const SourceCode* sourceCode = function->sourceCode(); if (!sourceCode) return jsUndefined(); int lineNumber = sourceCode->firstLine(); if (lineNumber) lineNumber -= 1; // In the inspector protocol all positions are 0-based while in SourceCode they are 1-based UString scriptId = UString::number(sourceCode->provider()->asID()); JSObject* location = constructEmptyObject(exec); location->putDirect(exec->globalData(), Identifier(exec, "lineNumber"), jsNumber(lineNumber)); location->putDirect(exec->globalData(), Identifier(exec, "scriptId"), jsString(exec, scriptId)); JSObject* result = constructEmptyObject(exec); result->putDirect(exec->globalData(), Identifier(exec, "location"), location); UString name = function->name(exec); if (!name.isEmpty()) result->putDirect(exec->globalData(), Identifier(exec, "name"), jsString(exec, name)); UString displayName = function->displayName(exec); if (!displayName.isEmpty()) result->putDirect(exec->globalData(), Identifier(exec, "displayName"), jsString(exec, displayName)); // FIXME: provide function scope data in "scopesRaw" property when JSC supports it. // https://bugs.webkit.org/show_bug.cgi?id=87192 return result; }
const UString* DebuggerCallFrame::functionName() const { if (!m_codeBlock) return 0; JSFunction* function = static_cast<JSFunction*>(callFrame()[RegisterFile::Callee].getJSValue()); if (!function) return 0; return &function->name(m_exec); }
const UString* DebuggerCallFrame::functionName() const { if (!m_callFrame->codeBlock()) return 0; JSFunction* function = asFunction(m_callFrame->callee()); if (!function) return 0; return &function->name(&m_callFrame->globalData()); }
EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); if (thisValue.inherits(&JSFunction::info)) { JSFunction* function = asFunction(thisValue); if (function->isHostFunction()) return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "() {\n [native code]\n}")); FunctionExecutable* executable = function->jsExecutable(); UString sourceString = executable->source().toString(); insertSemicolonIfNeeded(sourceString); return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "(", executable->paramString(), ") ", sourceString)); } if (thisValue.inherits(&InternalFunction::info)) { InternalFunction* function = asInternalFunction(thisValue); return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "() {\n [native code]\n}")); } return throwVMTypeError(exec); }
EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec) { JSValue thisValue = exec->thisValue(); if (thisValue.inherits(JSFunction::info())) { JSFunction* function = jsCast<JSFunction*>(thisValue); if (function->isHostOrBuiltinFunction()) return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "() {\n [native code]\n}")); FunctionExecutable* executable = function->jsExecutable(); String source = executable->source().provider()->getRange( executable->parametersStartOffset(), executable->typeProfilingEndOffset() + 1); // Type profiling end offset is the character before the '}'. return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), source)); } if (thisValue.inherits(InternalFunction::info())) { InternalFunction* function = asInternalFunction(thisValue); return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "() {\n [native code]\n}")); } return throwVMTypeError(exec); }
void ScriptCallStack::initialize() { if (!m_caller || m_initialized) return; JSValue func = m_exec->interpreter()->retrieveCaller(m_exec, m_caller); while (!func.isNull()) { JSFunction* jsFunction = asFunction(func); ArgList emptyArgList; m_frames.append(ScriptCallFrame(jsFunction->name(m_exec), UString(), 0, emptyArgList, 0)); func = m_exec->interpreter()->retrieveCaller(m_exec, jsFunction); } m_initialized = true; }
JSValue JSInjectedScriptHost::functionDetails(ExecState* exec) { if (exec->argumentCount() < 1) return jsUndefined(); JSValue value = exec->uncheckedArgument(0); if (!value.asCell()->inherits(JSFunction::info())) return jsUndefined(); // FIXME: This should provide better details for JSBoundFunctions. JSFunction* function = jsCast<JSFunction*>(value); const SourceCode* sourceCode = function->sourceCode(); if (!sourceCode) return jsUndefined(); // In the inspector protocol all positions are 0-based while in SourceCode they are 1-based int lineNumber = sourceCode->firstLine(); if (lineNumber) lineNumber -= 1; int columnNumber = sourceCode->startColumn(); if (columnNumber) columnNumber -= 1; VM& vm = exec->vm(); String scriptID = String::number(sourceCode->provider()->asID()); JSObject* location = constructEmptyObject(exec); location->putDirect(vm, Identifier::fromString(exec, "scriptId"), jsString(exec, scriptID)); location->putDirect(vm, Identifier::fromString(exec, "lineNumber"), jsNumber(lineNumber)); location->putDirect(vm, Identifier::fromString(exec, "columnNumber"), jsNumber(columnNumber)); JSObject* result = constructEmptyObject(exec); result->putDirect(vm, Identifier::fromString(exec, "location"), location); String name = function->name(); if (!name.isEmpty()) result->putDirect(vm, Identifier::fromString(exec, "name"), jsString(exec, name)); String displayName = function->displayName(vm); if (!displayName.isEmpty()) result->putDirect(vm, Identifier::fromString(exec, "displayName"), jsString(exec, displayName)); // FIXME: provide function scope data in "scopesRaw" property when JSC supports it. // <https://webkit.org/b/87192> [JSC] expose function (closure) inner context to debugger return result; }
void ScriptCallStack::initialize() { if (!m_caller || m_initialized) return; int signedLineNumber; intptr_t sourceID; UString urlString; JSValue function; // callFrame must exist if m_caller is not null. CallFrame* callFrame = m_exec->callerFrame(); while (true) { ASSERT(callFrame); m_exec->interpreter()->retrieveLastCaller(callFrame, signedLineNumber, sourceID, urlString, function); if (!function) break; JSFunction* jsFunction = asFunction(function); unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0; m_frames.append(ScriptCallFrame(jsFunction->name(m_exec), urlString, lineNumber, m_exec, 0)); callFrame = callFrame->callerFrame(); } m_initialized = true; }
JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { if (thisValue.inherits(&JSFunction::info)) { JSFunction* function = asFunction(thisValue); if (!function->isHostFunction()) { FunctionExecutable* executable = function->jsExecutable(); UString sourceString = executable->source().toString(); insertSemicolonIfNeeded(sourceString); return jsString(exec, makeString("function ", function->name(exec), "(", executable->paramString(), ") ", sourceString)); } } if (thisValue.inherits(&InternalFunction::info)) { InternalFunction* function = asInternalFunction(thisValue); return jsString(exec, makeString("function ", function->name(exec), "() {\n [native code]\n}")); } #ifdef QT_BUILD_SCRIPT_LIB //same error message as in the old engine, and in mozilla return throwError(exec, TypeError, "Function.prototype.toString called on incompatible object"); #else return throwError(exec, TypeError); #endif }