From 41386e9cb918eed93b3f13648cbef387e371e451 Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Wed, 20 May 2015 09:56:07 +0000 Subject: webkitgtk-2.4.9 --- Source/JavaScriptCore/runtime/Executable.cpp | 253 ++++++++++++--------------- 1 file changed, 113 insertions(+), 140 deletions(-) (limited to 'Source/JavaScriptCore/runtime/Executable.cpp') diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp index 0ab167211..bbd6ed23e 100644 --- a/Source/JavaScriptCore/runtime/Executable.cpp +++ b/Source/JavaScriptCore/runtime/Executable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2010, 2013, 2015 Apple Inc. All rights reserved. + * Copyright (C) 2009, 2010, 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,36 +27,34 @@ #include "Executable.h" #include "BatchedTransitionOptimizer.h" +#include "BytecodeGenerator.h" #include "CodeBlock.h" #include "DFGDriver.h" #include "JIT.h" -#include "JSCInlines.h" #include "LLIntEntrypoint.h" +#include "Operations.h" #include "Parser.h" -#include "ProfilerDatabase.h" -#include "TypeProfiler.h" -#include #include #include namespace JSC { -const ClassInfo ExecutableBase::s_info = { "Executable", 0, 0, CREATE_METHOD_TABLE(ExecutableBase) }; +const ClassInfo ExecutableBase::s_info = { "Executable", 0, 0, 0, CREATE_METHOD_TABLE(ExecutableBase) }; +#if ENABLE(JIT) void ExecutableBase::destroy(JSCell* cell) { static_cast(cell)->ExecutableBase::~ExecutableBase(); } +#endif void ExecutableBase::clearCode() { #if ENABLE(JIT) - m_jitCodeForCall = nullptr; - m_jitCodeForConstruct = nullptr; + m_jitCodeForCall.clear(); + m_jitCodeForConstruct.clear(); m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr(); m_jitCodeForConstructWithArityCheck = MacroAssemblerCodePtr(); - m_jitCodeForCallWithArityCheckAndPreserveRegs = MacroAssemblerCodePtr(); - m_jitCodeForConstructWithArityCheckAndPreserveRegs = MacroAssemblerCodePtr(); #endif m_numParametersForCall = NUM_PARAMETERS_NOT_COMPILED; m_numParametersForConstruct = NUM_PARAMETERS_NOT_COMPILED; @@ -76,12 +74,14 @@ Intrinsic ExecutableBase::intrinsic() const } #endif -const ClassInfo NativeExecutable::s_info = { "NativeExecutable", &ExecutableBase::s_info, 0, CREATE_METHOD_TABLE(NativeExecutable) }; +const ClassInfo NativeExecutable::s_info = { "NativeExecutable", &ExecutableBase::s_info, 0, 0, CREATE_METHOD_TABLE(NativeExecutable) }; +#if ENABLE(JIT) void NativeExecutable::destroy(JSCell* cell) { static_cast(cell)->NativeExecutable::~NativeExecutable(); } +#endif #if ENABLE(DFG_JIT) Intrinsic NativeExecutable::intrinsic() const @@ -90,38 +90,20 @@ Intrinsic NativeExecutable::intrinsic() const } #endif -const ClassInfo ScriptExecutable::s_info = { "ScriptExecutable", &ExecutableBase::s_info, 0, CREATE_METHOD_TABLE(ScriptExecutable) }; - -ScriptExecutable::ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext) - : ExecutableBase(vm, structure, NUM_PARAMETERS_NOT_COMPILED) - , m_source(source) - , m_features(isInStrictContext ? StrictModeFeature : 0) - , m_hasCapturedVariables(false) - , m_neverInline(false) - , m_didTryToEnterInLoop(false) - , m_overrideLineNumber(-1) - , m_firstLine(-1) - , m_lastLine(-1) - , m_startColumn(UINT_MAX) - , m_endColumn(UINT_MAX) - , m_typeProfilingStartOffset(UINT_MAX) - , m_typeProfilingEndOffset(UINT_MAX) -{ -} +const ClassInfo ScriptExecutable::s_info = { "ScriptExecutable", &ExecutableBase::s_info, 0, 0, CREATE_METHOD_TABLE(ScriptExecutable) }; +#if ENABLE(JIT) void ScriptExecutable::destroy(JSCell* cell) { static_cast(cell)->ScriptExecutable::~ScriptExecutable(); } +#endif void ScriptExecutable::installCode(CodeBlock* genericCodeBlock) { RELEASE_ASSERT(genericCodeBlock->ownerExecutable() == this); RELEASE_ASSERT(JITCode::isExecutableScript(genericCodeBlock->jitType())); - if (Options::verboseOSR()) - dataLog("Installing ", *genericCodeBlock, "\n"); - VM& vm = *genericCodeBlock->vm(); if (vm.m_perBytecodeProfiler) @@ -136,14 +118,12 @@ void ScriptExecutable::installCode(CodeBlock* genericCodeBlock) switch (kind) { case CodeForCall: m_jitCodeForCall = genericCodeBlock->jitCode(); - m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr(); - m_jitCodeForCallWithArityCheckAndPreserveRegs = MacroAssemblerCodePtr(); + m_jitCodeForCallWithArityCheck = genericCodeBlock->jitCodeWithArityCheck(); m_numParametersForCall = genericCodeBlock->numParameters(); break; case CodeForConstruct: m_jitCodeForConstruct = genericCodeBlock->jitCode(); - m_jitCodeForConstructWithArityCheck = MacroAssemblerCodePtr(); - m_jitCodeForConstructWithArityCheckAndPreserveRegs = MacroAssemblerCodePtr(); + m_jitCodeForConstructWithArityCheck = genericCodeBlock->jitCodeWithArityCheck(); m_numParametersForConstruct = genericCodeBlock->numParameters(); break; } @@ -153,6 +133,7 @@ void ScriptExecutable::installCode(CodeBlock* genericCodeBlock) ProgramExecutable* executable = jsCast(this); ProgramCodeBlock* codeBlock = static_cast(genericCodeBlock); + ASSERT(!codeBlock->jitCodeWithArityCheck()); ASSERT(kind == CodeForCall); oldCodeBlock = executable->m_programCodeBlock; @@ -164,6 +145,7 @@ void ScriptExecutable::installCode(CodeBlock* genericCodeBlock) EvalExecutable* executable = jsCast(this); EvalCodeBlock* codeBlock = static_cast(genericCodeBlock); + ASSERT(!codeBlock->jitCodeWithArityCheck()); ASSERT(kind == CodeForCall); oldCodeBlock = executable->m_evalCodeBlock; @@ -194,12 +176,10 @@ void ScriptExecutable::installCode(CodeBlock* genericCodeBlock) Debugger* debugger = genericCodeBlock->globalObject()->debugger(); if (debugger) debugger->registerCodeBlock(genericCodeBlock); - - Heap::heap(this)->writeBarrier(this); } -RefPtr ScriptExecutable::newCodeBlockFor( - CodeSpecializationKind kind, JSFunction* function, JSScope* scope, JSObject*& exception) +PassRefPtr ScriptExecutable::newCodeBlockFor( + CodeSpecializationKind kind, JSScope* scope, JSObject*& exception) { VM* vm = scope->vm(); @@ -211,7 +191,6 @@ RefPtr ScriptExecutable::newCodeBlockFor( EvalExecutable* executable = jsCast(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())); @@ -221,14 +200,12 @@ RefPtr ScriptExecutable::newCodeBlockFor( ProgramExecutable* executable = jsCast(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(this); RELEASE_ASSERT(!executable->codeBlockFor(kind)); JSGlobalObject* globalObject = scope->globalObject(); @@ -238,14 +215,14 @@ RefPtr ScriptExecutable::newCodeBlockFor( UnlinkedFunctionCodeBlock* unlinkedCodeBlock = executable->m_unlinkedExecutable->codeBlockFor( *vm, executable->m_source, kind, debuggerMode, profilerMode, error); - recordParse(executable->m_unlinkedExecutable->features(), executable->m_unlinkedExecutable->hasCapturedVariables(), firstLine(), lastLine(), startColumn(), endColumn()); + 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 nullptr; + return 0; } - + SourceProvider* provider = executable->source().provider(); unsigned sourceOffset = executable->source().startOffset(); unsigned startColumn = executable->source().startColumn(); @@ -291,7 +268,13 @@ PassRefPtr ScriptExecutable::newReplacementCodeBlockFor( static void setupLLInt(VM& vm, CodeBlock* codeBlock) { +#if ENABLE(LLINT) LLInt::setEntrypoint(vm, codeBlock); +#else + UNUSED_PARAM(vm); + UNUSED_PARAM(codeBlock); + UNREACHABLE_FOR_PLATFORM(); +#endif } static void setupJIT(VM& vm, CodeBlock* codeBlock) @@ -307,13 +290,13 @@ static void setupJIT(VM& vm, CodeBlock* codeBlock) } JSObject* ScriptExecutable::prepareForExecutionImpl( - ExecState* exec, JSFunction* function, JSScope* scope, CodeSpecializationKind kind) + ExecState* exec, JSScope* scope, CodeSpecializationKind kind) { VM& vm = exec->vm(); DeferGC deferGC(vm.heap); JSObject* exception = 0; - RefPtr codeBlock = newCodeBlockFor(kind, function, scope, exception); + RefPtr codeBlock = newCodeBlockFor(kind, scope, exception); if (!codeBlock) { RELEASE_ASSERT(exception); return exception; @@ -322,7 +305,18 @@ JSObject* ScriptExecutable::prepareForExecutionImpl( if (Options::validateBytecode()) codeBlock->validate(); - if (Options::useLLInt()) + bool shouldUseLLInt; +#if !ENABLE(JIT) + // No JIT implies use of the C Loop LLINT. Override the options to reflect this. + Options::useLLInt() = true; + shouldUseLLInt = true; +#elif ENABLE(LLINT) + shouldUseLLInt = Options::useLLInt(); +#else + shouldUseLLInt = false; +#endif + + if (shouldUseLLInt) setupLLInt(vm, codeBlock.get()); else setupJIT(vm, codeBlock.get()); @@ -331,9 +325,9 @@ JSObject* ScriptExecutable::prepareForExecutionImpl( return 0; } -const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(EvalExecutable) }; +const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(EvalExecutable) }; -EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source, bool isInStrictContext, ThisTDZMode thisTDZMode, const VariableEnvironment* variablesUnderTDZ) +EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source, bool isInStrictContext) { JSGlobalObject* globalObject = exec->lexicalGlobalObject(); if (!globalObject->evalEnabled()) { @@ -344,7 +338,7 @@ EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source EvalExecutable* executable = new (NotNull, allocateCell(*exec->heap())) EvalExecutable(exec, source, isInStrictContext); executable->finishCreation(exec->vm()); - UnlinkedEvalCodeBlock* unlinkedEvalCode = globalObject->createEvalCodeBlock(exec, executable, thisTDZMode, variablesUnderTDZ); + UnlinkedEvalCodeBlock* unlinkedEvalCode = globalObject->createEvalCodeBlock(exec, executable); if (!unlinkedEvalCode) return 0; @@ -354,7 +348,7 @@ EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source } EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext) - : ScriptExecutable(exec->vm().evalExecutableStructure.get(), exec->vm(), source, inStrictContext) + : ScriptExecutable(exec->vm().evalExecutableStructure.get(), exec, source, inStrictContext) { } @@ -363,15 +357,11 @@ void EvalExecutable::destroy(JSCell* cell) static_cast(cell)->EvalExecutable::~EvalExecutable(); } -const ClassInfo ProgramExecutable::s_info = { "ProgramExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(ProgramExecutable) }; +const ClassInfo ProgramExecutable::s_info = { "ProgramExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(ProgramExecutable) }; ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source) - : ScriptExecutable(exec->vm().programExecutableStructure.get(), exec->vm(), source, false) + : ScriptExecutable(exec->vm().programExecutableStructure.get(), exec, source, false) { - m_typeProfilingStartOffset = 0; - m_typeProfilingEndOffset = source.length() - 1; - if (exec->vm().typeProfiler() || exec->vm().controlFlowProfiler()) - exec->vm().functionHasExecutedCache()->insertUnexecutedRange(sourceID(), m_typeProfilingStartOffset, m_typeProfilingEndOffset); } void ProgramExecutable::destroy(JSCell* cell) @@ -379,13 +369,12 @@ void ProgramExecutable::destroy(JSCell* cell) static_cast(cell)->ProgramExecutable::~ProgramExecutable(); } -const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(FunctionExecutable) }; +const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionExecutable) }; -FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, - UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, - unsigned lastLine, unsigned startColumn, unsigned endColumn) +FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn, bool bodyIncludesBraces) : ScriptExecutable(vm.functionExecutableStructure.get(), vm, source, unlinkedExecutable->isInStrictContext()) , m_unlinkedExecutable(vm, this, unlinkedExecutable) + , m_bodyIncludesBraces(bodyIncludesBraces) { RELEASE_ASSERT(!source.isNull()); ASSERT(source.length()); @@ -395,15 +384,6 @@ FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, ASSERT(endColumn != UINT_MAX); m_startColumn = startColumn; m_endColumn = endColumn; - m_parametersStartOffset = unlinkedExecutable->parametersStartOffset(); - m_typeProfilingStartOffset = unlinkedExecutable->typeProfilingStartOffset(); - m_typeProfilingEndOffset = unlinkedExecutable->typeProfilingEndOffset(); -} - -void FunctionExecutable::finishCreation(VM& vm) -{ - Base::finishCreation(vm); - m_singletonFunction.set(vm, this, InferredValue::create(vm)); } void FunctionExecutable::destroy(JSCell* cell) @@ -432,6 +412,8 @@ void EvalExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor) { EvalExecutable* thisObject = jsCast(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); + ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); ScriptExecutable::visitChildren(thisObject, visitor); if (thisObject->m_evalCodeBlock) thisObject->m_evalCodeBlock->visitAggregate(visitor); @@ -450,7 +432,7 @@ void EvalExecutable::unlinkCalls() void EvalExecutable::clearCode() { - m_evalCodeBlock = nullptr; + m_evalCodeBlock.clear(); m_unlinkedEvalCodeBlock.clear(); Base::clearCode(); } @@ -460,12 +442,10 @@ JSObject* ProgramExecutable::checkSyntax(ExecState* exec) ParserError error; VM* vm = &exec->vm(); JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); - std::unique_ptr programNode = parse( - vm, m_source, Identifier(), JSParserBuiltinMode::NotBuiltin, - JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, error); + RefPtr programNode = parse(vm, m_source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, error); if (programNode) return 0; - ASSERT(error.isValid()); + ASSERT(error.m_type != ParserError::ErrorNone); return error.toErrorObject(lexicalGlobalObject, m_source); } @@ -495,21 +475,20 @@ JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callF BatchedTransitionOptimizer optimizer(vm, globalObject); - for (size_t i = 0, numberOfFunctions = unlinkedCodeBlock->numberOfFunctionDecls(); i < numberOfFunctions; ++i) { - UnlinkedFunctionExecutable* unlinkedFunctionExecutable = unlinkedCodeBlock->functionDecl(i); - ASSERT(!unlinkedFunctionExecutable->name().isEmpty()); - globalObject->addFunction(callFrame, unlinkedFunctionExecutable->name()); - if (vm.typeProfiler() || vm.controlFlowProfiler()) { - vm.functionHasExecutedCache()->insertUnexecutedRange(sourceID(), - unlinkedFunctionExecutable->typeProfilingStartOffset(), - unlinkedFunctionExecutable->typeProfilingEndOffset()); - } + const UnlinkedProgramCodeBlock::VariableDeclations& variableDeclarations = unlinkedCodeBlock->variableDeclarations(); + const UnlinkedProgramCodeBlock::FunctionDeclations& functionDeclarations = unlinkedCodeBlock->functionDeclarations(); + + for (size_t i = 0; i < functionDeclarations.size(); ++i) { + UnlinkedFunctionExecutable* unlinkedFunctionExecutable = functionDeclarations[i].second.get(); + JSValue value = JSFunction::create(vm, unlinkedFunctionExecutable->link(vm, m_source, lineNo(), 0), scope); + globalObject->addFunction(callFrame, functionDeclarations[i].first, value); } - const VariableEnvironment& variableDeclarations = unlinkedCodeBlock->variableDeclarations(); - for (auto& entry : variableDeclarations) { - ASSERT(entry.value.isVar()); - globalObject->addVar(callFrame, Identifier::fromUid(&vm, entry.key.get())); + for (size_t i = 0; i < variableDeclarations.size(); ++i) { + if (variableDeclarations[i].second & DeclarationStacks::IsConstant) + globalObject->addConst(callFrame, variableDeclarations[i].first); + else + globalObject->addVar(callFrame, variableDeclarations[i].first); } return 0; } @@ -518,6 +497,8 @@ void ProgramExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor) { ProgramExecutable* thisObject = jsCast(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); + ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); ScriptExecutable::visitChildren(thisObject, visitor); visitor.append(&thisObject->m_unlinkedProgramCodeBlock); if (thisObject->m_programCodeBlock) @@ -526,7 +507,7 @@ void ProgramExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor) void ProgramExecutable::clearCode() { - m_programCodeBlock = nullptr; + m_programCodeBlock.clear(); m_unlinkedProgramCodeBlock.clear(); Base::clearCode(); } @@ -549,24 +530,39 @@ void FunctionExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor) { FunctionExecutable* thisObject = jsCast(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); + ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); ScriptExecutable::visitChildren(thisObject, visitor); if (thisObject->m_codeBlockForCall) thisObject->m_codeBlockForCall->visitAggregate(visitor); if (thisObject->m_codeBlockForConstruct) thisObject->m_codeBlockForConstruct->visitAggregate(visitor); visitor.append(&thisObject->m_unlinkedExecutable); - visitor.append(&thisObject->m_singletonFunction); } -void FunctionExecutable::clearUnlinkedCodeForRecompilation() +SymbolTable* FunctionExecutable::symbolTable(CodeSpecializationKind kind) +{ + return codeBlockFor(kind)->symbolTable(); +} + +void FunctionExecutable::clearCodeIfNotCompiling() +{ + if (isCompiling()) + return; + clearCode(); +} + +void FunctionExecutable::clearUnlinkedCodeForRecompilationIfNotCompiling() { + if (isCompiling()) + return; m_unlinkedExecutable->clearCodeForRecompilation(); } void FunctionExecutable::clearCode() { - m_codeBlockForCall = nullptr; - m_codeBlockForConstruct = nullptr; + m_codeBlockForCall.clear(); + m_codeBlockForConstruct.clear(); Base::clearCode(); } @@ -584,57 +580,34 @@ void FunctionExecutable::unlinkCalls() #endif } -FunctionExecutable* FunctionExecutable::fromGlobalCode( - const Identifier& name, ExecState& exec, const SourceCode& source, - JSObject*& exception, int overrideLineNumber) +FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& name, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception) { - UnlinkedFunctionExecutable* unlinkedExecutable = - UnlinkedFunctionExecutable::fromGlobalCode( - name, exec, source, exception, overrideLineNumber); + UnlinkedFunctionExecutable* unlinkedExecutable = UnlinkedFunctionExecutable::fromGlobalCode(name, exec, debugger, source, exception); if (!unlinkedExecutable) - return nullptr; + return 0; + unsigned lineCount = unlinkedExecutable->lineCount(); + unsigned firstLine = source.firstLine() + unlinkedExecutable->firstLineOffset(); + unsigned startOffset = source.startOffset() + unlinkedExecutable->startOffset(); + + // We don't have any owner executable. The source string is effectively like a global + // string (like in the handling of eval). Hence, the startColumn is always 1. + unsigned startColumn = 1; + unsigned sourceLength = unlinkedExecutable->sourceLength(); + bool endColumnIsOnStartLine = !lineCount; + // The unlinkedBodyEndColumn is based-0. Hence, we need to add 1 to it. But if the + // endColumn is on the startLine, then we need to subtract back the adjustment for + // the open brace resulting in an adjustment of 0. + unsigned endColumnExcludingBraces = unlinkedExecutable->unlinkedBodyEndColumn() + (endColumnIsOnStartLine ? 0 : 1); + unsigned startOffsetExcludingOpenBrace = startOffset + 1; + unsigned endOffsetExcludingCloseBrace = startOffset + sourceLength - 1; + SourceCode bodySource(source.provider(), startOffsetExcludingOpenBrace, endOffsetExcludingCloseBrace, firstLine, startColumn); - return unlinkedExecutable->link(exec.vm(), source, overrideLineNumber); + return FunctionExecutable::create(exec->vm(), bodySource, unlinkedExecutable, firstLine, firstLine + lineCount, startColumn, endColumnExcludingBraces, false); } -void ExecutableBase::dump(PrintStream& out) const +String FunctionExecutable::paramString() const { - ExecutableBase* realThis = const_cast(this); - - if (classInfo() == NativeExecutable::info()) { - NativeExecutable* native = jsCast(realThis); - out.print("NativeExecutable:", RawPointer(bitwise_cast(native->function())), "/", RawPointer(bitwise_cast(native->constructor()))); - return; - } - - if (classInfo() == EvalExecutable::info()) { - EvalExecutable* eval = jsCast(realThis); - if (CodeBlock* codeBlock = eval->codeBlock()) - out.print(*codeBlock); - else - out.print("EvalExecutable w/o CodeBlock"); - return; - } - - if (classInfo() == ProgramExecutable::info()) { - ProgramExecutable* eval = jsCast(realThis); - if (CodeBlock* codeBlock = eval->codeBlock()) - out.print(*codeBlock); - else - out.print("ProgramExecutable w/o CodeBlock"); - return; - } - - FunctionExecutable* function = jsCast(realThis); - if (!function->eitherCodeBlock()) - out.print("FunctionExecutable w/o CodeBlock"); - else { - CommaPrinter comma("/"); - if (function->codeBlockForCall()) - out.print(comma, *function->codeBlockForCall()); - if (function->codeBlockForConstruct()) - out.print(comma, *function->codeBlockForConstruct()); - } + return m_unlinkedExecutable->paramString(); } CodeBlockHash ExecutableBase::hashFor(CodeSpecializationKind kind) const -- cgit v1.2.1