Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 89f50255789ac1f9d80a3d521aa2fa83e8554d3f..5b85246153c3732f13ead8aa1ae8a418d8e188d9 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -2175,60 +2175,58 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) { |
CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0); |
Handle<Object> code = args.at<Object>(1); |
- Handle<Context> context(target->context()); |
+ if (code->IsNull()) return *target; |
+ RUNTIME_ASSERT(code->IsJSFunction()); |
+ Handle<JSFunction> source = Handle<JSFunction>::cast(code); |
+ Handle<SharedFunctionInfo> target_shared(target->shared()); |
+ Handle<SharedFunctionInfo> source_shared(source->shared()); |
+ |
+ if (!source->is_compiled() && |
+ !JSFunction::CompileLazy(source, KEEP_EXCEPTION)) { |
+ return Failure::Exception(); |
+ } |
- if (!code->IsNull()) { |
- RUNTIME_ASSERT(code->IsJSFunction()); |
- Handle<JSFunction> fun = Handle<JSFunction>::cast(code); |
- Handle<SharedFunctionInfo> shared(fun->shared()); |
+ // Set the code, scope info, formal parameter count, and the length |
+ // of the target shared function info. Set the source code of the |
+ // target function to undefined. SetCode is only used for built-in |
+ // constructors like String, Array, and Object, and some web code |
+ // doesn't like seeing source code for constructors. |
+ target_shared->set_code(source_shared->code()); |
+ target_shared->set_scope_info(source_shared->scope_info()); |
+ target_shared->set_length(source_shared->length()); |
+ target_shared->set_formal_parameter_count( |
+ source_shared->formal_parameter_count()); |
+ target_shared->set_script(isolate->heap()->undefined_value()); |
+ |
+ // Since we don't store the source we should never optimize this. |
+ target_shared->code()->set_optimizable(false); |
+ |
+ // Clear the optimization hints related to the compiled code as these |
+ // are no longer valid when the code is overwritten. |
+ target_shared->ClearThisPropertyAssignmentsInfo(); |
+ |
+ // Set the code of the target function. |
+ target->ReplaceCode(source_shared->code()); |
+ |
+ // Make sure we get a fresh copy of the literal vector to avoid cross |
+ // context contamination. |
+ Handle<Context> context(source->context()); |
+ int number_of_literals = source->NumberOfLiterals(); |
+ Handle<FixedArray> literals = |
+ isolate->factory()->NewFixedArray(number_of_literals, TENURED); |
+ if (number_of_literals > 0) { |
+ literals->set(JSFunction::kLiteralGlobalContextIndex, |
+ context->global_context()); |
+ } |
+ target->set_context(*context); |
+ target->set_literals(*literals); |
+ target->set_next_function_link(isolate->heap()->undefined_value()); |
- if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) { |
- return Failure::Exception(); |
- } |
- // Since we don't store the source for this we should never |
- // optimize this. |
- shared->code()->set_optimizable(false); |
- // Set the code, scope info, formal parameter count, |
- // and the length of the target function. |
- target->shared()->set_code(shared->code()); |
- target->ReplaceCode(shared->code()); |
- target->shared()->set_scope_info(shared->scope_info()); |
- target->shared()->set_length(shared->length()); |
- target->shared()->set_formal_parameter_count( |
- shared->formal_parameter_count()); |
- // Set the source code of the target function to undefined. |
- // SetCode is only used for built-in constructors like String, |
- // Array, and Object, and some web code |
- // doesn't like seeing source code for constructors. |
- target->shared()->set_script(isolate->heap()->undefined_value()); |
- target->shared()->code()->set_optimizable(false); |
- // Clear the optimization hints related to the compiled code as these are no |
- // longer valid when the code is overwritten. |
- target->shared()->ClearThisPropertyAssignmentsInfo(); |
- context = Handle<Context>(fun->context()); |
- |
- // Make sure we get a fresh copy of the literal vector to avoid |
- // cross context contamination. |
- int number_of_literals = fun->NumberOfLiterals(); |
- Handle<FixedArray> literals = |
- isolate->factory()->NewFixedArray(number_of_literals, TENURED); |
- if (number_of_literals > 0) { |
- // Insert the object, regexp and array functions in the literals |
- // array prefix. These are the functions that will be used when |
- // creating object, regexp and array literals. |
- literals->set(JSFunction::kLiteralGlobalContextIndex, |
- context->global_context()); |
- } |
- target->set_literals(*literals); |
- target->set_next_function_link(isolate->heap()->undefined_value()); |
- |
- if (isolate->logger()->is_logging() || CpuProfiler::is_profiling(isolate)) { |
- isolate->logger()->LogExistingFunction( |
- shared, Handle<Code>(shared->code())); |
- } |
+ if (isolate->logger()->is_logging() || CpuProfiler::is_profiling(isolate)) { |
+ isolate->logger()->LogExistingFunction( |
+ source_shared, Handle<Code>(source_shared->code())); |
} |
- target->set_context(*context); |
return *target; |
} |