+void ScriptExecutable::installCode(CodeBlock* genericCodeBlock)
+{
+ RELEASE_ASSERT(genericCodeBlock->ownerExecutable() == this);
+ RELEASE_ASSERT(JITCode::isExecutableScript(genericCodeBlock->jitType()));
+
+ VM& vm = *genericCodeBlock->vm();
+
+ if (vm.m_perBytecodeProfiler)
+ vm.m_perBytecodeProfiler->ensureBytecodesFor(genericCodeBlock);
+
+ ASSERT(vm.heap.isDeferred());
+
+ CodeSpecializationKind kind = genericCodeBlock->specializationKind();
+
+ RefPtr<CodeBlock> oldCodeBlock;
+
+ switch (kind) {
+ case CodeForCall:
+ m_jitCodeForCall = genericCodeBlock->jitCode();
+ m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr();
+ m_jitCodeForCallWithArityCheckAndPreserveRegs = MacroAssemblerCodePtr();
+ m_numParametersForCall = genericCodeBlock->numParameters();
+ break;
+ case CodeForConstruct:
+ m_jitCodeForConstruct = genericCodeBlock->jitCode();
+ m_jitCodeForConstructWithArityCheck = MacroAssemblerCodePtr();
+ m_jitCodeForConstructWithArityCheckAndPreserveRegs = MacroAssemblerCodePtr();
+ m_numParametersForConstruct = genericCodeBlock->numParameters();
+ break;
+ }
+
+ switch (genericCodeBlock->codeType()) {
+ case GlobalCode: {
+ ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
+ ProgramCodeBlock* codeBlock = static_cast<ProgramCodeBlock*>(genericCodeBlock);
+
+ ASSERT(kind == CodeForCall);
+
+ oldCodeBlock = executable->m_programCodeBlock;
+ executable->m_programCodeBlock = codeBlock;
+ break;
+ }
+
+ case EvalCode: {
+ EvalExecutable* executable = jsCast<EvalExecutable*>(this);
+ EvalCodeBlock* codeBlock = static_cast<EvalCodeBlock*>(genericCodeBlock);
+
+ ASSERT(kind == CodeForCall);
+
+ oldCodeBlock = executable->m_evalCodeBlock;
+ executable->m_evalCodeBlock = codeBlock;
+ break;
+ }
+
+ case FunctionCode: {
+ FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
+ FunctionCodeBlock* codeBlock = static_cast<FunctionCodeBlock*>(genericCodeBlock);
+
+ switch (kind) {
+ case CodeForCall:
+ oldCodeBlock = executable->m_codeBlockForCall;
+ executable->m_codeBlockForCall = codeBlock;
+ break;
+ case CodeForConstruct:
+ oldCodeBlock = executable->m_codeBlockForConstruct;
+ executable->m_codeBlockForConstruct = codeBlock;
+ break;
+ }
+ break;
+ } }
+
+ if (oldCodeBlock)
+ oldCodeBlock->unlinkIncomingCalls();
+
+ Debugger* debugger = genericCodeBlock->globalObject()->debugger();
+ if (debugger)
+ debugger->registerCodeBlock(genericCodeBlock);
+
+ Heap::heap(this)->writeBarrier(this);
+}
+
+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;
+ }