| Index: src/isolate.cc
 | 
| diff --git a/src/isolate.cc b/src/isolate.cc
 | 
| index 926b9866d4e019afb8fad2dd811f876e20044449..b236d46a68ac4d85120ec1e1d676d33596758e05 100644
 | 
| --- a/src/isolate.cc
 | 
| +++ b/src/isolate.cc
 | 
| @@ -433,14 +433,13 @@ Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object,
 | 
|          Code* code = wasm_frame->unchecked_code();
 | 
|          Handle<AbstractCode> abstract_code =
 | 
|              Handle<AbstractCode>(AbstractCode::cast(code));
 | 
| -        Handle<JSFunction> fun = factory()->NewFunction(
 | 
| -            factory()->NewStringFromAsciiChecked("<WASM>"));
 | 
| +        int offset =
 | 
| +            static_cast<int>(wasm_frame->pc() - code->instruction_start());
 | 
|          elements = MaybeGrow(this, elements, cursor, cursor + 4);
 | 
| -        // TODO(jfb) Pass module object.
 | 
| -        elements->set(cursor++, *factory()->undefined_value());
 | 
| -        elements->set(cursor++, *fun);
 | 
| +        elements->set(cursor++, wasm_frame->wasm_obj());
 | 
| +        elements->set(cursor++, Smi::FromInt(wasm_frame->function_index()));
 | 
|          elements->set(cursor++, *abstract_code);
 | 
| -        elements->set(cursor++, Internals::IntToSmi(0));
 | 
| +        elements->set(cursor++, Smi::FromInt(offset));
 | 
|          frames_seen++;
 | 
|        } break;
 | 
|  
 | 
| @@ -542,65 +541,64 @@ class CaptureStackTraceHelper {
 | 
|      }
 | 
|    }
 | 
|  
 | 
| +  Handle<JSObject> NewStackFrameObject(FrameSummary& summ) {
 | 
| +    int position = summ.abstract_code()->SourcePosition(summ.code_offset());
 | 
| +    return NewStackFrameObject(summ.function(), position,
 | 
| +                               summ.is_constructor());
 | 
| +  }
 | 
| +
 | 
|    Handle<JSObject> NewStackFrameObject(Handle<JSFunction> fun, int position,
 | 
|                                         bool is_constructor) {
 | 
|      Handle<JSObject> stack_frame =
 | 
|          factory()->NewJSObject(isolate_->object_function());
 | 
| -
 | 
| -    // TODO(clemensh): this can be changed to a DCHECK once also WASM frames
 | 
| -    // define a script
 | 
| -    if (!fun->shared()->script()->IsUndefined()) {
 | 
| -      Handle<Script> script(Script::cast(fun->shared()->script()));
 | 
| -
 | 
| -      if (!line_key_.is_null()) {
 | 
| -        int script_line_offset = script->line_offset();
 | 
| -        int line_number = Script::GetLineNumber(script, position);
 | 
| -        // line_number is already shifted by the script_line_offset.
 | 
| -        int relative_line_number = line_number - script_line_offset;
 | 
| -        if (!column_key_.is_null() && relative_line_number >= 0) {
 | 
| -          Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
 | 
| -          int start = (relative_line_number == 0)
 | 
| -                          ? 0
 | 
| -                          : Smi::cast(line_ends->get(relative_line_number - 1))
 | 
| -                                    ->value() +
 | 
| -                                1;
 | 
| -          int column_offset = position - start;
 | 
| -          if (relative_line_number == 0) {
 | 
| -            // For the case where the code is on the same line as the script
 | 
| -            // tag.
 | 
| -            column_offset += script->column_offset();
 | 
| -          }
 | 
| -          JSObject::AddProperty(
 | 
| -              stack_frame, column_key_,
 | 
| -              handle(Smi::FromInt(column_offset + 1), isolate_), NONE);
 | 
| +    Handle<Script> script(Script::cast(fun->shared()->script()));
 | 
| +
 | 
| +    if (!line_key_.is_null()) {
 | 
| +      int script_line_offset = script->line_offset();
 | 
| +      int line_number = Script::GetLineNumber(script, position);
 | 
| +      // line_number is already shifted by the script_line_offset.
 | 
| +      int relative_line_number = line_number - script_line_offset;
 | 
| +      if (!column_key_.is_null() && relative_line_number >= 0) {
 | 
| +        Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
 | 
| +        int start =
 | 
| +            (relative_line_number == 0)
 | 
| +                ? 0
 | 
| +                : Smi::cast(line_ends->get(relative_line_number - 1))->value() +
 | 
| +                      1;
 | 
| +        int column_offset = position - start;
 | 
| +        if (relative_line_number == 0) {
 | 
| +          // For the case where the code is on the same line as the script tag.
 | 
| +          column_offset += script->column_offset();
 | 
|          }
 | 
| -        JSObject::AddProperty(stack_frame, line_key_,
 | 
| -                              handle(Smi::FromInt(line_number + 1), isolate_),
 | 
| +        JSObject::AddProperty(stack_frame, column_key_,
 | 
| +                              handle(Smi::FromInt(column_offset + 1), isolate_),
 | 
|                                NONE);
 | 
|        }
 | 
| +      JSObject::AddProperty(stack_frame, line_key_,
 | 
| +                            handle(Smi::FromInt(line_number + 1), isolate_),
 | 
| +                            NONE);
 | 
| +    }
 | 
|  
 | 
| -      if (!script_id_key_.is_null()) {
 | 
| -        JSObject::AddProperty(stack_frame, script_id_key_,
 | 
| -                              handle(Smi::FromInt(script->id()), isolate_),
 | 
| -                              NONE);
 | 
| -      }
 | 
| +    if (!script_id_key_.is_null()) {
 | 
| +      JSObject::AddProperty(stack_frame, script_id_key_,
 | 
| +                            handle(Smi::FromInt(script->id()), isolate_), NONE);
 | 
| +    }
 | 
|  
 | 
| -      if (!script_name_key_.is_null()) {
 | 
| -        JSObject::AddProperty(stack_frame, script_name_key_,
 | 
| -                              handle(script->name(), isolate_), NONE);
 | 
| -      }
 | 
| +    if (!script_name_key_.is_null()) {
 | 
| +      JSObject::AddProperty(stack_frame, script_name_key_,
 | 
| +                            handle(script->name(), isolate_), NONE);
 | 
| +    }
 | 
|  
 | 
| -      if (!script_name_or_source_url_key_.is_null()) {
 | 
| -        Handle<Object> result = Script::GetNameOrSourceURL(script);
 | 
| -        JSObject::AddProperty(stack_frame, script_name_or_source_url_key_,
 | 
| -                              result, NONE);
 | 
| -      }
 | 
| +    if (!script_name_or_source_url_key_.is_null()) {
 | 
| +      Handle<Object> result = Script::GetNameOrSourceURL(script);
 | 
| +      JSObject::AddProperty(stack_frame, script_name_or_source_url_key_, result,
 | 
| +                            NONE);
 | 
| +    }
 | 
|  
 | 
| -      if (!eval_key_.is_null()) {
 | 
| -        Handle<Object> is_eval = factory()->ToBoolean(
 | 
| -            script->compilation_type() == Script::COMPILATION_TYPE_EVAL);
 | 
| -        JSObject::AddProperty(stack_frame, eval_key_, is_eval, NONE);
 | 
| -      }
 | 
| +    if (!eval_key_.is_null()) {
 | 
| +      Handle<Object> is_eval = factory()->ToBoolean(
 | 
| +          script->compilation_type() == Script::COMPILATION_TYPE_EVAL);
 | 
| +      JSObject::AddProperty(stack_frame, eval_key_, is_eval, NONE);
 | 
|      }
 | 
|  
 | 
|      if (!function_key_.is_null()) {
 | 
| @@ -613,6 +611,35 @@ class CaptureStackTraceHelper {
 | 
|        JSObject::AddProperty(stack_frame, constructor_key_, is_constructor_obj,
 | 
|                              NONE);
 | 
|      }
 | 
| +    return stack_frame;
 | 
| +  }
 | 
| +
 | 
| +  Handle<JSObject> NewStackFrameObject(WasmFrame* frame) {
 | 
| +    Handle<JSObject> stack_frame =
 | 
| +        factory()->NewJSObject(isolate_->object_function());
 | 
| +
 | 
| +    if (!function_key_.is_null()) {
 | 
| +      Handle<Object> fun_name = handle(frame->function_name(), isolate_);
 | 
| +      if (fun_name->IsUndefined())
 | 
| +        fun_name = isolate_->factory()->InternalizeUtf8String(
 | 
| +            Vector<const char>("<WASM>"));
 | 
| +      JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE);
 | 
| +    }
 | 
| +    // Encode the function index as line number.
 | 
| +    if (!line_key_.is_null()) {
 | 
| +      JSObject::AddProperty(
 | 
| +          stack_frame, line_key_,
 | 
| +          isolate_->factory()->NewNumberFromInt(frame->function_index()), NONE);
 | 
| +    }
 | 
| +    // Encode the byte offset as column.
 | 
| +    if (!column_key_.is_null()) {
 | 
| +      Code* code = frame->LookupCode();
 | 
| +      int offset = static_cast<int>(frame->pc() - code->instruction_start());
 | 
| +      int position = code->SourcePosition(offset);
 | 
| +      JSObject::AddProperty(stack_frame, column_key_,
 | 
| +                            isolate_->factory()->NewNumberFromInt(position),
 | 
| +                            NONE);
 | 
| +    }
 | 
|  
 | 
|      return stack_frame;
 | 
|    }
 | 
| @@ -691,29 +718,34 @@ Handle<JSArray> Isolate::CaptureCurrentStackTrace(
 | 
|    // Ensure no negative values.
 | 
|    int limit = Max(frame_limit, 0);
 | 
|    Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit);
 | 
| +  Handle<FixedArray> stack_trace_elems(
 | 
| +      FixedArray::cast(stack_trace->elements()), this);
 | 
|  
 | 
| -  StackTraceFrameIterator it(this);
 | 
|    int frames_seen = 0;
 | 
| -  while (!it.done() && (frames_seen < limit)) {
 | 
| +  for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit);
 | 
| +       it.Advance()) {
 | 
|      StandardFrame* frame = it.frame();
 | 
| -    // Set initial size to the maximum inlining level + 1 for the outermost
 | 
| -    // function.
 | 
| -    List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
 | 
| -    frame->Summarize(&frames);
 | 
| -    for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) {
 | 
| -      Handle<JSFunction> fun = frames[i].function();
 | 
| -      // Filter frames from other security contexts.
 | 
| -      if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) &&
 | 
| -          !this->context()->HasSameSecurityTokenAs(fun->context())) continue;
 | 
| -      int position =
 | 
| -          frames[i].abstract_code()->SourcePosition(frames[i].code_offset());
 | 
| -      Handle<JSObject> stack_frame =
 | 
| -          helper.NewStackFrameObject(fun, position, frames[i].is_constructor());
 | 
| -
 | 
| -      FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame);
 | 
| +    if (frame->is_java_script()) {
 | 
| +      // Set initial size to the maximum inlining level + 1 for the outermost
 | 
| +      // function.
 | 
| +      List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
 | 
| +      JavaScriptFrame::cast(frame)->Summarize(&frames);
 | 
| +      for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) {
 | 
| +        Handle<JSFunction> fun = frames[i].function();
 | 
| +        // Filter frames from other security contexts.
 | 
| +        if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) &&
 | 
| +            !this->context()->HasSameSecurityTokenAs(fun->context()))
 | 
| +          continue;
 | 
| +        Handle<JSObject> new_frame_obj = helper.NewStackFrameObject(frames[i]);
 | 
| +        stack_trace_elems->set(frames_seen, *new_frame_obj);
 | 
| +        frames_seen++;
 | 
| +      }
 | 
| +    } else {
 | 
| +      WasmFrame* wasm_frame = WasmFrame::cast(frame);
 | 
| +      Handle<JSObject> new_frame_obj = helper.NewStackFrameObject(wasm_frame);
 | 
| +      stack_trace_elems->set(frames_seen, *new_frame_obj);
 | 
|        frames_seen++;
 | 
|      }
 | 
| -    it.Advance();
 | 
|    }
 | 
|  
 | 
|    stack_trace->set_length(Smi::FromInt(frames_seen));
 | 
| @@ -1332,15 +1364,20 @@ void Isolate::PrintCurrentStackTrace(FILE* out) {
 | 
|        InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame);
 | 
|        pos = iframe->GetBytecodeArray()->SourcePosition(
 | 
|            iframe->GetBytecodeOffset());
 | 
| -    } else {
 | 
| +    } else if (frame->is_java_script()) {
 | 
|        Code* code = frame->LookupCode();
 | 
|        int offset = static_cast<int>(frame->pc() - code->instruction_start());
 | 
|        pos = frame->LookupCode()->SourcePosition(offset);
 | 
| +    } else {
 | 
| +      DCHECK(frame->is_wasm());
 | 
| +      // TODO(clemensh): include wasm frames here
 | 
| +      continue;
 | 
|      }
 | 
| +    JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
 | 
|      Handle<Object> pos_obj(Smi::FromInt(pos), this);
 | 
|      // Fetch function and receiver.
 | 
| -    Handle<JSFunction> fun(frame->function());
 | 
| -    Handle<Object> recv(frame->receiver(), this);
 | 
| +    Handle<JSFunction> fun(js_frame->function());
 | 
| +    Handle<Object> recv(js_frame->receiver(), this);
 | 
|      // Advance to the next JavaScript frame and determine if the
 | 
|      // current frame is the top-level frame.
 | 
|      it.Advance();
 | 
| @@ -1355,31 +1392,29 @@ void Isolate::PrintCurrentStackTrace(FILE* out) {
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -
 | 
|  bool Isolate::ComputeLocation(MessageLocation* target) {
 | 
|    StackTraceFrameIterator it(this);
 | 
| -  if (!it.done()) {
 | 
| -    StandardFrame* frame = it.frame();
 | 
| -    JSFunction* fun = frame->function();
 | 
| -    Object* script = fun->shared()->script();
 | 
| -    if (script->IsScript() &&
 | 
| -        !(Script::cast(script)->source()->IsUndefined())) {
 | 
| -      Handle<Script> casted_script(Script::cast(script));
 | 
| -      // Compute the location from the function and the relocation info of the
 | 
| -      // baseline code. For optimized code this will use the deoptimization
 | 
| -      // information to get canonical location information.
 | 
| -      List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
 | 
| -      frame->Summarize(&frames);
 | 
| -      FrameSummary& summary = frames.last();
 | 
| -      int pos = summary.abstract_code()->SourcePosition(summary.code_offset());
 | 
| -      *target = MessageLocation(casted_script, pos, pos + 1, handle(fun));
 | 
| -      return true;
 | 
| -    }
 | 
| +  if (it.done()) return false;
 | 
| +  StandardFrame* frame = it.frame();
 | 
| +  // TODO(clemensh): handle wasm frames
 | 
| +  if (!frame->is_java_script()) return false;
 | 
| +  JSFunction* fun = JavaScriptFrame::cast(frame)->function();
 | 
| +  Object* script = fun->shared()->script();
 | 
| +  if (!script->IsScript() || (Script::cast(script)->source()->IsUndefined())) {
 | 
| +    return false;
 | 
|    }
 | 
| -  return false;
 | 
| +  Handle<Script> casted_script(Script::cast(script));
 | 
| +  // Compute the location from the function and the relocation info of the
 | 
| +  // baseline code. For optimized code this will use the deoptimization
 | 
| +  // information to get canonical location information.
 | 
| +  List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
 | 
| +  JavaScriptFrame::cast(frame)->Summarize(&frames);
 | 
| +  FrameSummary& summary = frames.last();
 | 
| +  int pos = summary.abstract_code()->SourcePosition(summary.code_offset());
 | 
| +  *target = MessageLocation(casted_script, pos, pos + 1, handle(fun));
 | 
| +  return true;
 | 
|  }
 | 
|  
 | 
| -
 | 
|  bool Isolate::ComputeLocationFromException(MessageLocation* target,
 | 
|                                             Handle<Object> exception) {
 | 
|    if (!exception->IsJSObject()) return false;
 | 
| @@ -1420,8 +1455,12 @@ bool Isolate::ComputeLocationFromStackTrace(MessageLocation* target,
 | 
|    int elements_limit = Smi::cast(simple_stack_trace->length())->value();
 | 
|  
 | 
|    for (int i = 1; i < elements_limit; i += 4) {
 | 
| -    Handle<JSFunction> fun =
 | 
| -        handle(JSFunction::cast(elements->get(i + 1)), this);
 | 
| +    Handle<Object> fun_obj = handle(elements->get(i + 1), this);
 | 
| +    if (fun_obj->IsSmi()) {
 | 
| +      // TODO(clemensh): handle wasm frames
 | 
| +      return false;
 | 
| +    }
 | 
| +    Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj);
 | 
|      if (!fun->shared()->IsSubjectToDebugging()) continue;
 | 
|  
 | 
|      Object* script = fun->shared()->script();
 | 
| 
 |