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 sourceString = executable->source().toString(); insertSemicolonIfNeeded(sourceString, executable->bodyIncludesBraces()); 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); }
PassRefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor( CodeSpecializationKind kind, JSFunction* function, JSScope** scope, JSObject*& exception) { VM* vm = (*scope)->vm(); ASSERT(vm->heap.isDeferred()); ASSERT(startColumn() != UINT_MAX); ASSERT(endColumn() != UINT_MAX); if (classInfo() == EvalExecutable::info()) { EvalExecutable* executable = jsCast<EvalExecutable*>(this); RELEASE_ASSERT(kind == CodeForCall); RELEASE_ASSERT(!executable->m_evalCodeBlock); RELEASE_ASSERT(!function); return adoptRef(new EvalCodeBlock( executable, executable->m_unlinkedEvalCodeBlock.get(), *scope, executable->source().provider())); } if (classInfo() == ProgramExecutable::info()) { ProgramExecutable* executable = jsCast<ProgramExecutable*>(this); RELEASE_ASSERT(kind == CodeForCall); RELEASE_ASSERT(!executable->m_programCodeBlock); RELEASE_ASSERT(!function); return adoptRef(new ProgramCodeBlock( executable, executable->m_unlinkedProgramCodeBlock.get(), *scope, executable->source().provider(), executable->source().startColumn())); } RELEASE_ASSERT(classInfo() == FunctionExecutable::info()); RELEASE_ASSERT(function); FunctionExecutable* executable = jsCast<FunctionExecutable*>(this); RELEASE_ASSERT(!executable->codeBlockFor(kind)); JSGlobalObject* globalObject = (*scope)->globalObject(); ParserError error; DebuggerMode debuggerMode = globalObject->hasDebugger() ? DebuggerOn : DebuggerOff; ProfilerMode profilerMode = globalObject->hasProfiler() ? ProfilerOn : ProfilerOff; UnlinkedFunctionCodeBlock* unlinkedCodeBlock = executable->m_unlinkedExecutable->codeBlockFor( *vm, executable->m_source, kind, debuggerMode, profilerMode, executable->bodyIncludesBraces(), error); recordParse(executable->m_unlinkedExecutable->features(), executable->m_unlinkedExecutable->hasCapturedVariables(), lineNo(), lastLine(), startColumn(), endColumn()); if (!unlinkedCodeBlock) { exception = vm->throwException( globalObject->globalExec(), error.toErrorObject(globalObject, executable->m_source)); return 0; } // Parsing reveals whether our function uses features that require a separate function name object in the scope chain. // Be sure to add this scope before linking the bytecode because this scope will change the resolution depth of non-local variables. if (!executable->m_didParseForTheFirstTime) { executable->m_didParseForTheFirstTime = true; function->addNameScopeIfNeeded(*vm); *scope = function->scope(); } SourceProvider* provider = executable->source().provider(); unsigned sourceOffset = executable->source().startOffset(); unsigned startColumn = executable->source().startColumn(); return adoptRef(new FunctionCodeBlock( executable, unlinkedCodeBlock, *scope, provider, sourceOffset, startColumn)); }