// Copyright 2014 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/runtime/runtime-utils.h"

#include <stdlib.h>
#include <limits>

#include "src/accessors.h"
#include "src/arguments.h"
#include "src/debug/debug.h"
#include "src/elements.h"
#include "src/frames-inl.h"
#include "src/isolate-inl.h"
#include "src/messages.h"
#include "src/runtime/runtime.h"

namespace v8 {
namespace internal {


RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) {
  HandleScope scope(isolate);
  DCHECK_EQ(0, args.length());
  THROW_NEW_ERROR_RETURN_FAILURE(
      isolate, NewReferenceError(MessageTemplate::kUnsupportedSuper));
}


RUNTIME_FUNCTION(Runtime_ThrowConstructorNonCallableError) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
  Handle<Object> name(constructor->shared()->name(), isolate);
  THROW_NEW_ERROR_RETURN_FAILURE(
      isolate, NewTypeError(MessageTemplate::kConstructorNonCallable, name));
}


RUNTIME_FUNCTION(Runtime_ThrowStaticPrototypeError) {
  HandleScope scope(isolate);
  DCHECK_EQ(0, args.length());
  THROW_NEW_ERROR_RETURN_FAILURE(
      isolate, NewTypeError(MessageTemplate::kStaticPrototype));
}

RUNTIME_FUNCTION(Runtime_ThrowSuperAlreadyCalledError) {
  HandleScope scope(isolate);
  DCHECK_EQ(0, args.length());
  // Invalidate the hole check protector.
  if (isolate->IsHoleCheckProtectorIntact()) {
    isolate->InvalidateHoleCheckProtector();
  }
  THROW_NEW_ERROR_RETURN_FAILURE(
      isolate, NewReferenceError(MessageTemplate::kSuperAlreadyCalled));
}

RUNTIME_FUNCTION(Runtime_ThrowSuperNotCalled) {
  HandleScope scope(isolate);
  DCHECK_EQ(0, args.length());
  // Invalidate the hole check protector.
  if (isolate->IsHoleCheckProtectorIntact()) {
    isolate->InvalidateHoleCheckProtector();
  }
  THROW_NEW_ERROR_RETURN_FAILURE(
      isolate, NewReferenceError(MessageTemplate::kSuperNotCalled));
}

namespace {

Object* ThrowNotSuperConstructor(Isolate* isolate, Handle<Object> constructor,
                                 Handle<JSFunction> function) {
  Handle<Object> super_name;
  if (constructor->IsJSFunction()) {
    super_name = handle(Handle<JSFunction>::cast(constructor)->shared()->name(),
                        isolate);
  } else if (constructor->IsOddball()) {
    DCHECK(constructor->IsNull(isolate));
    super_name = isolate->factory()->null_string();
  } else {
    super_name = Object::NoSideEffectsToString(isolate, constructor);
  }
  // null constructor
  if (Handle<String>::cast(super_name)->length() == 0) {
    super_name = isolate->factory()->null_string();
  }
  Handle<Object> function_name(function->shared()->name(), isolate);
  // anonymous class
  if (Handle<String>::cast(function_name)->length() == 0) {
    THROW_NEW_ERROR_RETURN_FAILURE(
        isolate,
        NewTypeError(MessageTemplate::kNotSuperConstructorAnonymousClass,
                     super_name));
  }
  THROW_NEW_ERROR_RETURN_FAILURE(
      isolate, NewTypeError(MessageTemplate::kNotSuperConstructor, super_name,
                            function_name));
}

}  // namespace

RUNTIME_FUNCTION(Runtime_ThrowNotSuperConstructor) {
  HandleScope scope(isolate);
  DCHECK_EQ(2, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 1);
  return ThrowNotSuperConstructor(isolate, constructor, function);
}

RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) {
  DCHECK_EQ(0, args.length());
  return isolate->heap()->home_object_symbol();
}

static MaybeHandle<Object> DefineClass(Isolate* isolate,
                                       Handle<Object> super_class,
                                       Handle<JSFunction> constructor,
                                       int start_position, int end_position) {
  Handle<Object> prototype_parent;
  Handle<Object> constructor_parent;

  if (super_class->IsTheHole(isolate)) {
    prototype_parent = isolate->initial_object_prototype();
  } else {
    if (super_class->IsNull(isolate)) {
      prototype_parent = isolate->factory()->null_value();
    } else if (super_class->IsConstructor()) {
      DCHECK(!super_class->IsJSFunction() ||
             !IsResumableFunction(
                 Handle<JSFunction>::cast(super_class)->shared()->kind()));
      ASSIGN_RETURN_ON_EXCEPTION(
          isolate, prototype_parent,
          Runtime::GetObjectProperty(isolate, super_class,
                                     isolate->factory()->prototype_string()),
          Object);
      if (!prototype_parent->IsNull(isolate) &&
          !prototype_parent->IsJSReceiver()) {
        THROW_NEW_ERROR(
            isolate, NewTypeError(MessageTemplate::kPrototypeParentNotAnObject,
                                  prototype_parent),
            Object);
      }
      constructor_parent = super_class;
    } else {
      THROW_NEW_ERROR(isolate,
                      NewTypeError(MessageTemplate::kExtendsValueNotConstructor,
                                   super_class),
                      Object);
    }
  }

  Handle<Map> map =
      isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
  map->set_is_prototype_map(true);
  Map::SetPrototype(map, prototype_parent);
  map->SetConstructor(*constructor);
  Handle<JSObject> prototype = isolate->factory()->NewJSObjectFromMap(map);

  JSFunction::SetPrototype(constructor, prototype);
  PropertyAttributes attribs =
      static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
  RETURN_ON_EXCEPTION(isolate,
                      JSObject::SetOwnPropertyIgnoreAttributes(
                          constructor, isolate->factory()->prototype_string(),
                          prototype, attribs),
                      Object);

  if (!constructor_parent.is_null()) {
    MAYBE_RETURN_NULL(JSObject::SetPrototype(constructor, constructor_parent,
                                             false, Object::THROW_ON_ERROR));
  }

  JSObject::AddProperty(prototype, isolate->factory()->constructor_string(),
                        constructor, DONT_ENUM);

  // Install private properties that are used to construct the FunctionToString.
  RETURN_ON_EXCEPTION(
      isolate,
      Object::SetProperty(
          constructor, isolate->factory()->class_start_position_symbol(),
          handle(Smi::FromInt(start_position), isolate), STRICT),
      Object);
  RETURN_ON_EXCEPTION(
      isolate, Object::SetProperty(
                   constructor, isolate->factory()->class_end_position_symbol(),
                   handle(Smi::FromInt(end_position), isolate), STRICT),
      Object);

  // Caller already has access to constructor, so return the prototype.
  return prototype;
}


RUNTIME_FUNCTION(Runtime_DefineClass) {
  HandleScope scope(isolate);
  DCHECK_EQ(4, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 0);
  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 1);
  CONVERT_SMI_ARG_CHECKED(start_position, 2);
  CONVERT_SMI_ARG_CHECKED(end_position, 3);

  RETURN_RESULT_OR_FAILURE(
      isolate, DefineClass(isolate, super_class, constructor, start_position,
                           end_position));
}

namespace {
void InstallClassNameAccessor(Isolate* isolate, Handle<JSObject> object) {
  PropertyAttributes attrs =
      static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
  // Cannot fail since this should only be called when creating an object
  // literal.
  CHECK(!JSObject::SetAccessor(
             object, Accessors::FunctionNameInfo(object->GetIsolate(), attrs))
             .is_null());
}
}  // anonymous namespace

RUNTIME_FUNCTION(Runtime_InstallClassNameAccessor) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
  InstallClassNameAccessor(isolate, object);
  return *object;
}

RUNTIME_FUNCTION(Runtime_InstallClassNameAccessorWithCheck) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);

  // If a property named "name" is already defined, exit.
  Handle<Name> key = isolate->factory()->name_string();
  if (JSObject::HasRealNamedProperty(object, key).FromMaybe(false)) {
    return *object;
  }

  // Define the "name" accessor.
  InstallClassNameAccessor(isolate, object);
  return *object;
}

namespace {

enum class SuperMode { kLoad, kStore };

MaybeHandle<JSReceiver> GetSuperHolder(
    Isolate* isolate, Handle<Object> receiver, Handle<JSObject> home_object,
    SuperMode mode, MaybeHandle<Name> maybe_name, uint32_t index) {
  if (home_object->IsAccessCheckNeeded() &&
      !isolate->MayAccess(handle(isolate->context()), home_object)) {
    isolate->ReportFailedAccessCheck(home_object);
    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, JSReceiver);
  }

  PrototypeIterator iter(isolate, home_object);
  Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
  if (!proto->IsJSReceiver()) {
    MessageTemplate::Template message =
        mode == SuperMode::kLoad ? MessageTemplate::kNonObjectPropertyLoad
                                 : MessageTemplate::kNonObjectPropertyStore;
    Handle<Name> name;
    if (!maybe_name.ToHandle(&name)) {
      name = isolate->factory()->Uint32ToString(index);
    }
    THROW_NEW_ERROR(isolate, NewTypeError(message, name, proto), JSReceiver);
  }
  return Handle<JSReceiver>::cast(proto);
}

MaybeHandle<Object> LoadFromSuper(Isolate* isolate, Handle<Object> receiver,
                                  Handle<JSObject> home_object,
                                  Handle<Name> name) {
  Handle<JSReceiver> holder;
  ASSIGN_RETURN_ON_EXCEPTION(
      isolate, holder,
      GetSuperHolder(isolate, receiver, home_object, SuperMode::kLoad, name, 0),
      Object);
  LookupIterator it(receiver, name, holder);
  Handle<Object> result;
  ASSIGN_RETURN_ON_EXCEPTION(isolate, result, Object::GetProperty(&it), Object);
  return result;
}

MaybeHandle<Object> LoadElementFromSuper(Isolate* isolate,
                                         Handle<Object> receiver,
                                         Handle<JSObject> home_object,
                                         uint32_t index) {
  Handle<JSReceiver> holder;
  ASSIGN_RETURN_ON_EXCEPTION(
      isolate, holder,
      GetSuperHolder(isolate, receiver, home_object, SuperMode::kLoad,
                     MaybeHandle<Name>(), index),
      Object);
  LookupIterator it(isolate, receiver, index, holder);
  Handle<Object> result;
  ASSIGN_RETURN_ON_EXCEPTION(isolate, result, Object::GetProperty(&it), Object);
  return result;
}

}  // anonymous namespace

RUNTIME_FUNCTION(Runtime_LoadFromSuper) {
  HandleScope scope(isolate);
  DCHECK_EQ(3, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
  CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);

  RETURN_RESULT_OR_FAILURE(isolate,
                           LoadFromSuper(isolate, receiver, home_object, name));
}


RUNTIME_FUNCTION(Runtime_LoadKeyedFromSuper) {
  HandleScope scope(isolate);
  DCHECK_EQ(3, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
  CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);

  uint32_t index = 0;

  if (key->ToArrayIndex(&index)) {
    RETURN_RESULT_OR_FAILURE(
        isolate, LoadElementFromSuper(isolate, receiver, home_object, index));
  }

  Handle<Name> name;
  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
                                     Object::ToName(isolate, key));
  // TODO(verwaest): Unify using LookupIterator.
  if (name->AsArrayIndex(&index)) {
    RETURN_RESULT_OR_FAILURE(
        isolate, LoadElementFromSuper(isolate, receiver, home_object, index));
  }
  RETURN_RESULT_OR_FAILURE(isolate,
                           LoadFromSuper(isolate, receiver, home_object, name));
}

namespace {

MaybeHandle<Object> StoreToSuper(Isolate* isolate, Handle<JSObject> home_object,
                                 Handle<Object> receiver, Handle<Name> name,
                                 Handle<Object> value,
                                 LanguageMode language_mode) {
  Handle<JSReceiver> holder;
  ASSIGN_RETURN_ON_EXCEPTION(isolate, holder,
                             GetSuperHolder(isolate, receiver, home_object,
                                            SuperMode::kStore, name, 0),
                             Object);
  LookupIterator it(receiver, name, holder);
  MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode,
                                        Object::CERTAINLY_NOT_STORE_FROM_KEYED),
               MaybeHandle<Object>());
  return value;
}

MaybeHandle<Object> StoreElementToSuper(Isolate* isolate,
                                        Handle<JSObject> home_object,
                                        Handle<Object> receiver, uint32_t index,
                                        Handle<Object> value,
                                        LanguageMode language_mode) {
  Handle<JSReceiver> holder;
  ASSIGN_RETURN_ON_EXCEPTION(
      isolate, holder,
      GetSuperHolder(isolate, receiver, home_object, SuperMode::kStore,
                     MaybeHandle<Name>(), index),
      Object);
  LookupIterator it(isolate, receiver, index, holder);
  MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode,
                                        Object::MAY_BE_STORE_FROM_KEYED),
               MaybeHandle<Object>());
  return value;
}

}  // anonymous namespace

RUNTIME_FUNCTION(Runtime_StoreToSuper_Strict) {
  HandleScope scope(isolate);
  DCHECK_EQ(4, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
  CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
  CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);

  RETURN_RESULT_OR_FAILURE(isolate, StoreToSuper(isolate, home_object, receiver,
                                                 name, value, STRICT));
}


RUNTIME_FUNCTION(Runtime_StoreToSuper_Sloppy) {
  HandleScope scope(isolate);
  DCHECK_EQ(4, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
  CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
  CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);

  RETURN_RESULT_OR_FAILURE(isolate, StoreToSuper(isolate, home_object, receiver,
                                                 name, value, SLOPPY));
}

static MaybeHandle<Object> StoreKeyedToSuper(
    Isolate* isolate, Handle<JSObject> home_object, Handle<Object> receiver,
    Handle<Object> key, Handle<Object> value, LanguageMode language_mode) {
  uint32_t index = 0;

  if (key->ToArrayIndex(&index)) {
    return StoreElementToSuper(isolate, home_object, receiver, index, value,
                               language_mode);
  }
  Handle<Name> name;
  ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key),
                             Object);
  // TODO(verwaest): Unify using LookupIterator.
  if (name->AsArrayIndex(&index)) {
    return StoreElementToSuper(isolate, home_object, receiver, index, value,
                               language_mode);
  }
  return StoreToSuper(isolate, home_object, receiver, name, value,
                      language_mode);
}


RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Strict) {
  HandleScope scope(isolate);
  DCHECK_EQ(4, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
  CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
  CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);

  RETURN_RESULT_OR_FAILURE(
      isolate,
      StoreKeyedToSuper(isolate, home_object, receiver, key, value, STRICT));
}


RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Sloppy) {
  HandleScope scope(isolate);
  DCHECK_EQ(4, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
  CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
  CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);

  RETURN_RESULT_OR_FAILURE(
      isolate,
      StoreKeyedToSuper(isolate, home_object, receiver, key, value, SLOPPY));
}


RUNTIME_FUNCTION(Runtime_GetSuperConstructor) {
  SealHandleScope shs(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_ARG_CHECKED(JSFunction, active_function, 0);
  Object* prototype = active_function->map()->prototype();
  if (!prototype->IsConstructor()) {
    HandleScope scope(isolate);
    return ThrowNotSuperConstructor(isolate, handle(prototype, isolate),
                                    handle(active_function, isolate));
  }
  return prototype;
}

}  // namespace internal
}  // namespace v8
