Commit 381616fb authored by yangguo@chromium.org's avatar yangguo@chromium.org

Split even more runtime functions into separate files.

R=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/612023002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24307 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent aee775a5
......@@ -827,7 +827,11 @@ source_set("v8_base") {
"src/runtime/runtime-collections.cc",
"src/runtime/runtime-compiler.cc",
"src/runtime/runtime-i18n.cc",
"src/runtime/runtime-date.cc",
"src/runtime/runtime-debug.cc",
"src/runtime/runtime-generator.cc",
"src/runtime/runtime-json.cc",
"src/runtime/runtime-liveedit.cc",
"src/runtime/runtime-maths.cc",
"src/runtime/runtime-numbers.cc",
"src/runtime/runtime-regexp.cc",
......
......@@ -454,6 +454,10 @@ class Debug {
// Record function from which eval was called.
static void RecordEvalCaller(Handle<Script> script);
bool CheckExecutionState(int id) {
return !debug_context().is_null() && break_id() != 0 && break_id() == id;
}
// Flags and states.
DebugScope* debugger_entry() { return thread_local_.current_debug_scope_; }
inline Handle<Context> debug_context() { return debug_context_; }
......
......@@ -1121,6 +1121,19 @@ MaybeHandle<Object> Object::GetElement(Isolate* isolate,
}
Handle<Object> Object::GetPrototypeSkipHiddenPrototypes(
Isolate* isolate, Handle<Object> receiver) {
PrototypeIterator iter(isolate, receiver);
while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
return PrototypeIterator::GetCurrent(iter);
}
iter.Advance();
}
return PrototypeIterator::GetCurrent(iter);
}
MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> object,
Handle<Name> name) {
uint32_t index;
......
......@@ -1167,6 +1167,9 @@ class Object {
Handle<Object> receiver,
uint32_t index);
static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
Isolate* isolate, Handle<Object> receiver);
// Returns the permanent hash code associated with this object. May return
// undefined if not yet created.
Object* GetHash();
......
......@@ -9,12 +9,10 @@
#include "src/deoptimizer.h"
#include "src/frames.h"
#include "src/full-codegen.h"
#include "src/isolate.h"
#include "src/isolate-inl.h"
#include "src/runtime/runtime.h"
#include "src/runtime/runtime-utils.h"
#include "src/v8threads.h"
#include "src/vm-state.h"
#include "src/vm-state-inl.h"
namespace v8 {
......
// 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/v8.h"
#include "src/arguments.h"
#include "src/date.h"
#include "src/dateparser-inl.h"
#include "src/runtime/runtime.h"
#include "src/runtime/runtime-utils.h"
namespace v8 {
namespace internal {
RUNTIME_FUNCTION(Runtime_DateMakeDay) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(year, 0);
CONVERT_SMI_ARG_CHECKED(month, 1);
int days = isolate->date_cache()->DaysFromYearMonth(year, month);
RUNTIME_ASSERT(Smi::IsValid(days));
return Smi::FromInt(days);
}
RUNTIME_FUNCTION(Runtime_DateSetValue) {
HandleScope scope(isolate);
DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
CONVERT_DOUBLE_ARG_CHECKED(time, 1);
CONVERT_SMI_ARG_CHECKED(is_utc, 2);
DateCache* date_cache = isolate->date_cache();
Handle<Object> value;
;
bool is_value_nan = false;
if (std::isnan(time)) {
value = isolate->factory()->nan_value();
is_value_nan = true;
} else if (!is_utc && (time < -DateCache::kMaxTimeBeforeUTCInMs ||
time > DateCache::kMaxTimeBeforeUTCInMs)) {
value = isolate->factory()->nan_value();
is_value_nan = true;
} else {
time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
if (time < -DateCache::kMaxTimeInMs || time > DateCache::kMaxTimeInMs) {
value = isolate->factory()->nan_value();
is_value_nan = true;
} else {
value = isolate->factory()->NewNumber(DoubleToInteger(time));
}
}
date->SetValue(*value, is_value_nan);
return *value;
}
RUNTIME_FUNCTION(Runtime_ThrowNotDateError) {
HandleScope scope(isolate);
DCHECK(args.length() == 0);
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError("not_date_object", HandleVector<Object>(NULL, 0)));
}
RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
HandleScope scope(isolate);
DCHECK(args.length() == 0);
if (FLAG_log_timer_events) LOG(isolate, CurrentTimeEvent());
// According to ECMA-262, section 15.9.1, page 117, the precision of
// the number in a Date object representing a particular instant in
// time is milliseconds. Therefore, we floor the result of getting
// the OS time.
double millis;
if (FLAG_verify_predictable) {
millis = 1388534400000.0; // Jan 1 2014 00:00:00 GMT+0000
millis += Floor(isolate->heap()->synthetic_time());
} else {
millis = Floor(base::OS::TimeCurrentMillis());
}
return *isolate->factory()->NewNumber(millis);
}
RUNTIME_FUNCTION(Runtime_DateParseString) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
RUNTIME_ASSERT(output->HasFastElements());
JSObject::EnsureCanContainHeapObjectElements(output);
RUNTIME_ASSERT(output->HasFastObjectElements());
Handle<FixedArray> output_array(FixedArray::cast(output->elements()));
RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
str = String::Flatten(str);
DisallowHeapAllocation no_gc;
bool result;
String::FlatContent str_content = str->GetFlatContent();
if (str_content.IsOneByte()) {
result = DateParser::Parse(str_content.ToOneByteVector(), *output_array,
isolate->unicode_cache());
} else {
DCHECK(str_content.IsTwoByte());
result = DateParser::Parse(str_content.ToUC16Vector(), *output_array,
isolate->unicode_cache());
}
if (result) {
return *output;
} else {
return isolate->heap()->null_value();
}
}
RUNTIME_FUNCTION(Runtime_DateLocalTimezone) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
x <= DateCache::kMaxTimeBeforeUTCInMs);
const char* zone =
isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
Handle<String> result =
isolate->factory()->NewStringFromUtf8(CStrVector(zone)).ToHandleChecked();
return *result;
}
RUNTIME_FUNCTION(Runtime_DateToUTC) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
x <= DateCache::kMaxTimeBeforeUTCInMs);
int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
return *isolate->factory()->NewNumber(static_cast<double>(time));
}
RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
HandleScope hs(isolate);
DCHECK(args.length() == 0);
if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
Handle<FixedArray> date_cache_version =
isolate->factory()->NewFixedArray(1, TENURED);
date_cache_version->set(0, Smi::FromInt(0));
isolate->eternal_handles()->CreateSingleton(
isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
}
Handle<FixedArray> date_cache_version =
Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
EternalHandles::DATE_CACHE_VERSION));
// Return result as a JS array.
Handle<JSObject> result =
isolate->factory()->NewJSObject(isolate->array_function());
JSArray::SetContent(Handle<JSArray>::cast(result), date_cache_version);
return *result;
}
RUNTIME_FUNCTION(RuntimeReference_DateField) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 2);
CONVERT_ARG_CHECKED(Object, obj, 0);
CONVERT_SMI_ARG_CHECKED(index, 1);
if (!obj->IsJSDate()) {
HandleScope scope(isolate);
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
NewTypeError("not_date_object", HandleVector<Object>(NULL, 0)));
}
JSDate* date = JSDate::cast(obj);
if (index == 0) return date->value();
return JSDate::GetField(date, Smi::FromInt(index));
}
}
} // namespace v8::internal
This diff is collapsed.
// 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/v8.h"
#include "src/arguments.h"
#include "src/frames-inl.h"
#include "src/runtime/runtime.h"
#include "src/runtime/runtime-utils.h"
namespace v8 {
namespace internal {
RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
HandleScope scope(isolate);
DCHECK(args.length() == 0);
JavaScriptFrameIterator it(isolate);
JavaScriptFrame* frame = it.frame();
Handle<JSFunction> function(frame->function());
RUNTIME_ASSERT(function->shared()->is_generator());
Handle<JSGeneratorObject> generator;
if (frame->IsConstructor()) {
generator = handle(JSGeneratorObject::cast(frame->receiver()));
} else {
generator = isolate->factory()->NewJSGeneratorObject(function);
}
generator->set_function(*function);
generator->set_context(Context::cast(frame->context()));
generator->set_receiver(frame->receiver());
generator->set_continuation(0);
generator->set_operand_stack(isolate->heap()->empty_fixed_array());
generator->set_stack_handler_index(-1);
return *generator;
}
RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) {
HandleScope handle_scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
JavaScriptFrameIterator stack_iterator(isolate);
JavaScriptFrame* frame = stack_iterator.frame();
RUNTIME_ASSERT(frame->function()->shared()->is_generator());
DCHECK_EQ(frame->function(), generator_object->function());
// The caller should have saved the context and continuation already.
DCHECK_EQ(generator_object->context(), Context::cast(frame->context()));
DCHECK_LT(0, generator_object->continuation());
// We expect there to be at least two values on the operand stack: the return
// value of the yield expression, and the argument to this runtime call.
// Neither of those should be saved.
int operands_count = frame->ComputeOperandsCount();
DCHECK_GE(operands_count, 2);
operands_count -= 2;
if (operands_count == 0) {
// Although it's semantically harmless to call this function with an
// operands_count of zero, it is also unnecessary.
DCHECK_EQ(generator_object->operand_stack(),
isolate->heap()->empty_fixed_array());
DCHECK_EQ(generator_object->stack_handler_index(), -1);
// If there are no operands on the stack, there shouldn't be a handler
// active either.
DCHECK(!frame->HasHandler());
} else {
int stack_handler_index = -1;
Handle<FixedArray> operand_stack =
isolate->factory()->NewFixedArray(operands_count);
frame->SaveOperandStack(*operand_stack, &stack_handler_index);
generator_object->set_operand_stack(*operand_stack);
generator_object->set_stack_handler_index(stack_handler_index);
}
return isolate->heap()->undefined_value();
}
// Note that this function is the slow path for resuming generators. It is only
// called if the suspended activation had operands on the stack, stack handlers
// needing rewinding, or if the resume should throw an exception. The fast path
// is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
// inlined into GeneratorNext and GeneratorThrow. EmitGeneratorResumeResume is
// called in any case, as it needs to reconstruct the stack frame and make space
// for arguments and operands.
RUNTIME_FUNCTION(Runtime_ResumeJSGeneratorObject) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 3);
CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
CONVERT_ARG_CHECKED(Object, value, 1);
CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
JavaScriptFrameIterator stack_iterator(isolate);
JavaScriptFrame* frame = stack_iterator.frame();
DCHECK_EQ(frame->function(), generator_object->function());
DCHECK(frame->function()->is_compiled());
STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
Address pc = generator_object->function()->code()->instruction_start();
int offset = generator_object->continuation();
DCHECK(offset > 0);
frame->set_pc(pc + offset);
if (FLAG_enable_ool_constant_pool) {
frame->set_constant_pool(
generator_object->function()->code()->constant_pool());
}
generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
FixedArray* operand_stack = generator_object->operand_stack();
int operands_count = operand_stack->length();
if (operands_count != 0) {
frame->RestoreOperandStack(operand_stack,
generator_object->stack_handler_index());
generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
generator_object->set_stack_handler_index(-1);
}
JSGeneratorObject::ResumeMode resume_mode =
static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
switch (resume_mode) {
case JSGeneratorObject::NEXT:
return value;
case JSGeneratorObject::THROW:
return isolate->Throw(value);
}
UNREACHABLE();
return isolate->ThrowIllegalOperation();
}
RUNTIME_FUNCTION(Runtime_ThrowGeneratorStateError) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
int continuation = generator->continuation();
const char* message = continuation == JSGeneratorObject::kGeneratorClosed
? "generator_finished"
: "generator_running";
Vector<Handle<Object> > argv = HandleVector<Object>(NULL, 0);
THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewError(message, argv));
}
// Returns function of generator activation.
RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
return generator->function();
}
// Returns context of generator activation.
RUNTIME_FUNCTION(Runtime_GeneratorGetContext) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
return generator->context();
}
// Returns receiver of generator activation.
RUNTIME_FUNCTION(Runtime_GeneratorGetReceiver) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
return generator->receiver();
}
// Returns generator continuation as a PC offset, or the magic -1 or 0 values.
RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
return Smi::FromInt(generator->continuation());
}
RUNTIME_FUNCTION(Runtime_GeneratorGetSourcePosition) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
if (generator->is_suspended()) {
Handle<Code> code(generator->function()->code(), isolate);
int offset = generator->continuation();
RUNTIME_ASSERT(0 <= offset && offset < code->Size());
Address pc = code->address() + offset;
return Smi::FromInt(code->SourcePosition(pc));
}
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_FunctionIsGenerator) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
return isolate->heap()->ToBoolean(f->shared()->is_generator());
}
RUNTIME_FUNCTION(RuntimeReference_GeneratorNext) {
UNREACHABLE(); // Optimization disabled in SetUpGenerators().
return NULL;
}
RUNTIME_FUNCTION(RuntimeReference_GeneratorThrow) {
UNREACHABLE(); // Optimization disabled in SetUpGenerators().
return NULL;
}
}
} // namespace v8::internal
This diff is collapsed.
......@@ -292,6 +292,61 @@ RUNTIME_FUNCTION(Runtime_AbortJS) {
}
// Returns V8 version as a string.
RUNTIME_FUNCTION(Runtime_GetV8Version) {
HandleScope scope(isolate);
DCHECK(args.length() == 0);
const char* version_string = v8::V8::GetVersion();
return *isolate->factory()->NewStringFromAsciiChecked(version_string);
}
#ifdef DEBUG
// ListNatives is ONLY used by the fuzz-natives.js in debug mode
// Exclude the code in release mode.
RUNTIME_FUNCTION(Runtime_ListNatives) {
HandleScope scope(isolate);
DCHECK(args.length() == 0);
#define COUNT_ENTRY(Name, argc, ressize) +1
int entry_count =
0 RUNTIME_FUNCTION_LIST(COUNT_ENTRY) INLINE_FUNCTION_LIST(COUNT_ENTRY)
INLINE_OPTIMIZED_FUNCTION_LIST(COUNT_ENTRY);
#undef COUNT_ENTRY
Factory* factory = isolate->factory();
Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
int index = 0;
bool inline_runtime_functions = false;
#define ADD_ENTRY(Name, argc, ressize) \
{ \
HandleScope inner(isolate); \
Handle<String> name; \
/* Inline runtime functions have an underscore in front of the name. */ \
if (inline_runtime_functions) { \
name = factory->NewStringFromStaticChars("_" #Name); \
} else { \
name = factory->NewStringFromStaticChars(#Name); \
} \
Handle<FixedArray> pair_elements = factory->NewFixedArray(2); \
pair_elements->set(0, *name); \
pair_elements->set(1, Smi::FromInt(argc)); \
Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements); \
elements->set(index++, *pair); \
}
inline_runtime_functions = false;
RUNTIME_FUNCTION_LIST(ADD_ENTRY)
INLINE_OPTIMIZED_FUNCTION_LIST(ADD_ENTRY)
inline_runtime_functions = true;
INLINE_FUNCTION_LIST(ADD_ENTRY)
#undef ADD_ENTRY
DCHECK_EQ(index, entry_count);
Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
return *result;
}
#endif
RUNTIME_FUNCTION(Runtime_HaveSameMap) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 2);
......@@ -319,5 +374,27 @@ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
#undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
#define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size) \
RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) { \
CONVERT_ARG_CHECKED(JSObject, obj, 0); \
return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements()); \
}
TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
#undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
#define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s) \
RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) { \
CONVERT_ARG_CHECKED(JSObject, obj, 0); \
return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements()); \
}
TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
#undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
}
} // namespace v8::internal
......@@ -140,6 +140,10 @@ static inline ObjectPair MakePair(Object* x, Object* y) {
#endif
}
#endif
class JavaScriptFrameIterator;
int FindIndexedNonNativeFrame(JavaScriptFrameIterator* it, int index);
}
} // namespace v8::internal
......
This diff is collapsed.
......@@ -737,8 +737,12 @@
'../../src/runtime-profiler.h',
'../../src/runtime/runtime-collections.cc',
'../../src/runtime/runtime-compiler.cc',
'../../src/runtime/runtime-date.cc',
'../../src/runtime/runtime-debug.cc',
'../../src/runtime/runtime-generator.cc',
'../../src/runtime/runtime-i18n.cc',
'../../src/runtime/runtime-json.cc',
'../../src/runtime/runtime-liveedit.cc',
'../../src/runtime/runtime-maths.cc',
'../../src/runtime/runtime-numbers.cc',
'../../src/runtime/runtime-regexp.cc',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment