Correctly annotate eval origin.
There were a couple of issues with it: - interpreter is not supported - the source position was just accidentally correct for full-codegen - the eval origin could have been cached Also fixes a few other places to use AbstractCode. R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/1854713002 Cr-Commit-Position: refs/heads/master@{#35257}
This commit is contained in:
parent
c9d1668f98
commit
2f3a171adc
@ -661,11 +661,8 @@ void Accessors::ScriptEvalFromScriptPositionGetter(
|
|||||||
Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
|
Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
|
||||||
Handle<Object> result = isolate->factory()->undefined_value();
|
Handle<Object> result = isolate->factory()->undefined_value();
|
||||||
if (script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
|
if (script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
|
||||||
Handle<Code> code(SharedFunctionInfo::cast(
|
result =
|
||||||
script->eval_from_shared())->code());
|
Handle<Object>(Smi::FromInt(script->eval_from_position()), isolate);
|
||||||
result = Handle<Object>(Smi::FromInt(code->SourcePosition(
|
|
||||||
script->eval_from_instructions_offset())),
|
|
||||||
isolate);
|
|
||||||
}
|
}
|
||||||
info.GetReturnValue().Set(Utils::ToLocal(result));
|
info.GetReturnValue().Set(Utils::ToLocal(result));
|
||||||
}
|
}
|
||||||
|
12
src/api.cc
12
src/api.cc
@ -2032,6 +2032,7 @@ MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
|
|||||||
}
|
}
|
||||||
|
|
||||||
i::Handle<i::Object> name_obj;
|
i::Handle<i::Object> name_obj;
|
||||||
|
int eval_position = 0;
|
||||||
int line_offset = 0;
|
int line_offset = 0;
|
||||||
int column_offset = 0;
|
int column_offset = 0;
|
||||||
if (!source->resource_name.IsEmpty()) {
|
if (!source->resource_name.IsEmpty()) {
|
||||||
@ -2044,11 +2045,12 @@ MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
|
|||||||
column_offset = static_cast<int>(source->resource_column_offset->Value());
|
column_offset = static_cast<int>(source->resource_column_offset->Value());
|
||||||
}
|
}
|
||||||
i::Handle<i::JSFunction> fun;
|
i::Handle<i::JSFunction> fun;
|
||||||
has_pending_exception = !i::Compiler::GetFunctionFromEval(
|
has_pending_exception =
|
||||||
source_string, outer_info, context, i::SLOPPY,
|
!i::Compiler::GetFunctionFromEval(
|
||||||
i::ONLY_SINGLE_FUNCTION_LITERAL, line_offset,
|
source_string, outer_info, context, i::SLOPPY,
|
||||||
column_offset - scope_position, name_obj,
|
i::ONLY_SINGLE_FUNCTION_LITERAL, eval_position, line_offset,
|
||||||
source->resource_options).ToHandle(&fun);
|
column_offset - scope_position, name_obj, source->resource_options)
|
||||||
|
.ToHandle(&fun);
|
||||||
if (has_pending_exception) {
|
if (has_pending_exception) {
|
||||||
isolate->ReportPendingMessages();
|
isolate->ReportPendingMessages();
|
||||||
}
|
}
|
||||||
|
@ -2055,11 +2055,12 @@ MaybeHandle<JSFunction> CompileString(Handle<Context> context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compile source string in the native context.
|
// Compile source string in the native context.
|
||||||
Handle<SharedFunctionInfo> outer_info(native_context->closure()->shared(),
|
StackTraceFrameIterator it(isolate);
|
||||||
isolate);
|
FrameSummary summary = FrameSummary::GetFirst(it.frame());
|
||||||
|
Handle<SharedFunctionInfo> outer_info(summary.function()->shared());
|
||||||
|
int pos = summary.abstract_code()->SourcePosition(summary.code_offset());
|
||||||
return Compiler::GetFunctionFromEval(source, outer_info, native_context,
|
return Compiler::GetFunctionFromEval(source, outer_info, native_context,
|
||||||
SLOPPY, restriction,
|
SLOPPY, restriction, pos);
|
||||||
RelocInfo::kNoPosition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -1509,8 +1509,9 @@ void Compiler::CompileForLiveEdit(Handle<Script> script) {
|
|||||||
MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
|
MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
|
||||||
Handle<String> source, Handle<SharedFunctionInfo> outer_info,
|
Handle<String> source, Handle<SharedFunctionInfo> outer_info,
|
||||||
Handle<Context> context, LanguageMode language_mode,
|
Handle<Context> context, LanguageMode language_mode,
|
||||||
ParseRestriction restriction, int line_offset, int column_offset,
|
ParseRestriction restriction, int eval_position, int line_offset,
|
||||||
Handle<Object> script_name, ScriptOriginOptions options) {
|
int column_offset, Handle<Object> script_name,
|
||||||
|
ScriptOriginOptions options) {
|
||||||
Isolate* isolate = source->GetIsolate();
|
Isolate* isolate = source->GetIsolate();
|
||||||
int source_length = source->length();
|
int source_length = source->length();
|
||||||
isolate->counters()->total_eval_size()->Increment(source_length);
|
isolate->counters()->total_eval_size()->Increment(source_length);
|
||||||
@ -1519,7 +1520,7 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
|
|||||||
CompilationCache* compilation_cache = isolate->compilation_cache();
|
CompilationCache* compilation_cache = isolate->compilation_cache();
|
||||||
MaybeHandle<SharedFunctionInfo> maybe_shared_info =
|
MaybeHandle<SharedFunctionInfo> maybe_shared_info =
|
||||||
compilation_cache->LookupEval(source, outer_info, context, language_mode,
|
compilation_cache->LookupEval(source, outer_info, context, language_mode,
|
||||||
line_offset);
|
eval_position);
|
||||||
Handle<SharedFunctionInfo> shared_info;
|
Handle<SharedFunctionInfo> shared_info;
|
||||||
|
|
||||||
Handle<Script> script;
|
Handle<Script> script;
|
||||||
@ -1531,6 +1532,10 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
|
|||||||
script->set_column_offset(column_offset);
|
script->set_column_offset(column_offset);
|
||||||
}
|
}
|
||||||
script->set_origin_options(options);
|
script->set_origin_options(options);
|
||||||
|
script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
|
||||||
|
script->set_eval_from_shared(*outer_info);
|
||||||
|
script->set_eval_from_position(eval_position);
|
||||||
|
|
||||||
Zone zone(isolate->allocator());
|
Zone zone(isolate->allocator());
|
||||||
ParseInfo parse_info(&zone, script);
|
ParseInfo parse_info(&zone, script);
|
||||||
CompilationInfo info(&parse_info);
|
CompilationInfo info(&parse_info);
|
||||||
@ -1540,8 +1545,6 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
|
|||||||
parse_info.set_parse_restriction(restriction);
|
parse_info.set_parse_restriction(restriction);
|
||||||
parse_info.set_context(context);
|
parse_info.set_context(context);
|
||||||
|
|
||||||
Debug::RecordEvalCaller(script);
|
|
||||||
|
|
||||||
shared_info = CompileToplevel(&info);
|
shared_info = CompileToplevel(&info);
|
||||||
|
|
||||||
if (shared_info.is_null()) {
|
if (shared_info.is_null()) {
|
||||||
@ -1557,7 +1560,7 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
|
|||||||
DCHECK(is_sloppy(language_mode) ||
|
DCHECK(is_sloppy(language_mode) ||
|
||||||
is_strict(shared_info->language_mode()));
|
is_strict(shared_info->language_mode()));
|
||||||
compilation_cache->PutEval(source, outer_info, context, shared_info,
|
compilation_cache->PutEval(source, outer_info, context, shared_info,
|
||||||
line_offset);
|
eval_position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,8 +77,8 @@ class Compiler : public AllStatic {
|
|||||||
MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval(
|
MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval(
|
||||||
Handle<String> source, Handle<SharedFunctionInfo> outer_info,
|
Handle<String> source, Handle<SharedFunctionInfo> outer_info,
|
||||||
Handle<Context> context, LanguageMode language_mode,
|
Handle<Context> context, LanguageMode language_mode,
|
||||||
ParseRestriction restriction, int line_offset, int column_offset = 0,
|
ParseRestriction restriction, int eval_position, int line_offset = 0,
|
||||||
Handle<Object> script_name = Handle<Object>(),
|
int column_offset = 0, Handle<Object> script_name = Handle<Object>(),
|
||||||
ScriptOriginOptions options = ScriptOriginOptions());
|
ScriptOriginOptions options = ScriptOriginOptions());
|
||||||
|
|
||||||
// Create a shared function info object for a String source within a context.
|
// Create a shared function info object for a String source within a context.
|
||||||
|
@ -2456,7 +2456,7 @@ void AstGraphBuilder::VisitCall(Call* expr) {
|
|||||||
// provide a fully resolved callee to patch into the environment.
|
// provide a fully resolved callee to patch into the environment.
|
||||||
Node* function = GetFunctionClosure();
|
Node* function = GetFunctionClosure();
|
||||||
Node* language = jsgraph()->Constant(language_mode());
|
Node* language = jsgraph()->Constant(language_mode());
|
||||||
Node* position = jsgraph()->Constant(current_scope()->start_position());
|
Node* position = jsgraph()->Constant(expr->position());
|
||||||
const Operator* op =
|
const Operator* op =
|
||||||
javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval);
|
javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval);
|
||||||
Node* new_callee =
|
Node* new_callee =
|
||||||
|
@ -95,11 +95,11 @@ MaybeHandle<Object> DebugEvaluate::Evaluate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Handle<JSFunction> eval_fun;
|
Handle<JSFunction> eval_fun;
|
||||||
ASSIGN_RETURN_ON_EXCEPTION(isolate, eval_fun,
|
ASSIGN_RETURN_ON_EXCEPTION(
|
||||||
Compiler::GetFunctionFromEval(
|
isolate, eval_fun,
|
||||||
source, outer_info, context, SLOPPY,
|
Compiler::GetFunctionFromEval(source, outer_info, context, SLOPPY,
|
||||||
NO_PARSE_RESTRICTION, RelocInfo::kNoPosition),
|
NO_PARSE_RESTRICTION, 0),
|
||||||
Object);
|
Object);
|
||||||
|
|
||||||
Handle<Object> result;
|
Handle<Object> result;
|
||||||
ASSIGN_RETURN_ON_EXCEPTION(
|
ASSIGN_RETURN_ON_EXCEPTION(
|
||||||
|
@ -72,8 +72,7 @@ int FrameInspector::GetSourcePosition() {
|
|||||||
return deoptimized_frame_->GetSourcePosition();
|
return deoptimized_frame_->GetSourcePosition();
|
||||||
} else if (is_interpreted_) {
|
} else if (is_interpreted_) {
|
||||||
InterpretedFrame* frame = reinterpret_cast<InterpretedFrame*>(frame_);
|
InterpretedFrame* frame = reinterpret_cast<InterpretedFrame*>(frame_);
|
||||||
BytecodeArray* bytecode_array =
|
BytecodeArray* bytecode_array = frame->GetBytecodeArray();
|
||||||
frame->function()->shared()->bytecode_array();
|
|
||||||
return bytecode_array->SourcePosition(frame->GetBytecodeOffset());
|
return bytecode_array->SourcePosition(frame->GetBytecodeOffset());
|
||||||
} else {
|
} else {
|
||||||
Code* code = frame_->LookupCode();
|
Code* code = frame_->LookupCode();
|
||||||
|
@ -260,12 +260,6 @@ BreakLocation BreakLocation::FromCodeOffset(Handle<DebugInfo> debug_info,
|
|||||||
return it->GetBreakLocation();
|
return it->GetBreakLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameSummary GetFirstFrameSummary(JavaScriptFrame* frame) {
|
|
||||||
List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
|
|
||||||
frame->Summarize(&frames);
|
|
||||||
return frames.first();
|
|
||||||
}
|
|
||||||
|
|
||||||
int CallOffsetFromCodeOffset(int code_offset, bool is_interpreted) {
|
int CallOffsetFromCodeOffset(int code_offset, bool is_interpreted) {
|
||||||
// Code offset points to the instruction after the call. Subtract 1 to
|
// Code offset points to the instruction after the call. Subtract 1 to
|
||||||
// exclude that instruction from the search. For bytecode, the code offset
|
// exclude that instruction from the search. For bytecode, the code offset
|
||||||
@ -275,7 +269,7 @@ int CallOffsetFromCodeOffset(int code_offset, bool is_interpreted) {
|
|||||||
|
|
||||||
BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info,
|
BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info,
|
||||||
JavaScriptFrame* frame) {
|
JavaScriptFrame* frame) {
|
||||||
FrameSummary summary = GetFirstFrameSummary(frame);
|
FrameSummary summary = FrameSummary::GetFirst(frame);
|
||||||
int call_offset =
|
int call_offset =
|
||||||
CallOffsetFromCodeOffset(summary.code_offset(), frame->is_interpreted());
|
CallOffsetFromCodeOffset(summary.code_offset(), frame->is_interpreted());
|
||||||
return FromCodeOffset(debug_info, call_offset);
|
return FromCodeOffset(debug_info, call_offset);
|
||||||
@ -631,7 +625,7 @@ void Debug::Break(JavaScriptFrame* frame) {
|
|||||||
step_break = location.IsTailCall();
|
step_break = location.IsTailCall();
|
||||||
// Fall through.
|
// Fall through.
|
||||||
case StepIn: {
|
case StepIn: {
|
||||||
FrameSummary summary = GetFirstFrameSummary(frame);
|
FrameSummary summary = FrameSummary::GetFirst(frame);
|
||||||
int offset = summary.code_offset();
|
int offset = summary.code_offset();
|
||||||
step_break = step_break || location.IsReturn() ||
|
step_break = step_break || location.IsReturn() ||
|
||||||
(current_fp != last_fp) ||
|
(current_fp != last_fp) ||
|
||||||
@ -1011,7 +1005,7 @@ void Debug::PrepareStep(StepAction step_action) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the debug info (create it if it does not exist).
|
// Get the debug info (create it if it does not exist).
|
||||||
FrameSummary summary = GetFirstFrameSummary(frame);
|
FrameSummary summary = FrameSummary::GetFirst(frame);
|
||||||
Handle<JSFunction> function(summary.function());
|
Handle<JSFunction> function(summary.function());
|
||||||
Handle<SharedFunctionInfo> shared(function->shared());
|
Handle<SharedFunctionInfo> shared(function->shared());
|
||||||
if (!EnsureDebugInfo(shared, function)) {
|
if (!EnsureDebugInfo(shared, function)) {
|
||||||
@ -1022,7 +1016,7 @@ void Debug::PrepareStep(StepAction step_action) {
|
|||||||
Handle<DebugInfo> debug_info(shared->GetDebugInfo());
|
Handle<DebugInfo> debug_info(shared->GetDebugInfo());
|
||||||
// Refresh frame summary if the code has been recompiled for debugging.
|
// Refresh frame summary if the code has been recompiled for debugging.
|
||||||
if (AbstractCode::cast(shared->code()) != *summary.abstract_code()) {
|
if (AbstractCode::cast(shared->code()) != *summary.abstract_code()) {
|
||||||
summary = GetFirstFrameSummary(frame);
|
summary = FrameSummary::GetFirst(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
int call_offset =
|
int call_offset =
|
||||||
@ -1604,7 +1598,7 @@ bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
|
|||||||
if (!shared->HasDebugInfo()) return false;
|
if (!shared->HasDebugInfo()) return false;
|
||||||
|
|
||||||
DCHECK(!frame->is_optimized());
|
DCHECK(!frame->is_optimized());
|
||||||
FrameSummary summary = GetFirstFrameSummary(frame);
|
FrameSummary summary = FrameSummary::GetFirst(frame);
|
||||||
|
|
||||||
Handle<DebugInfo> debug_info(shared->GetDebugInfo());
|
Handle<DebugInfo> debug_info(shared->GetDebugInfo());
|
||||||
BreakLocation location =
|
BreakLocation location =
|
||||||
@ -1656,21 +1650,6 @@ Handle<FixedArray> Debug::GetLoadedScripts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Debug::RecordEvalCaller(Handle<Script> script) {
|
|
||||||
script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
|
|
||||||
// For eval scripts add information on the function from which eval was
|
|
||||||
// called.
|
|
||||||
StackTraceFrameIterator it(script->GetIsolate());
|
|
||||||
if (!it.done()) {
|
|
||||||
script->set_eval_from_shared(it.frame()->function()->shared());
|
|
||||||
Code* code = it.frame()->LookupCode();
|
|
||||||
int offset = static_cast<int>(
|
|
||||||
it.frame()->pc() - code->instruction_start());
|
|
||||||
script->set_eval_from_instructions_offset(offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MaybeHandle<Object> Debug::MakeExecutionState() {
|
MaybeHandle<Object> Debug::MakeExecutionState() {
|
||||||
// Create the execution state object.
|
// Create the execution state object.
|
||||||
Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()) };
|
Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()) };
|
||||||
@ -2287,7 +2266,7 @@ void Debug::PrintBreakLocation() {
|
|||||||
JavaScriptFrameIterator iterator(isolate_);
|
JavaScriptFrameIterator iterator(isolate_);
|
||||||
if (iterator.done()) return;
|
if (iterator.done()) return;
|
||||||
JavaScriptFrame* frame = iterator.frame();
|
JavaScriptFrame* frame = iterator.frame();
|
||||||
FrameSummary summary = GetFirstFrameSummary(frame);
|
FrameSummary summary = FrameSummary::GetFirst(frame);
|
||||||
int source_position =
|
int source_position =
|
||||||
summary.abstract_code()->SourcePosition(summary.code_offset());
|
summary.abstract_code()->SourcePosition(summary.code_offset());
|
||||||
Handle<Object> script_obj(summary.function()->shared()->script(), isolate_);
|
Handle<Object> script_obj(summary.function()->shared()->script(), isolate_);
|
||||||
|
@ -499,9 +499,6 @@ class Debug {
|
|||||||
static int ArchiveSpacePerThread();
|
static int ArchiveSpacePerThread();
|
||||||
void FreeThreadResources() { }
|
void FreeThreadResources() { }
|
||||||
|
|
||||||
// Record function from which eval was called.
|
|
||||||
static void RecordEvalCaller(Handle<Script> script);
|
|
||||||
|
|
||||||
bool CheckExecutionState(int id) {
|
bool CheckExecutionState(int id) {
|
||||||
return is_active() && !debug_context().is_null() && break_id() != 0 &&
|
return is_active() && !debug_context().is_null() && break_id() != 0 &&
|
||||||
break_id() == id;
|
break_id() == id;
|
||||||
|
@ -1374,8 +1374,7 @@ static Handle<Script> CreateScriptCopy(Handle<Script> original) {
|
|||||||
copy->set_type(original->type());
|
copy->set_type(original->type());
|
||||||
copy->set_context_data(original->context_data());
|
copy->set_context_data(original->context_data());
|
||||||
copy->set_eval_from_shared(original->eval_from_shared());
|
copy->set_eval_from_shared(original->eval_from_shared());
|
||||||
copy->set_eval_from_instructions_offset(
|
copy->set_eval_from_position(original->eval_from_position());
|
||||||
original->eval_from_instructions_offset());
|
|
||||||
|
|
||||||
// Copy all the flags, but clear compilation state.
|
// Copy all the flags, but clear compilation state.
|
||||||
copy->set_flags(original->flags());
|
copy->set_flags(original->flags());
|
||||||
|
@ -893,7 +893,7 @@ Handle<Script> Factory::NewScript(Handle<String> source) {
|
|||||||
script->set_wrapper(heap->undefined_value());
|
script->set_wrapper(heap->undefined_value());
|
||||||
script->set_line_ends(heap->undefined_value());
|
script->set_line_ends(heap->undefined_value());
|
||||||
script->set_eval_from_shared(heap->undefined_value());
|
script->set_eval_from_shared(heap->undefined_value());
|
||||||
script->set_eval_from_instructions_offset(0);
|
script->set_eval_from_position(0);
|
||||||
script->set_shared_function_infos(Smi::FromInt(0));
|
script->set_shared_function_infos(Smi::FromInt(0));
|
||||||
script->set_flags(0);
|
script->set_flags(0);
|
||||||
|
|
||||||
|
@ -976,6 +976,12 @@ FrameSummary::FrameSummary(Object* receiver, JSFunction* function,
|
|||||||
CannotDeoptFromAsmCode(Code::cast(abstract_code), function));
|
CannotDeoptFromAsmCode(Code::cast(abstract_code), function));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FrameSummary FrameSummary::GetFirst(JavaScriptFrame* frame) {
|
||||||
|
List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
|
||||||
|
frame->Summarize(&frames);
|
||||||
|
return frames.first();
|
||||||
|
}
|
||||||
|
|
||||||
void FrameSummary::Print() {
|
void FrameSummary::Print() {
|
||||||
PrintF("receiver: ");
|
PrintF("receiver: ");
|
||||||
receiver_->ShortPrint();
|
receiver_->ShortPrint();
|
||||||
@ -1228,15 +1234,15 @@ void InterpretedFrame::PatchBytecodeOffset(int new_offset) {
|
|||||||
SetExpression(index, Smi::FromInt(raw_offset));
|
SetExpression(index, Smi::FromInt(raw_offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
Object* InterpretedFrame::GetBytecodeArray() const {
|
BytecodeArray* InterpretedFrame::GetBytecodeArray() const {
|
||||||
const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
|
const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
|
||||||
DCHECK_EQ(
|
DCHECK_EQ(
|
||||||
InterpreterFrameConstants::kBytecodeArrayFromFp,
|
InterpreterFrameConstants::kBytecodeArrayFromFp,
|
||||||
InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
|
InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
|
||||||
return GetExpression(index);
|
return BytecodeArray::cast(GetExpression(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpretedFrame::PatchBytecodeArray(Object* bytecode_array) {
|
void InterpretedFrame::PatchBytecodeArray(BytecodeArray* bytecode_array) {
|
||||||
const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
|
const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
|
||||||
DCHECK_EQ(
|
DCHECK_EQ(
|
||||||
InterpreterFrameConstants::kBytecodeArrayFromFp,
|
InterpreterFrameConstants::kBytecodeArrayFromFp,
|
||||||
|
@ -701,6 +701,7 @@ class StandardFrame: public StackFrame {
|
|||||||
friend class SafeStackFrameIterator;
|
friend class SafeStackFrameIterator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class JavaScriptFrame;
|
||||||
|
|
||||||
class FrameSummary BASE_EMBEDDED {
|
class FrameSummary BASE_EMBEDDED {
|
||||||
public:
|
public:
|
||||||
@ -708,6 +709,8 @@ class FrameSummary BASE_EMBEDDED {
|
|||||||
AbstractCode* abstract_code, int code_offset,
|
AbstractCode* abstract_code, int code_offset,
|
||||||
bool is_constructor);
|
bool is_constructor);
|
||||||
|
|
||||||
|
static FrameSummary GetFirst(JavaScriptFrame* frame);
|
||||||
|
|
||||||
Handle<Object> receiver() { return receiver_; }
|
Handle<Object> receiver() { return receiver_; }
|
||||||
Handle<JSFunction> function() { return function_; }
|
Handle<JSFunction> function() { return function_; }
|
||||||
Handle<AbstractCode> abstract_code() { return abstract_code_; }
|
Handle<AbstractCode> abstract_code() { return abstract_code_; }
|
||||||
@ -893,11 +896,11 @@ class InterpretedFrame : public JavaScriptFrame {
|
|||||||
void PatchBytecodeOffset(int new_offset);
|
void PatchBytecodeOffset(int new_offset);
|
||||||
|
|
||||||
// Returns the frame's current bytecode array.
|
// Returns the frame's current bytecode array.
|
||||||
Object* GetBytecodeArray() const;
|
BytecodeArray* GetBytecodeArray() const;
|
||||||
|
|
||||||
// Updates the frame's BytecodeArray with |bytecode_array|. Used by the
|
// Updates the frame's BytecodeArray with |bytecode_array|. Used by the
|
||||||
// debugger to swap execution onto a BytecodeArray patched with breakpoints.
|
// debugger to swap execution onto a BytecodeArray patched with breakpoints.
|
||||||
void PatchBytecodeArray(Object* bytecode_array);
|
void PatchBytecodeArray(BytecodeArray* bytecode_array);
|
||||||
|
|
||||||
// Access to the interpreter register file for this frame.
|
// Access to the interpreter register file for this frame.
|
||||||
Object* GetInterpreterRegister(int register_index) const;
|
Object* GetInterpreterRegister(int register_index) const;
|
||||||
|
@ -2663,8 +2663,8 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
|
|||||||
context()->DropAndPlug(1, r0);
|
context()->DropAndPlug(1, r0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
|
||||||
void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
int arg_count = expr->arguments()->length();
|
||||||
// r4: copy of the first argument or undefined if it doesn't exist.
|
// r4: copy of the first argument or undefined if it doesn't exist.
|
||||||
if (arg_count > 0) {
|
if (arg_count > 0) {
|
||||||
__ ldr(r4, MemOperand(sp, arg_count * kPointerSize));
|
__ ldr(r4, MemOperand(sp, arg_count * kPointerSize));
|
||||||
@ -2678,8 +2678,8 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
|||||||
// r2: language mode.
|
// r2: language mode.
|
||||||
__ mov(r2, Operand(Smi::FromInt(language_mode())));
|
__ mov(r2, Operand(Smi::FromInt(language_mode())));
|
||||||
|
|
||||||
// r1: the start position of the scope the calls resides in.
|
// r1: the source position of the eval call.
|
||||||
__ mov(r1, Operand(Smi::FromInt(scope()->start_position())));
|
__ mov(r1, Operand(Smi::FromInt(expr->position())));
|
||||||
|
|
||||||
// Do the runtime call.
|
// Do the runtime call.
|
||||||
__ Push(r4, r3, r2, r1);
|
__ Push(r4, r3, r2, r1);
|
||||||
@ -2731,7 +2731,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
|||||||
|
|
||||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||||
// In a call to eval, we first call
|
// In a call to eval, we first call
|
||||||
// RuntimeHidden_asResolvePossiblyDirectEval to resolve the function we need
|
// Runtime_ResolvePossiblyDirectEval to resolve the function we need
|
||||||
// to call. Then we call the resolved function using the given arguments.
|
// to call. Then we call the resolved function using the given arguments.
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
int arg_count = args->length();
|
int arg_count = args->length();
|
||||||
@ -2747,7 +2747,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
|||||||
// resolve eval.
|
// resolve eval.
|
||||||
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||||
__ push(r1);
|
__ push(r1);
|
||||||
EmitResolvePossiblyDirectEval(arg_count);
|
EmitResolvePossiblyDirectEval(expr);
|
||||||
|
|
||||||
// Touch up the stack with the resolved function.
|
// Touch up the stack with the resolved function.
|
||||||
__ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
__ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||||
|
@ -2461,8 +2461,8 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
|
|||||||
context()->DropAndPlug(1, x0);
|
context()->DropAndPlug(1, x0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
|
||||||
void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
int arg_count = expr->arguments()->length();
|
||||||
ASM_LOCATION("FullCodeGenerator::EmitResolvePossiblyDirectEval");
|
ASM_LOCATION("FullCodeGenerator::EmitResolvePossiblyDirectEval");
|
||||||
// Prepare to push a copy of the first argument or undefined if it doesn't
|
// Prepare to push a copy of the first argument or undefined if it doesn't
|
||||||
// exist.
|
// exist.
|
||||||
@ -2476,8 +2476,8 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
|||||||
|
|
||||||
// Prepare to push the language mode.
|
// Prepare to push the language mode.
|
||||||
__ Mov(x11, Smi::FromInt(language_mode()));
|
__ Mov(x11, Smi::FromInt(language_mode()));
|
||||||
// Prepare to push the start position of the scope the calls resides in.
|
// Prepare to push the source position of the eval call.
|
||||||
__ Mov(x12, Smi::FromInt(scope()->start_position()));
|
__ Mov(x12, Smi::FromInt(expr->position()));
|
||||||
|
|
||||||
// Push.
|
// Push.
|
||||||
__ Push(x9, x10, x11, x12);
|
__ Push(x9, x10, x11, x12);
|
||||||
@ -2530,7 +2530,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
|||||||
|
|
||||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||||
ASM_LOCATION("FullCodeGenerator::EmitPossiblyEvalCall");
|
ASM_LOCATION("FullCodeGenerator::EmitPossiblyEvalCall");
|
||||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
// In a call to eval, we first call Runtime_ResolvePossiblyDirectEval
|
||||||
// to resolve the function we need to call. Then we call the resolved
|
// to resolve the function we need to call. Then we call the resolved
|
||||||
// function using the given arguments.
|
// function using the given arguments.
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
@ -2547,7 +2547,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
|||||||
// resolve eval.
|
// resolve eval.
|
||||||
__ Peek(x10, (arg_count + 1) * kPointerSize);
|
__ Peek(x10, (arg_count + 1) * kPointerSize);
|
||||||
__ Push(x10);
|
__ Push(x10);
|
||||||
EmitResolvePossiblyDirectEval(arg_count);
|
EmitResolvePossiblyDirectEval(expr);
|
||||||
|
|
||||||
// Touch up the stack with the resolved function.
|
// Touch up the stack with the resolved function.
|
||||||
__ Poke(x0, (arg_count + 1) * kPointerSize);
|
__ Poke(x0, (arg_count + 1) * kPointerSize);
|
||||||
|
@ -560,7 +560,7 @@ class FullCodeGenerator: public AstVisitor {
|
|||||||
bool NeedsHoleCheckForLoad(VariableProxy* proxy);
|
bool NeedsHoleCheckForLoad(VariableProxy* proxy);
|
||||||
|
|
||||||
// Expects the arguments and the function already pushed.
|
// Expects the arguments and the function already pushed.
|
||||||
void EmitResolvePossiblyDirectEval(int arg_count);
|
void EmitResolvePossiblyDirectEval(Call* expr);
|
||||||
|
|
||||||
// Platform-specific support for allocating a new closure based on
|
// Platform-specific support for allocating a new closure based on
|
||||||
// the given function info.
|
// the given function info.
|
||||||
|
@ -2550,8 +2550,8 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
|
|||||||
context()->DropAndPlug(1, eax);
|
context()->DropAndPlug(1, eax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
|
||||||
void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
int arg_count = expr->arguments()->length();
|
||||||
// Push copy of the first argument or undefined if it doesn't exist.
|
// Push copy of the first argument or undefined if it doesn't exist.
|
||||||
if (arg_count > 0) {
|
if (arg_count > 0) {
|
||||||
__ push(Operand(esp, arg_count * kPointerSize));
|
__ push(Operand(esp, arg_count * kPointerSize));
|
||||||
@ -2565,8 +2565,8 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
|||||||
// Push the language mode.
|
// Push the language mode.
|
||||||
__ push(Immediate(Smi::FromInt(language_mode())));
|
__ push(Immediate(Smi::FromInt(language_mode())));
|
||||||
|
|
||||||
// Push the start position of the scope the calls resides in.
|
// Push the source position of the eval call.
|
||||||
__ push(Immediate(Smi::FromInt(scope()->start_position())));
|
__ push(Immediate(Smi::FromInt(expr->position())));
|
||||||
|
|
||||||
// Do the runtime call.
|
// Do the runtime call.
|
||||||
__ CallRuntime(Runtime::kResolvePossiblyDirectEval);
|
__ CallRuntime(Runtime::kResolvePossiblyDirectEval);
|
||||||
@ -2614,7 +2614,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
|||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
// In a call to eval, we first call Runtime_ResolvePossiblyDirectEval
|
||||||
// to resolve the function we need to call. Then we call the resolved
|
// to resolve the function we need to call. Then we call the resolved
|
||||||
// function using the given arguments.
|
// function using the given arguments.
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
@ -2630,7 +2630,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
|||||||
// Push a copy of the function (found below the arguments) and
|
// Push a copy of the function (found below the arguments) and
|
||||||
// resolve eval.
|
// resolve eval.
|
||||||
__ push(Operand(esp, (arg_count + 1) * kPointerSize));
|
__ push(Operand(esp, (arg_count + 1) * kPointerSize));
|
||||||
EmitResolvePossiblyDirectEval(arg_count);
|
EmitResolvePossiblyDirectEval(expr);
|
||||||
|
|
||||||
// Touch up the stack with the resolved function.
|
// Touch up the stack with the resolved function.
|
||||||
__ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
|
__ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
|
||||||
|
@ -2660,8 +2660,8 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
|
|||||||
context()->DropAndPlug(1, v0);
|
context()->DropAndPlug(1, v0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
|
||||||
void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
int arg_count = expr->arguments()->length();
|
||||||
// t3: copy of the first argument or undefined if it doesn't exist.
|
// t3: copy of the first argument or undefined if it doesn't exist.
|
||||||
if (arg_count > 0) {
|
if (arg_count > 0) {
|
||||||
__ lw(t3, MemOperand(sp, arg_count * kPointerSize));
|
__ lw(t3, MemOperand(sp, arg_count * kPointerSize));
|
||||||
@ -2675,8 +2675,8 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
|||||||
// t1: the language mode.
|
// t1: the language mode.
|
||||||
__ li(t1, Operand(Smi::FromInt(language_mode())));
|
__ li(t1, Operand(Smi::FromInt(language_mode())));
|
||||||
|
|
||||||
// t0: the start position of the scope the calls resides in.
|
// t0: the source position of the eval call.
|
||||||
__ li(t0, Operand(Smi::FromInt(scope()->start_position())));
|
__ li(t0, Operand(Smi::FromInt(expr->position())));
|
||||||
|
|
||||||
// Do the runtime call.
|
// Do the runtime call.
|
||||||
__ Push(t3, t2, t1, t0);
|
__ Push(t3, t2, t1, t0);
|
||||||
@ -2728,7 +2728,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
|||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
// In a call to eval, we first call Runtime_ResolvePossiblyDirectEval
|
||||||
// to resolve the function we need to call. Then we call the resolved
|
// to resolve the function we need to call. Then we call the resolved
|
||||||
// function using the given arguments.
|
// function using the given arguments.
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
@ -2744,7 +2744,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
|||||||
// resolve eval.
|
// resolve eval.
|
||||||
__ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
__ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||||
__ push(a1);
|
__ push(a1);
|
||||||
EmitResolvePossiblyDirectEval(arg_count);
|
EmitResolvePossiblyDirectEval(expr);
|
||||||
|
|
||||||
// Touch up the stack with the resolved function.
|
// Touch up the stack with the resolved function.
|
||||||
__ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
__ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||||
|
@ -2661,8 +2661,8 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
|
|||||||
context()->DropAndPlug(1, v0);
|
context()->DropAndPlug(1, v0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
|
||||||
void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
int arg_count = expr->arguments()->length();
|
||||||
// a6: copy of the first argument or undefined if it doesn't exist.
|
// a6: copy of the first argument or undefined if it doesn't exist.
|
||||||
if (arg_count > 0) {
|
if (arg_count > 0) {
|
||||||
__ ld(a6, MemOperand(sp, arg_count * kPointerSize));
|
__ ld(a6, MemOperand(sp, arg_count * kPointerSize));
|
||||||
@ -2676,8 +2676,8 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
|||||||
// a4: the language mode.
|
// a4: the language mode.
|
||||||
__ li(a4, Operand(Smi::FromInt(language_mode())));
|
__ li(a4, Operand(Smi::FromInt(language_mode())));
|
||||||
|
|
||||||
// a1: the start position of the scope the calls resides in.
|
// a1: the source position of the eval call.
|
||||||
__ li(a1, Operand(Smi::FromInt(scope()->start_position())));
|
__ li(a1, Operand(Smi::FromInt(expr->position())));
|
||||||
|
|
||||||
// Do the runtime call.
|
// Do the runtime call.
|
||||||
__ Push(a6, a5, a4, a1);
|
__ Push(a6, a5, a4, a1);
|
||||||
@ -2729,7 +2729,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
|||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
// In a call to eval, we first call Runtime_ResolvePossiblyDirectEval
|
||||||
// to resolve the function we need to call. Then we call the resolved
|
// to resolve the function we need to call. Then we call the resolved
|
||||||
// function using the given arguments.
|
// function using the given arguments.
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
@ -2745,7 +2745,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
|||||||
// resolve eval.
|
// resolve eval.
|
||||||
__ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
__ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||||
__ push(a1);
|
__ push(a1);
|
||||||
EmitResolvePossiblyDirectEval(arg_count);
|
EmitResolvePossiblyDirectEval(expr);
|
||||||
|
|
||||||
// Touch up the stack with the resolved function.
|
// Touch up the stack with the resolved function.
|
||||||
__ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
__ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||||
|
@ -2664,8 +2664,8 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
|
|||||||
context()->DropAndPlug(1, r3);
|
context()->DropAndPlug(1, r3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
|
||||||
void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
int arg_count = expr->arguments()->length();
|
||||||
// r7: copy of the first argument or undefined if it doesn't exist.
|
// r7: copy of the first argument or undefined if it doesn't exist.
|
||||||
if (arg_count > 0) {
|
if (arg_count > 0) {
|
||||||
__ LoadP(r7, MemOperand(sp, arg_count * kPointerSize), r0);
|
__ LoadP(r7, MemOperand(sp, arg_count * kPointerSize), r0);
|
||||||
@ -2679,8 +2679,8 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
|||||||
// r5: language mode.
|
// r5: language mode.
|
||||||
__ LoadSmiLiteral(r5, Smi::FromInt(language_mode()));
|
__ LoadSmiLiteral(r5, Smi::FromInt(language_mode()));
|
||||||
|
|
||||||
// r4: the start position of the scope the calls resides in.
|
// r4: the source position of the eval call.
|
||||||
__ LoadSmiLiteral(r4, Smi::FromInt(scope()->start_position()));
|
__ LoadSmiLiteral(r4, Smi::FromInt(expr->position()));
|
||||||
|
|
||||||
// Do the runtime call.
|
// Do the runtime call.
|
||||||
__ Push(r7, r6, r5, r4);
|
__ Push(r7, r6, r5, r4);
|
||||||
@ -2731,7 +2731,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
|||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
// In a call to eval, we first call Runtime_ResolvePossiblyDirectEval
|
||||||
// to resolve the function we need to call. Then we call the resolved
|
// to resolve the function we need to call. Then we call the resolved
|
||||||
// function using the given arguments.
|
// function using the given arguments.
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
@ -2748,7 +2748,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
|||||||
// resolve eval.
|
// resolve eval.
|
||||||
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||||
__ push(r4);
|
__ push(r4);
|
||||||
EmitResolvePossiblyDirectEval(arg_count);
|
EmitResolvePossiblyDirectEval(expr);
|
||||||
|
|
||||||
// Touch up the stack with the resolved function.
|
// Touch up the stack with the resolved function.
|
||||||
__ StoreP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
__ StoreP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||||
|
@ -2599,7 +2599,8 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
|
|||||||
context()->DropAndPlug(1, r2);
|
context()->DropAndPlug(1, r2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
|
||||||
|
int arg_count = expr->arguments()->length();
|
||||||
// r6: copy of the first argument or undefined if it doesn't exist.
|
// r6: copy of the first argument or undefined if it doesn't exist.
|
||||||
if (arg_count > 0) {
|
if (arg_count > 0) {
|
||||||
__ LoadP(r6, MemOperand(sp, arg_count * kPointerSize), r0);
|
__ LoadP(r6, MemOperand(sp, arg_count * kPointerSize), r0);
|
||||||
@ -2613,8 +2614,8 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
|||||||
// r4: language mode.
|
// r4: language mode.
|
||||||
__ LoadSmiLiteral(r4, Smi::FromInt(language_mode()));
|
__ LoadSmiLiteral(r4, Smi::FromInt(language_mode()));
|
||||||
|
|
||||||
// r3: the start position of the scope the calls resides in.
|
// r3: the source position of the eval call.
|
||||||
__ LoadSmiLiteral(r3, Smi::FromInt(scope()->start_position()));
|
__ LoadSmiLiteral(r3, Smi::FromInt(expr->position()));
|
||||||
|
|
||||||
// Do the runtime call.
|
// Do the runtime call.
|
||||||
__ Push(r6, r5, r4, r3);
|
__ Push(r6, r5, r4, r3);
|
||||||
@ -2663,7 +2664,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
// In a call to eval, we first call Runtime_ResolvePossiblyDirectEval
|
||||||
// to resolve the function we need to call. Then we call the resolved
|
// to resolve the function we need to call. Then we call the resolved
|
||||||
// function using the given arguments.
|
// function using the given arguments.
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
@ -2680,7 +2681,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
|||||||
// resolve eval.
|
// resolve eval.
|
||||||
__ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
__ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||||
__ push(r3);
|
__ push(r3);
|
||||||
EmitResolvePossiblyDirectEval(arg_count);
|
EmitResolvePossiblyDirectEval(expr);
|
||||||
|
|
||||||
// Touch up the stack with the resolved function.
|
// Touch up the stack with the resolved function.
|
||||||
__ StoreP(r2, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
__ StoreP(r2, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||||
|
@ -2540,8 +2540,8 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
|
|||||||
context()->DropAndPlug(1, rax);
|
context()->DropAndPlug(1, rax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
|
||||||
void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
int arg_count = expr->arguments()->length();
|
||||||
// Push copy of the first argument or undefined if it doesn't exist.
|
// Push copy of the first argument or undefined if it doesn't exist.
|
||||||
if (arg_count > 0) {
|
if (arg_count > 0) {
|
||||||
__ Push(Operand(rsp, arg_count * kPointerSize));
|
__ Push(Operand(rsp, arg_count * kPointerSize));
|
||||||
@ -2555,8 +2555,8 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
|||||||
// Push the language mode.
|
// Push the language mode.
|
||||||
__ Push(Smi::FromInt(language_mode()));
|
__ Push(Smi::FromInt(language_mode()));
|
||||||
|
|
||||||
// Push the start position of the scope the calls resides in.
|
// Push the source position of the eval call.
|
||||||
__ Push(Smi::FromInt(scope()->start_position()));
|
__ Push(Smi::FromInt(expr->position()));
|
||||||
|
|
||||||
// Do the runtime call.
|
// Do the runtime call.
|
||||||
__ CallRuntime(Runtime::kResolvePossiblyDirectEval);
|
__ CallRuntime(Runtime::kResolvePossiblyDirectEval);
|
||||||
@ -2605,7 +2605,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
|||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
// In a call to eval, we first call Runtime_ResolvePossiblyDirectEval
|
||||||
// to resolve the function we need to call. Then we call the resolved
|
// to resolve the function we need to call. Then we call the resolved
|
||||||
// function using the given arguments.
|
// function using the given arguments.
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
@ -2620,7 +2620,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
|||||||
// Push a copy of the function (found below the arguments) and resolve
|
// Push a copy of the function (found below the arguments) and resolve
|
||||||
// eval.
|
// eval.
|
||||||
__ Push(Operand(rsp, (arg_count + 1) * kPointerSize));
|
__ Push(Operand(rsp, (arg_count + 1) * kPointerSize));
|
||||||
EmitResolvePossiblyDirectEval(arg_count);
|
EmitResolvePossiblyDirectEval(expr);
|
||||||
|
|
||||||
// Touch up the callee.
|
// Touch up the callee.
|
||||||
__ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
|
__ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
|
||||||
|
@ -2542,8 +2542,8 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
|
|||||||
context()->DropAndPlug(1, eax);
|
context()->DropAndPlug(1, eax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
|
||||||
void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
int arg_count = expr->arguments()->length();
|
||||||
// Push copy of the first argument or undefined if it doesn't exist.
|
// Push copy of the first argument or undefined if it doesn't exist.
|
||||||
if (arg_count > 0) {
|
if (arg_count > 0) {
|
||||||
__ push(Operand(esp, arg_count * kPointerSize));
|
__ push(Operand(esp, arg_count * kPointerSize));
|
||||||
@ -2557,8 +2557,8 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
|||||||
// Push the language mode.
|
// Push the language mode.
|
||||||
__ push(Immediate(Smi::FromInt(language_mode())));
|
__ push(Immediate(Smi::FromInt(language_mode())));
|
||||||
|
|
||||||
// Push the start position of the scope the calls resides in.
|
// Push the source position of the eval call.
|
||||||
__ push(Immediate(Smi::FromInt(scope()->start_position())));
|
__ push(Immediate(Smi::FromInt(expr->position())));
|
||||||
|
|
||||||
// Do the runtime call.
|
// Do the runtime call.
|
||||||
__ CallRuntime(Runtime::kResolvePossiblyDirectEval);
|
__ CallRuntime(Runtime::kResolvePossiblyDirectEval);
|
||||||
@ -2606,7 +2606,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
|
|||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
||||||
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
|
// In a call to eval, we first call Runtime_ResolvePossiblyDirectEval
|
||||||
// to resolve the function we need to call. Then we call the resolved
|
// to resolve the function we need to call. Then we call the resolved
|
||||||
// function using the given arguments.
|
// function using the given arguments.
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
@ -2622,7 +2622,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
|
|||||||
// Push a copy of the function (found below the arguments) and
|
// Push a copy of the function (found below the arguments) and
|
||||||
// resolve eval.
|
// resolve eval.
|
||||||
__ push(Operand(esp, (arg_count + 1) * kPointerSize));
|
__ push(Operand(esp, (arg_count + 1) * kPointerSize));
|
||||||
EmitResolvePossiblyDirectEval(arg_count);
|
EmitResolvePossiblyDirectEval(expr);
|
||||||
|
|
||||||
// Touch up the stack with the resolved function.
|
// Touch up the stack with the resolved function.
|
||||||
__ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
|
__ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
|
||||||
|
@ -763,10 +763,10 @@ void Heap::PreprocessStackTraces() {
|
|||||||
// If GC happens while adding a stack trace to the weak fixed array,
|
// If GC happens while adding a stack trace to the weak fixed array,
|
||||||
// which has been copied into a larger backing store, we may run into
|
// which has been copied into a larger backing store, we may run into
|
||||||
// a stack trace that has already been preprocessed. Guard against this.
|
// a stack trace that has already been preprocessed. Guard against this.
|
||||||
if (!maybe_code->IsCode()) break;
|
if (!maybe_code->IsAbstractCode()) break;
|
||||||
Code* code = Code::cast(maybe_code);
|
AbstractCode* abstract_code = AbstractCode::cast(maybe_code);
|
||||||
int offset = Smi::cast(elements->get(j + 3))->value();
|
int offset = Smi::cast(elements->get(j + 3))->value();
|
||||||
int pos = code->SourcePosition(offset);
|
int pos = abstract_code->SourcePosition(offset);
|
||||||
elements->set(j + 2, Smi::FromInt(pos));
|
elements->set(j + 2, Smi::FromInt(pos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2468,8 +2468,7 @@ void BytecodeGenerator::VisitCall(Call* expr) {
|
|||||||
.MoveRegister(Register::function_closure(), function)
|
.MoveRegister(Register::function_closure(), function)
|
||||||
.LoadLiteral(Smi::FromInt(language_mode()))
|
.LoadLiteral(Smi::FromInt(language_mode()))
|
||||||
.StoreAccumulatorInRegister(language)
|
.StoreAccumulatorInRegister(language)
|
||||||
.LoadLiteral(
|
.LoadLiteral(Smi::FromInt(expr->position()))
|
||||||
Smi::FromInt(execution_context()->scope()->start_position()))
|
|
||||||
.StoreAccumulatorInRegister(position);
|
.StoreAccumulatorInRegister(position);
|
||||||
|
|
||||||
// Call ResolvePossiblyDirectEval and modify the callee.
|
// Call ResolvePossiblyDirectEval and modify the callee.
|
||||||
|
@ -1319,9 +1319,16 @@ void Isolate::PrintCurrentStackTrace(FILE* out) {
|
|||||||
HandleScope scope(this);
|
HandleScope scope(this);
|
||||||
// Find code position if recorded in relocation info.
|
// Find code position if recorded in relocation info.
|
||||||
JavaScriptFrame* frame = it.frame();
|
JavaScriptFrame* frame = it.frame();
|
||||||
Code* code = frame->LookupCode();
|
int pos = RelocInfo::kNoPosition;
|
||||||
int offset = static_cast<int>(frame->pc() - code->instruction_start());
|
if (frame->is_interpreted()) {
|
||||||
int pos = frame->LookupCode()->SourcePosition(offset);
|
InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame);
|
||||||
|
BytecodeArray* bytecode_array = iframe->GetBytecodeArray();
|
||||||
|
pos = bytecode_array->SourcePosition(iframe->GetBytecodeOffset());
|
||||||
|
} else if (!frame->is_optimized()) {
|
||||||
|
Code* code = frame->LookupCode();
|
||||||
|
int offset = static_cast<int>(frame->pc() - code->instruction_start());
|
||||||
|
pos = frame->LookupCode()->SourcePosition(offset);
|
||||||
|
}
|
||||||
Handle<Object> pos_obj(Smi::FromInt(pos), this);
|
Handle<Object> pos_obj(Smi::FromInt(pos), this);
|
||||||
// Fetch function and receiver.
|
// Fetch function and receiver.
|
||||||
Handle<JSFunction> fun(frame->function());
|
Handle<JSFunction> fun(frame->function());
|
||||||
|
@ -5534,8 +5534,7 @@ ACCESSORS(Script, wrapper, HeapObject, kWrapperOffset)
|
|||||||
SMI_ACCESSORS(Script, type, kTypeOffset)
|
SMI_ACCESSORS(Script, type, kTypeOffset)
|
||||||
ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
|
ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
|
||||||
ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
|
ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
|
||||||
SMI_ACCESSORS(Script, eval_from_instructions_offset,
|
SMI_ACCESSORS(Script, eval_from_position, kEvalFromPositionOffset)
|
||||||
kEvalFrominstructionsOffsetOffset)
|
|
||||||
ACCESSORS(Script, shared_function_infos, Object, kSharedFunctionInfosOffset)
|
ACCESSORS(Script, shared_function_infos, Object, kSharedFunctionInfosOffset)
|
||||||
SMI_ACCESSORS(Script, flags, kFlagsOffset)
|
SMI_ACCESSORS(Script, flags, kFlagsOffset)
|
||||||
ACCESSORS(Script, source_url, Object, kSourceUrlOffset)
|
ACCESSORS(Script, source_url, Object, kSourceUrlOffset)
|
||||||
|
@ -1140,8 +1140,7 @@ void Script::ScriptPrint(std::ostream& os) { // NOLINT
|
|||||||
os << "\n - compilation type: " << compilation_type();
|
os << "\n - compilation type: " << compilation_type();
|
||||||
os << "\n - line ends: " << Brief(line_ends());
|
os << "\n - line ends: " << Brief(line_ends());
|
||||||
os << "\n - eval from shared: " << Brief(eval_from_shared());
|
os << "\n - eval from shared: " << Brief(eval_from_shared());
|
||||||
os << "\n - eval from instructions offset: "
|
os << "\n - eval from position: " << eval_from_position();
|
||||||
<< eval_from_instructions_offset();
|
|
||||||
os << "\n - shared function infos: " << Brief(shared_function_infos());
|
os << "\n - shared function infos: " << Brief(shared_function_infos());
|
||||||
os << "\n";
|
os << "\n";
|
||||||
}
|
}
|
||||||
|
@ -6481,9 +6481,9 @@ class Script: public Struct {
|
|||||||
// function from which eval was called.
|
// function from which eval was called.
|
||||||
DECL_ACCESSORS(eval_from_shared, Object)
|
DECL_ACCESSORS(eval_from_shared, Object)
|
||||||
|
|
||||||
// [eval_from_instructions_offset]: the instruction offset in the code for the
|
// [eval_from_position]: the source position in the code for the
|
||||||
// function from which eval was called where eval was called.
|
// function from which eval was called.
|
||||||
DECL_INT_ACCESSORS(eval_from_instructions_offset)
|
DECL_INT_ACCESSORS(eval_from_position)
|
||||||
|
|
||||||
// [shared_function_infos]: weak fixed array containing all shared
|
// [shared_function_infos]: weak fixed array containing all shared
|
||||||
// function infos created from this script.
|
// function infos created from this script.
|
||||||
@ -6570,10 +6570,10 @@ class Script: public Struct {
|
|||||||
static const int kLineEndsOffset = kTypeOffset + kPointerSize;
|
static const int kLineEndsOffset = kTypeOffset + kPointerSize;
|
||||||
static const int kIdOffset = kLineEndsOffset + kPointerSize;
|
static const int kIdOffset = kLineEndsOffset + kPointerSize;
|
||||||
static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
|
static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
|
||||||
static const int kEvalFrominstructionsOffsetOffset =
|
static const int kEvalFromPositionOffset =
|
||||||
kEvalFromSharedOffset + kPointerSize;
|
kEvalFromSharedOffset + kPointerSize;
|
||||||
static const int kSharedFunctionInfosOffset =
|
static const int kSharedFunctionInfosOffset =
|
||||||
kEvalFrominstructionsOffsetOffset + kPointerSize;
|
kEvalFromPositionOffset + kPointerSize;
|
||||||
static const int kFlagsOffset = kSharedFunctionInfosOffset + kPointerSize;
|
static const int kFlagsOffset = kSharedFunctionInfosOffset + kPointerSize;
|
||||||
static const int kSourceUrlOffset = kFlagsOffset + kPointerSize;
|
static const int kSourceUrlOffset = kFlagsOffset + kPointerSize;
|
||||||
static const int kSourceMappingUrlOffset = kSourceUrlOffset + kPointerSize;
|
static const int kSourceMappingUrlOffset = kSourceUrlOffset + kPointerSize;
|
||||||
|
@ -305,11 +305,10 @@ bool CodeGenerationFromStringsAllowed(Isolate* isolate,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Object* CompileGlobalEval(Isolate* isolate, Handle<String> source,
|
static Object* CompileGlobalEval(Isolate* isolate, Handle<String> source,
|
||||||
Handle<SharedFunctionInfo> outer_info,
|
Handle<SharedFunctionInfo> outer_info,
|
||||||
LanguageMode language_mode,
|
LanguageMode language_mode,
|
||||||
int scope_position) {
|
int eval_position) {
|
||||||
Handle<Context> context = Handle<Context>(isolate->context());
|
Handle<Context> context = Handle<Context>(isolate->context());
|
||||||
Handle<Context> native_context = Handle<Context>(context->native_context());
|
Handle<Context> native_context = Handle<Context>(context->native_context());
|
||||||
|
|
||||||
@ -333,7 +332,7 @@ static Object* CompileGlobalEval(Isolate* isolate, Handle<String> source,
|
|||||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||||
isolate, compiled,
|
isolate, compiled,
|
||||||
Compiler::GetFunctionFromEval(source, outer_info, context, language_mode,
|
Compiler::GetFunctionFromEval(source, outer_info, context, language_mode,
|
||||||
restriction, scope_position),
|
restriction, eval_position),
|
||||||
isolate->heap()->exception());
|
isolate->heap()->exception());
|
||||||
return *compiled;
|
return *compiled;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ bytecodes: [
|
|||||||
B(Mov), R(closure), R(6),
|
B(Mov), R(closure), R(6),
|
||||||
B(LdaZero),
|
B(LdaZero),
|
||||||
B(Star), R(7),
|
B(Star), R(7),
|
||||||
B(LdaSmi), U8(30),
|
B(LdaSmi), U8(52),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(5),
|
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(5),
|
||||||
B(Star), R(1),
|
B(Star), R(1),
|
||||||
|
@ -34,7 +34,7 @@ bytecodes: [
|
|||||||
B(Mov), R(closure), R(6),
|
B(Mov), R(closure), R(6),
|
||||||
B(LdaZero),
|
B(LdaZero),
|
||||||
B(Star), R(7),
|
B(Star), R(7),
|
||||||
B(LdaSmi), U8(30),
|
B(LdaSmi), U8(41),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(5),
|
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(5),
|
||||||
B(Star), R(1),
|
B(Star), R(1),
|
||||||
|
@ -647,119 +647,3 @@ constant pool: [
|
|||||||
handlers: [
|
handlers: [
|
||||||
]
|
]
|
||||||
|
|
||||||
---
|
|
||||||
snippet: "
|
|
||||||
function f(a, b) {
|
|
||||||
if (a == b) { return 1; }
|
|
||||||
if (a === b) { return 1; }
|
|
||||||
if (a < b) { return 1; }
|
|
||||||
if (a > b) { return 1; }
|
|
||||||
if (a <= b) { return 1; }
|
|
||||||
if (a >= b) { return 1; }
|
|
||||||
if (a in b) { return 1; }
|
|
||||||
if (a instanceof b) { return 1; }
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
f(1, 1);
|
|
||||||
"
|
|
||||||
frame size: 1
|
|
||||||
parameter count: 3
|
|
||||||
bytecode array length: 107
|
|
||||||
bytecodes: [
|
|
||||||
B(StackCheck),
|
|
||||||
B(Ldar), R(arg0),
|
|
||||||
B(Star), R(0),
|
|
||||||
B(Ldar), R(arg1),
|
|
||||||
B(TestEqual), R(0),
|
|
||||||
B(JumpIfFalse), U8(5),
|
|
||||||
B(LdaSmi), U8(1),
|
|
||||||
B(Return),
|
|
||||||
B(Ldar), R(arg0),
|
|
||||||
B(Star), R(0),
|
|
||||||
B(Ldar), R(arg1),
|
|
||||||
B(TestEqualStrict), R(0),
|
|
||||||
B(JumpIfFalse), U8(5),
|
|
||||||
B(LdaSmi), U8(1),
|
|
||||||
B(Return),
|
|
||||||
B(Ldar), R(arg0),
|
|
||||||
B(Star), R(0),
|
|
||||||
B(Ldar), R(arg1),
|
|
||||||
B(TestLessThan), R(0),
|
|
||||||
B(JumpIfFalse), U8(5),
|
|
||||||
B(LdaSmi), U8(1),
|
|
||||||
B(Return),
|
|
||||||
B(Ldar), R(arg0),
|
|
||||||
B(Star), R(0),
|
|
||||||
B(Ldar), R(arg1),
|
|
||||||
B(TestGreaterThan), R(0),
|
|
||||||
B(JumpIfFalse), U8(5),
|
|
||||||
B(LdaSmi), U8(1),
|
|
||||||
B(Return),
|
|
||||||
B(Ldar), R(arg0),
|
|
||||||
B(Star), R(0),
|
|
||||||
B(Ldar), R(arg1),
|
|
||||||
B(TestLessThanOrEqual), R(0),
|
|
||||||
B(JumpIfFalse), U8(5),
|
|
||||||
B(LdaSmi), U8(1),
|
|
||||||
B(Return),
|
|
||||||
B(Ldar), R(arg0),
|
|
||||||
B(Star), R(0),
|
|
||||||
B(Ldar), R(arg1),
|
|
||||||
B(TestGreaterThanOrEqual), R(0),
|
|
||||||
B(JumpIfFalse), U8(5),
|
|
||||||
B(LdaSmi), U8(1),
|
|
||||||
B(Return),
|
|
||||||
B(Ldar), R(arg0),
|
|
||||||
B(Star), R(0),
|
|
||||||
B(Ldar), R(arg1),
|
|
||||||
B(TestIn), R(0),
|
|
||||||
B(JumpIfFalse), U8(5),
|
|
||||||
B(LdaSmi), U8(1),
|
|
||||||
B(Return),
|
|
||||||
B(Ldar), R(arg0),
|
|
||||||
B(Star), R(0),
|
|
||||||
B(Ldar), R(arg1),
|
|
||||||
B(TestInstanceOf), R(0),
|
|
||||||
B(JumpIfFalse), U8(5),
|
|
||||||
B(LdaSmi), U8(1),
|
|
||||||
B(Return),
|
|
||||||
B(LdaZero),
|
|
||||||
B(Return),
|
|
||||||
]
|
|
||||||
constant pool: [
|
|
||||||
]
|
|
||||||
handlers: [
|
|
||||||
]
|
|
||||||
|
|
||||||
---
|
|
||||||
snippet: "
|
|
||||||
function f() {
|
|
||||||
var a = 0;
|
|
||||||
if (a) {
|
|
||||||
return 20;
|
|
||||||
} else {
|
|
||||||
return -20;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
f();
|
|
||||||
"
|
|
||||||
frame size: 1
|
|
||||||
parameter count: 1
|
|
||||||
bytecode array length: 14
|
|
||||||
bytecodes: [
|
|
||||||
B(StackCheck),
|
|
||||||
B(LdaZero),
|
|
||||||
B(Star), R(0),
|
|
||||||
B(JumpIfToBooleanFalse), U8(5),
|
|
||||||
B(LdaSmi), U8(20),
|
|
||||||
B(Return),
|
|
||||||
B(LdaSmi), U8(-20),
|
|
||||||
B(Return),
|
|
||||||
B(LdaUndefined),
|
|
||||||
B(Return),
|
|
||||||
]
|
|
||||||
constant pool: [
|
|
||||||
]
|
|
||||||
handlers: [
|
|
||||||
]
|
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ bytecodes: [
|
|||||||
B(Mov), R(closure), R(6),
|
B(Mov), R(closure), R(6),
|
||||||
B(LdaZero),
|
B(LdaZero),
|
||||||
B(Star), R(7),
|
B(Star), R(7),
|
||||||
B(LdaSmi), U8(30),
|
B(LdaSmi), U8(34),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(5),
|
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(5),
|
||||||
B(Star), R(1),
|
B(Star), R(1),
|
||||||
@ -77,7 +77,7 @@ bytecodes: [
|
|||||||
B(Mov), R(closure), R(6),
|
B(Mov), R(closure), R(6),
|
||||||
B(LdaZero),
|
B(LdaZero),
|
||||||
B(Star), R(7),
|
B(Star), R(7),
|
||||||
B(LdaSmi), U8(30),
|
B(LdaSmi), U8(34),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(5),
|
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(5),
|
||||||
B(Star), R(1),
|
B(Star), R(1),
|
||||||
@ -123,7 +123,7 @@ bytecodes: [
|
|||||||
B(Mov), R(closure), R(6),
|
B(Mov), R(closure), R(6),
|
||||||
B(LdaZero),
|
B(LdaZero),
|
||||||
B(Star), R(7),
|
B(Star), R(7),
|
||||||
B(LdaSmi), U8(30),
|
B(LdaSmi), U8(49),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(5),
|
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(5),
|
||||||
B(Star), R(1),
|
B(Star), R(1),
|
||||||
|
37
test/mjsunit/eval-origin.js
Normal file
37
test/mjsunit/eval-origin.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright 2016 the V8 project authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
Error.prepareStackTrace = function(exception, frames) {
|
||||||
|
return frames[0].getEvalOrigin();
|
||||||
|
}
|
||||||
|
|
||||||
|
var source = "new Error()";
|
||||||
|
var eval_origin;
|
||||||
|
var geval = eval;
|
||||||
|
var log = [];
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
log.push([geval(source).stack, "15:13"]);
|
||||||
|
log.push([geval(source).stack, "16:13"]);
|
||||||
|
log.push([geval(source).stack, "17:13"]);
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
log.push([eval(source).stack, "21:13"]);
|
||||||
|
log.push([eval(source).stack, "22:13"]);
|
||||||
|
log.push([eval(source).stack, "23:13"]);
|
||||||
|
})();
|
||||||
|
|
||||||
|
log.push([eval(source).stack, "26:11"]);
|
||||||
|
log.push([eval(source).stack, "27:11"]);
|
||||||
|
log.push([eval(source).stack, "28:11"]);
|
||||||
|
|
||||||
|
Error.prepareStackTrace = undefined;
|
||||||
|
|
||||||
|
for (var item of log) {
|
||||||
|
var stacktraceline = item[0];
|
||||||
|
var expectation = item[1];
|
||||||
|
var re = new RegExp(`:${expectation}\\)$`);
|
||||||
|
assertTrue(re.test(stacktraceline));
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user