// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


#include "v8.h"

#include "cctest.h"
#include "compiler.h"
#include "execution.h"
#include "isolate.h"


using namespace v8::internal;

static v8::Persistent<v8::Context> env;


void SetSeeds(Handle<ByteArray> seeds, uint32_t state0, uint32_t state1) {
  for (int i = 0; i < 4; i++) {
    seeds->set(i, static_cast<byte>(state0 >> (i * kBitsPerByte)));
    seeds->set(i + 4, static_cast<byte>(state1 >> (i * kBitsPerByte)));
  }
}


void TestSeeds(Handle<JSFunction> fun,
               Handle<Context> context,
               uint32_t state0,
               uint32_t state1) {
  bool has_pending_exception;
  Handle<JSObject> global(context->global_object());
  Handle<ByteArray> seeds(context->random_seed());

  SetSeeds(seeds, state0, state1);
  Handle<Object> value =
      Execution::Call(fun, global, 0, NULL, &has_pending_exception);
  CHECK(value->IsHeapNumber());
  CHECK(fun->IsOptimized());
  double crankshaft_value = HeapNumber::cast(*value)->value();

  SetSeeds(seeds, state0, state1);
  V8::FillHeapNumberWithRandom(*value, *context);
  double runtime_value = HeapNumber::cast(*value)->value();
  CHECK_EQ(runtime_value, crankshaft_value);
}


TEST(CrankshaftRandom) {
  if (env.IsEmpty()) env = v8::Context::New();
  // Skip test if crankshaft is disabled.
  if (!V8::UseCrankshaft()) return;
  v8::HandleScope scope(env->GetIsolate());
  env->Enter();

  Handle<Context> context(Isolate::Current()->context());
  Handle<JSObject> global(context->global_object());
  Handle<ByteArray> seeds(context->random_seed());
  bool has_pending_exception;

  CompileRun("function f() { return Math.random(); }");

  Object* string = FACTORY->InternalizeOneByteString(STATIC_ASCII_VECTOR("f"))->
      ToObjectChecked();
  MaybeObject* fun_object =
      context->global_object()->GetProperty(String::cast(string));
  Handle<JSFunction> fun(JSFunction::cast(fun_object->ToObjectChecked()));

  // Optimize function.
  Execution::Call(fun, global, 0, NULL, &has_pending_exception);
  Execution::Call(fun, global, 0, NULL, &has_pending_exception);
  if (!fun->IsOptimized()) fun->MarkForLazyRecompilation();

  // Test with some random values.
  TestSeeds(fun, context, 0xC0C0AFFE, 0x31415926);
  TestSeeds(fun, context, 0x01020304, 0xFFFFFFFF);
  TestSeeds(fun, context, 0x00000001, 0x00000000);

  // Test that we bail out to runtime when seeds are uninitialized (zeros).
  SetSeeds(seeds, 0, 0);
  Handle<Object> value =
      Execution::Call(fun, global, 0, NULL, &has_pending_exception);
  CHECK(value->IsHeapNumber());
  CHECK(fun->IsOptimized());
  double crankshaft_value = HeapNumber::cast(*value)->value();
  CHECK_NE(0.0, crankshaft_value);
}
