| Index: src/builtins/builtins-callsite.cc
 | 
| diff --git a/src/builtins/builtins-callsite.cc b/src/builtins/builtins-callsite.cc
 | 
| index c2cd22f09077781237370751406ccd930965ccd1..339c3f2475afb3594229310a7853252ff0fd690e 100644
 | 
| --- a/src/builtins/builtins-callsite.cc
 | 
| +++ b/src/builtins/builtins-callsite.cc
 | 
| @@ -22,65 +22,21 @@ namespace internal {
 | 
|                       isolate->factory()->NewStringFromAsciiChecked(method))); \
 | 
|    }
 | 
|  
 | 
| -#define SET_CALLSITE_PROPERTY(target, key, value)        \
 | 
| -  RETURN_FAILURE_ON_EXCEPTION(                           \
 | 
| -      isolate, JSObject::SetOwnPropertyIgnoreAttributes( \
 | 
| -                   target, isolate->factory()->key(), value, DONT_ENUM))
 | 
| -
 | 
|  BUILTIN(CallSiteConstructor) {
 | 
|    HandleScope scope(isolate);
 | 
| +
 | 
|    Handle<JSFunction> target = args.target<JSFunction>();
 | 
| -  Handle<HeapObject> new_target_obj = args.new_target();
 | 
| +  Handle<Object> new_target = Handle<Object>::cast(args.new_target());
 | 
|    Handle<Object> receiver = args.atOrUndefined(isolate, 1);
 | 
|    Handle<Object> fun = args.atOrUndefined(isolate, 2);
 | 
|    Handle<Object> pos = args.atOrUndefined(isolate, 3);
 | 
|    Handle<Object> strict_mode = args.atOrUndefined(isolate, 4);
 | 
|  
 | 
| -  // Create the JS object.
 | 
| -
 | 
| -  Handle<JSReceiver> new_target = new_target_obj->IsJSReceiver()
 | 
| -                                      ? Handle<JSReceiver>::cast(new_target_obj)
 | 
| -                                      : Handle<JSReceiver>::cast(target);
 | 
| -
 | 
| -  Handle<JSObject> obj;
 | 
| -  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, obj,
 | 
| -                                     JSObject::New(target, new_target));
 | 
| -
 | 
| -  // For wasm frames, receiver is the wasm object and fun is the function index
 | 
| -  // instead of an actual function.
 | 
| -  const bool is_wasm_object =
 | 
| -      receiver->IsJSObject() && wasm::IsWasmObject(JSObject::cast(*receiver));
 | 
| -  if (!fun->IsJSFunction() && !is_wasm_object) {
 | 
| -    THROW_NEW_ERROR_RETURN_FAILURE(
 | 
| -        isolate, NewTypeError(MessageTemplate::kCallSiteExpectsFunction,
 | 
| -                              Object::TypeOf(isolate, receiver),
 | 
| -                              Object::TypeOf(isolate, fun)));
 | 
| -  }
 | 
| -
 | 
| -  if (is_wasm_object) {
 | 
| -    DCHECK(fun->IsSmi());
 | 
| -    DCHECK(wasm::GetNumberOfFunctions(JSObject::cast(*receiver)) >
 | 
| -           Smi::cast(*fun)->value());
 | 
| -
 | 
| -    SET_CALLSITE_PROPERTY(obj, call_site_wasm_obj_symbol, receiver);
 | 
| -    SET_CALLSITE_PROPERTY(obj, call_site_wasm_func_index_symbol, fun);
 | 
| -  } else {
 | 
| -    DCHECK(fun->IsJSFunction());
 | 
| -    SET_CALLSITE_PROPERTY(obj, call_site_receiver_symbol, receiver);
 | 
| -    SET_CALLSITE_PROPERTY(obj, call_site_function_symbol, fun);
 | 
| -  }
 | 
| -
 | 
| -  DCHECK(pos->IsSmi());
 | 
| -  SET_CALLSITE_PROPERTY(obj, call_site_position_symbol, pos);
 | 
| -  SET_CALLSITE_PROPERTY(
 | 
| -      obj, call_site_strict_symbol,
 | 
| -      isolate->factory()->ToBoolean(strict_mode->BooleanValue()));
 | 
| -
 | 
| -  return *obj;
 | 
| +  RETURN_RESULT_OR_FAILURE(
 | 
| +      isolate, CallSiteUtils::Construct(isolate, target, new_target, receiver,
 | 
| +                                        fun, pos, strict_mode));
 | 
|  }
 | 
|  
 | 
| -#undef SET_CALLSITE_PROPERTY
 | 
| -
 | 
|  namespace {
 | 
|  
 | 
|  Object* PositiveNumberOrNull(int value, Isolate* isolate) {
 | 
| @@ -99,136 +55,13 @@ BUILTIN(CallSitePrototypeGetColumnNumber) {
 | 
|    return PositiveNumberOrNull(call_site.GetColumnNumber(), isolate);
 | 
|  }
 | 
|  
 | 
| -namespace {
 | 
| -
 | 
| -Object* EvalFromFunctionName(Isolate* isolate, Handle<Script> script) {
 | 
| -  if (script->eval_from_shared()->IsUndefined(isolate))
 | 
| -    return *isolate->factory()->undefined_value();
 | 
| -
 | 
| -  Handle<SharedFunctionInfo> shared(
 | 
| -      SharedFunctionInfo::cast(script->eval_from_shared()));
 | 
| -  // Find the name of the function calling eval.
 | 
| -  if (shared->name()->BooleanValue()) {
 | 
| -    return shared->name();
 | 
| -  }
 | 
| -
 | 
| -  return shared->inferred_name();
 | 
| -}
 | 
| -
 | 
| -Object* EvalFromScript(Isolate* isolate, Handle<Script> script) {
 | 
| -  if (script->eval_from_shared()->IsUndefined(isolate))
 | 
| -    return *isolate->factory()->undefined_value();
 | 
| -
 | 
| -  Handle<SharedFunctionInfo> eval_from_shared(
 | 
| -      SharedFunctionInfo::cast(script->eval_from_shared()));
 | 
| -  return eval_from_shared->script()->IsScript()
 | 
| -             ? eval_from_shared->script()
 | 
| -             : *isolate->factory()->undefined_value();
 | 
| -}
 | 
| -
 | 
| -MaybeHandle<String> FormatEvalOrigin(Isolate* isolate, Handle<Script> script) {
 | 
| -  Handle<Object> sourceURL = Script::GetNameOrSourceURL(script);
 | 
| -  if (!sourceURL->IsUndefined(isolate)) {
 | 
| -    DCHECK(sourceURL->IsString());
 | 
| -    return Handle<String>::cast(sourceURL);
 | 
| -  }
 | 
| -
 | 
| -  IncrementalStringBuilder builder(isolate);
 | 
| -  builder.AppendCString("eval at ");
 | 
| -
 | 
| -  Handle<Object> eval_from_function_name =
 | 
| -      handle(EvalFromFunctionName(isolate, script), isolate);
 | 
| -  if (eval_from_function_name->BooleanValue()) {
 | 
| -    Handle<String> str;
 | 
| -    ASSIGN_RETURN_ON_EXCEPTION(
 | 
| -        isolate, str, Object::ToString(isolate, eval_from_function_name),
 | 
| -        String);
 | 
| -    builder.AppendString(str);
 | 
| -  } else {
 | 
| -    builder.AppendCString("<anonymous>");
 | 
| -  }
 | 
| -
 | 
| -  Handle<Object> eval_from_script_obj =
 | 
| -      handle(EvalFromScript(isolate, script), isolate);
 | 
| -  if (eval_from_script_obj->IsScript()) {
 | 
| -    Handle<Script> eval_from_script =
 | 
| -        Handle<Script>::cast(eval_from_script_obj);
 | 
| -    builder.AppendCString(" (");
 | 
| -    if (eval_from_script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
 | 
| -      // Eval script originated from another eval.
 | 
| -      Handle<String> str;
 | 
| -      ASSIGN_RETURN_ON_EXCEPTION(
 | 
| -          isolate, str, FormatEvalOrigin(isolate, eval_from_script), String);
 | 
| -      builder.AppendString(str);
 | 
| -    } else {
 | 
| -      DCHECK(eval_from_script->compilation_type() !=
 | 
| -             Script::COMPILATION_TYPE_EVAL);
 | 
| -      // eval script originated from "real" source.
 | 
| -      Handle<Object> name_obj = handle(eval_from_script->name(), isolate);
 | 
| -      if (eval_from_script->name()->IsString()) {
 | 
| -        builder.AppendString(Handle<String>::cast(name_obj));
 | 
| -
 | 
| -        Script::PositionInfo info;
 | 
| -        if (eval_from_script->GetPositionInfo(script->GetEvalPosition(), &info,
 | 
| -                                              Script::NO_OFFSET)) {
 | 
| -          builder.AppendCString(":");
 | 
| -
 | 
| -          Handle<String> str = isolate->factory()->NumberToString(
 | 
| -              handle(Smi::FromInt(info.line + 1), isolate));
 | 
| -          builder.AppendString(str);
 | 
| -
 | 
| -          builder.AppendCString(":");
 | 
| -
 | 
| -          str = isolate->factory()->NumberToString(
 | 
| -              handle(Smi::FromInt(info.column + 1), isolate));
 | 
| -          builder.AppendString(str);
 | 
| -        }
 | 
| -      } else {
 | 
| -        DCHECK(!eval_from_script->name()->IsString());
 | 
| -        builder.AppendCString("unknown source");
 | 
| -      }
 | 
| -    }
 | 
| -    builder.AppendCString(")");
 | 
| -  }
 | 
| -
 | 
| -  Handle<String> result;
 | 
| -  ASSIGN_RETURN_ON_EXCEPTION(isolate, result, builder.Finish(), String);
 | 
| -  return result;
 | 
| -}
 | 
| -
 | 
| -MaybeHandle<Object> GetEvalOrigin(Isolate* isolate, Handle<JSObject> object) {
 | 
| -  CallSite call_site(isolate, object);
 | 
| -  if (call_site.IsWasm()) return isolate->factory()->undefined_value();
 | 
| -
 | 
| -  // Retrieve the function's script object.
 | 
| -
 | 
| -  Handle<Object> function_obj;
 | 
| -  Handle<Symbol> symbol = isolate->factory()->call_site_function_symbol();
 | 
| -  ASSIGN_RETURN_ON_EXCEPTION(isolate, function_obj,
 | 
| -                             JSObject::GetProperty(object, symbol), Object);
 | 
| -
 | 
| -  DCHECK(function_obj->IsJSFunction());
 | 
| -  Handle<JSFunction> function = Handle<JSFunction>::cast(function_obj);
 | 
| -  Handle<Object> script = handle(function->shared()->script(), isolate);
 | 
| -
 | 
| -  if (!script->IsScript()) {
 | 
| -    return isolate->factory()->undefined_value();
 | 
| -  }
 | 
| -
 | 
| -  Handle<String> str;
 | 
| -  ASSIGN_RETURN_ON_EXCEPTION(
 | 
| -      isolate, str, FormatEvalOrigin(isolate, Handle<Script>::cast(script)),
 | 
| -      String);
 | 
| -
 | 
| -  return str;
 | 
| -}
 | 
| -
 | 
| -}  // namespace
 | 
| -
 | 
|  BUILTIN(CallSitePrototypeGetEvalOrigin) {
 | 
|    HandleScope scope(isolate);
 | 
|    CHECK_CALLSITE(recv, "getEvalOrigin");
 | 
| -  RETURN_RESULT_OR_FAILURE(isolate, GetEvalOrigin(isolate, recv));
 | 
| +
 | 
| +  CallSite call_site(isolate, recv);
 | 
| +  CHECK(call_site.IsJavaScript() || call_site.IsWasm());
 | 
| +  return *call_site.GetEvalOrigin();
 | 
|  }
 | 
|  
 | 
|  BUILTIN(CallSitePrototypeGetFileName) {
 | 
| @@ -328,32 +161,13 @@ BUILTIN(CallSitePrototypeGetThis) {
 | 
|    return *receiver;
 | 
|  }
 | 
|  
 | 
| -namespace {
 | 
| -
 | 
| -MaybeHandle<Object> GetTypeName(Isolate* isolate, Handle<JSObject> object) {
 | 
| -  Handle<Object> receiver;
 | 
| -  Handle<Symbol> symbol = isolate->factory()->call_site_receiver_symbol();
 | 
| -  ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
 | 
| -                             JSObject::GetProperty(object, symbol), Object);
 | 
| -
 | 
| -  // TODO(jgruber): Check for strict/constructor here as above.
 | 
| -
 | 
| -  if (receiver->IsNull(isolate) || receiver->IsUndefined(isolate))
 | 
| -    return isolate->factory()->null_value();
 | 
| -
 | 
| -  if (receiver->IsJSProxy()) return isolate->factory()->Proxy_string();
 | 
| -
 | 
| -  Handle<JSReceiver> receiver_object =
 | 
| -      Object::ToObject(isolate, receiver).ToHandleChecked();
 | 
| -  return JSReceiver::GetConstructorName(receiver_object);
 | 
| -}
 | 
| -
 | 
| -}  // namespace
 | 
| -
 | 
|  BUILTIN(CallSitePrototypeGetTypeName) {
 | 
|    HandleScope scope(isolate);
 | 
|    CHECK_CALLSITE(recv, "getTypeName");
 | 
| -  RETURN_RESULT_OR_FAILURE(isolate, GetTypeName(isolate, recv));
 | 
| +
 | 
| +  CallSite call_site(isolate, recv);
 | 
| +  CHECK(call_site.IsJavaScript() || call_site.IsWasm());
 | 
| +  return *call_site.GetTypeName();
 | 
|  }
 | 
|  
 | 
|  BUILTIN(CallSitePrototypeIsConstructor) {
 | 
| @@ -392,217 +206,10 @@ BUILTIN(CallSitePrototypeIsToplevel) {
 | 
|    return isolate->heap()->ToBoolean(call_site.IsToplevel());
 | 
|  }
 | 
|  
 | 
| -namespace {
 | 
| -
 | 
| -bool IsNonEmptyString(Handle<Object> object) {
 | 
| -  return (object->IsString() && String::cast(*object)->length() > 0);
 | 
| -}
 | 
| -
 | 
| -MaybeHandle<JSObject> AppendWasmToString(Isolate* isolate,
 | 
| -                                         Handle<JSObject> recv,
 | 
| -                                         CallSite* call_site,
 | 
| -                                         IncrementalStringBuilder* builder) {
 | 
| -  Handle<Object> name = call_site->GetFunctionName();
 | 
| -  if (name->IsNull(isolate)) {
 | 
| -    builder->AppendCString("<WASM UNNAMED>");
 | 
| -  } else {
 | 
| -    DCHECK(name->IsString());
 | 
| -    builder->AppendString(Handle<String>::cast(name));
 | 
| -  }
 | 
| -
 | 
| -  builder->AppendCString(" (<WASM>[");
 | 
| -
 | 
| -  Handle<String> ix = isolate->factory()->NumberToString(
 | 
| -      handle(Smi::FromInt(call_site->wasm_func_index()), isolate));
 | 
| -  builder->AppendString(ix);
 | 
| -
 | 
| -  builder->AppendCString("]+");
 | 
| -
 | 
| -  Handle<Object> pos;
 | 
| -  ASSIGN_RETURN_ON_EXCEPTION(
 | 
| -      isolate, pos, JSObject::GetProperty(
 | 
| -                        recv, isolate->factory()->call_site_position_symbol()),
 | 
| -      JSObject);
 | 
| -  DCHECK(pos->IsNumber());
 | 
| -  builder->AppendString(isolate->factory()->NumberToString(pos));
 | 
| -  builder->AppendCString(")");
 | 
| -
 | 
| -  return recv;
 | 
| -}
 | 
| -
 | 
| -MaybeHandle<JSObject> AppendFileLocation(Isolate* isolate,
 | 
| -                                         Handle<JSObject> recv,
 | 
| -                                         CallSite* call_site,
 | 
| -                                         IncrementalStringBuilder* builder) {
 | 
| -  if (call_site->IsNative()) {
 | 
| -    builder->AppendCString("native");
 | 
| -    return recv;
 | 
| -  }
 | 
| -
 | 
| -  Handle<Object> file_name = call_site->GetScriptNameOrSourceUrl();
 | 
| -  if (!file_name->IsString() && call_site->IsEval()) {
 | 
| -    Handle<Object> eval_origin;
 | 
| -    ASSIGN_RETURN_ON_EXCEPTION(isolate, eval_origin,
 | 
| -                               GetEvalOrigin(isolate, recv), JSObject);
 | 
| -    DCHECK(eval_origin->IsString());
 | 
| -    builder->AppendString(Handle<String>::cast(eval_origin));
 | 
| -    builder->AppendCString(", ");  // Expecting source position to follow.
 | 
| -  }
 | 
| -
 | 
| -  if (IsNonEmptyString(file_name)) {
 | 
| -    builder->AppendString(Handle<String>::cast(file_name));
 | 
| -  } else {
 | 
| -    // Source code does not originate from a file and is not native, but we
 | 
| -    // can still get the source position inside the source string, e.g. in
 | 
| -    // an eval string.
 | 
| -    builder->AppendCString("<anonymous>");
 | 
| -  }
 | 
| -
 | 
| -  int line_number = call_site->GetLineNumber();
 | 
| -  if (line_number != -1) {
 | 
| -    builder->AppendCharacter(':');
 | 
| -    Handle<String> line_string = isolate->factory()->NumberToString(
 | 
| -        handle(Smi::FromInt(line_number), isolate), isolate);
 | 
| -    builder->AppendString(line_string);
 | 
| -
 | 
| -    int column_number = call_site->GetColumnNumber();
 | 
| -    if (column_number != -1) {
 | 
| -      builder->AppendCharacter(':');
 | 
| -      Handle<String> column_string = isolate->factory()->NumberToString(
 | 
| -          handle(Smi::FromInt(column_number), isolate), isolate);
 | 
| -      builder->AppendString(column_string);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  return recv;
 | 
| -}
 | 
| -
 | 
| -int StringIndexOf(Isolate* isolate, Handle<String> subject,
 | 
| -                  Handle<String> pattern) {
 | 
| -  if (pattern->length() > subject->length()) return -1;
 | 
| -  return String::IndexOf(isolate, subject, pattern, 0);
 | 
| -}
 | 
| -
 | 
| -// Returns true iff
 | 
| -// 1. the subject ends with '.' + pattern, or
 | 
| -// 2. subject == pattern.
 | 
| -bool StringEndsWithMethodName(Isolate* isolate, Handle<String> subject,
 | 
| -                              Handle<String> pattern) {
 | 
| -  if (String::Equals(subject, pattern)) return true;
 | 
| -
 | 
| -  FlatStringReader subject_reader(isolate, String::Flatten(subject));
 | 
| -  FlatStringReader pattern_reader(isolate, String::Flatten(pattern));
 | 
| -
 | 
| -  int pattern_index = pattern_reader.length() - 1;
 | 
| -  int subject_index = subject_reader.length() - 1;
 | 
| -  for (int i = 0; i <= pattern_reader.length(); i++) {  // Iterate over len + 1.
 | 
| -    if (subject_index < 0) {
 | 
| -      return false;
 | 
| -    }
 | 
| -
 | 
| -    const uc32 subject_char = subject_reader.Get(subject_index);
 | 
| -    if (i == pattern_reader.length()) {
 | 
| -      if (subject_char != '.') return false;
 | 
| -    } else if (subject_char != pattern_reader.Get(pattern_index)) {
 | 
| -      return false;
 | 
| -    }
 | 
| -
 | 
| -    pattern_index--;
 | 
| -    subject_index--;
 | 
| -  }
 | 
| -
 | 
| -  return true;
 | 
| -}
 | 
| -
 | 
| -MaybeHandle<JSObject> AppendMethodCall(Isolate* isolate, Handle<JSObject> recv,
 | 
| -                                       CallSite* call_site,
 | 
| -                                       IncrementalStringBuilder* builder) {
 | 
| -  Handle<Object> type_name;
 | 
| -  ASSIGN_RETURN_ON_EXCEPTION(isolate, type_name, GetTypeName(isolate, recv),
 | 
| -                             JSObject);
 | 
| -  Handle<Object> method_name = call_site->GetMethodName();
 | 
| -  Handle<Object> function_name = call_site->GetFunctionName();
 | 
| -
 | 
| -  if (IsNonEmptyString(function_name)) {
 | 
| -    Handle<String> function_string = Handle<String>::cast(function_name);
 | 
| -    if (type_name->IsString()) {
 | 
| -      Handle<String> type_string = Handle<String>::cast(type_name);
 | 
| -      bool starts_with_type_name =
 | 
| -          (StringIndexOf(isolate, function_string, type_string) == 0);
 | 
| -      if (!starts_with_type_name) {
 | 
| -        builder->AppendString(type_string);
 | 
| -        builder->AppendCharacter('.');
 | 
| -      }
 | 
| -    }
 | 
| -    builder->AppendString(function_string);
 | 
| -
 | 
| -    if (IsNonEmptyString(method_name)) {
 | 
| -      Handle<String> method_string = Handle<String>::cast(method_name);
 | 
| -      if (!StringEndsWithMethodName(isolate, function_string, method_string)) {
 | 
| -        builder->AppendCString(" [as ");
 | 
| -        builder->AppendString(method_string);
 | 
| -        builder->AppendCharacter(']');
 | 
| -      }
 | 
| -    }
 | 
| -  } else {
 | 
| -    builder->AppendString(Handle<String>::cast(type_name));
 | 
| -    builder->AppendCharacter('.');
 | 
| -    if (IsNonEmptyString(method_name)) {
 | 
| -      builder->AppendString(Handle<String>::cast(method_name));
 | 
| -    } else {
 | 
| -      builder->AppendCString("<anonymous>");
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  return recv;
 | 
| -}
 | 
| -
 | 
| -}  // namespace
 | 
| -
 | 
|  BUILTIN(CallSitePrototypeToString) {
 | 
|    HandleScope scope(isolate);
 | 
|    CHECK_CALLSITE(recv, "toString");
 | 
| -
 | 
| -  IncrementalStringBuilder builder(isolate);
 | 
| -
 | 
| -  CallSite call_site(isolate, recv);
 | 
| -  if (call_site.IsWasm()) {
 | 
| -    RETURN_FAILURE_ON_EXCEPTION(
 | 
| -        isolate, AppendWasmToString(isolate, recv, &call_site, &builder));
 | 
| -    RETURN_RESULT_OR_FAILURE(isolate, builder.Finish());
 | 
| -  }
 | 
| -
 | 
| -  DCHECK(!call_site.IsWasm());
 | 
| -  Handle<Object> function_name = call_site.GetFunctionName();
 | 
| -
 | 
| -  const bool is_toplevel = call_site.IsToplevel();
 | 
| -  const bool is_constructor = call_site.IsConstructor();
 | 
| -  const bool is_method_call = !(is_toplevel || is_constructor);
 | 
| -
 | 
| -  if (is_method_call) {
 | 
| -    RETURN_FAILURE_ON_EXCEPTION(
 | 
| -        isolate, AppendMethodCall(isolate, recv, &call_site, &builder));
 | 
| -  } else if (is_constructor) {
 | 
| -    builder.AppendCString("new ");
 | 
| -    if (IsNonEmptyString(function_name)) {
 | 
| -      builder.AppendString(Handle<String>::cast(function_name));
 | 
| -    } else {
 | 
| -      builder.AppendCString("<anonymous>");
 | 
| -    }
 | 
| -  } else if (IsNonEmptyString(function_name)) {
 | 
| -    builder.AppendString(Handle<String>::cast(function_name));
 | 
| -  } else {
 | 
| -    RETURN_FAILURE_ON_EXCEPTION(
 | 
| -        isolate, AppendFileLocation(isolate, recv, &call_site, &builder));
 | 
| -    RETURN_RESULT_OR_FAILURE(isolate, builder.Finish());
 | 
| -  }
 | 
| -
 | 
| -  builder.AppendCString(" (");
 | 
| -  RETURN_FAILURE_ON_EXCEPTION(
 | 
| -      isolate, AppendFileLocation(isolate, recv, &call_site, &builder));
 | 
| -  builder.AppendCString(")");
 | 
| -
 | 
| -  RETURN_RESULT_OR_FAILURE(isolate, builder.Finish());
 | 
| +  RETURN_RESULT_OR_FAILURE(isolate, CallSiteUtils::ToString(isolate, recv));
 | 
|  }
 | 
|  
 | 
|  #undef CHECK_CALLSITE
 | 
| 
 |