// 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.

#include "src/builtins/builtins-utils-inl.h"
#include "src/builtins/builtins.h"
#include "src/heap/heap-inl.h"  // For ToBoolean.
#include "src/logging/counters.h"
#include "src/objects/objects-inl.h"
#include "src/objects/stack-frame-info-inl.h"

namespace v8 {
namespace internal {

#define CHECK_CALLSITE(frame, method)                                         \
  CHECK_RECEIVER(JSObject, receiver, method);                                 \
  LookupIterator it(isolate, receiver,                                        \
                    isolate->factory()->call_site_frame_info_symbol(),        \
                    LookupIterator::OWN_SKIP_INTERCEPTOR);                    \
  if (it.state() != LookupIterator::DATA) {                                   \
    THROW_NEW_ERROR_RETURN_FAILURE(                                           \
        isolate,                                                              \
        NewTypeError(MessageTemplate::kCallSiteMethod,                        \
                     isolate->factory()->NewStringFromAsciiChecked(method))); \
  }                                                                           \
  Handle<StackFrameInfo> frame = Handle<StackFrameInfo>::cast(it.GetDataValue())
namespace {

Object PositiveNumberOrNull(int value, Isolate* isolate) {
  if (value > 0) return *isolate->factory()->NewNumberFromInt(value);
  return ReadOnlyRoots(isolate).null_value();
}

}  // namespace

BUILTIN(CallSitePrototypeGetColumnNumber) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "getColumnNumber");
  return PositiveNumberOrNull(StackFrameInfo::GetColumnNumber(frame), isolate);
}

BUILTIN(CallSitePrototypeGetEnclosingColumnNumber) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "getEnclosingColumnNumber");
  return PositiveNumberOrNull(StackFrameInfo::GetEnclosingColumnNumber(frame),
                              isolate);
}

BUILTIN(CallSitePrototypeGetEnclosingLineNumber) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "getEnclosingLineNumber");
  return PositiveNumberOrNull(StackFrameInfo::GetEnclosingLineNumber(frame),
                              isolate);
}

BUILTIN(CallSitePrototypeGetEvalOrigin) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "getEvalOrigin");
  return *StackFrameInfo::GetEvalOrigin(frame);
}

BUILTIN(CallSitePrototypeGetFileName) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "getFileName");
  return frame->GetScriptName();
}

BUILTIN(CallSitePrototypeGetFunction) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "getFunction");
  if (frame->IsStrict() ||
      (frame->function().IsJSFunction() &&
       JSFunction::cast(frame->function()).shared().is_toplevel())) {
    return ReadOnlyRoots(isolate).undefined_value();
  }
  isolate->CountUsage(v8::Isolate::kCallSiteAPIGetFunctionSloppyCall);
  return frame->function();
}

BUILTIN(CallSitePrototypeGetFunctionName) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "getFunctionName");
  return *StackFrameInfo::GetFunctionName(frame);
}

BUILTIN(CallSitePrototypeGetLineNumber) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "getLineNumber");
  return PositiveNumberOrNull(StackFrameInfo::GetLineNumber(frame), isolate);
}

BUILTIN(CallSitePrototypeGetMethodName) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "getMethodName");
  return *StackFrameInfo::GetMethodName(frame);
}

BUILTIN(CallSitePrototypeGetPosition) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "getPosition");
  return Smi::FromInt(StackFrameInfo::GetSourcePosition(frame));
}

BUILTIN(CallSitePrototypeGetPromiseIndex) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "getPromiseIndex");
  if (!frame->IsPromiseAll() && !frame->IsPromiseAny()) {
    return ReadOnlyRoots(isolate).null_value();
  }
  return Smi::FromInt(StackFrameInfo::GetSourcePosition(frame));
}

BUILTIN(CallSitePrototypeGetScriptNameOrSourceURL) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "getScriptNameOrSourceUrl");
  return frame->GetScriptNameOrSourceURL();
}

BUILTIN(CallSitePrototypeGetThis) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "getThis");
  if (frame->IsStrict()) return ReadOnlyRoots(isolate).undefined_value();
  isolate->CountUsage(v8::Isolate::kCallSiteAPIGetThisSloppyCall);
#if V8_ENABLE_WEBASSEMBLY
  if (frame->IsAsmJsWasm()) {
    return frame->GetWasmInstance().native_context().global_proxy();
  }
#endif  // V8_ENABLE_WEBASSEMBLY
  return frame->receiver_or_instance();
}

BUILTIN(CallSitePrototypeGetTypeName) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "getTypeName");
  return *StackFrameInfo::GetTypeName(frame);
}

BUILTIN(CallSitePrototypeIsAsync) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "isAsync");
  return isolate->heap()->ToBoolean(frame->IsAsync());
}

BUILTIN(CallSitePrototypeIsConstructor) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "isConstructor");
  return isolate->heap()->ToBoolean(frame->IsConstructor());
}

BUILTIN(CallSitePrototypeIsEval) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "isEval");
  return isolate->heap()->ToBoolean(frame->IsEval());
}

BUILTIN(CallSitePrototypeIsNative) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "isNative");
  return isolate->heap()->ToBoolean(frame->IsNative());
}

BUILTIN(CallSitePrototypeIsPromiseAll) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "isPromiseAll");
  return isolate->heap()->ToBoolean(frame->IsPromiseAll());
}

BUILTIN(CallSitePrototypeIsToplevel) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "isToplevel");
  return isolate->heap()->ToBoolean(frame->IsToplevel());
}

BUILTIN(CallSitePrototypeToString) {
  HandleScope scope(isolate);
  CHECK_CALLSITE(frame, "toString");
  RETURN_RESULT_OR_FAILURE(isolate, SerializeStackFrameInfo(isolate, frame));
}

#undef CHECK_CALLSITE

}  // namespace internal
}  // namespace v8
