00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "v8.h"
00029
00030 #include "api.h"
00031 #include "bootstrapper.h"
00032 #include "compiler.h"
00033 #include "debug.h"
00034 #include "execution.h"
00035 #include "global-handles.h"
00036 #include "platform.h"
00037 #include "serialize.h"
00038 #include "snapshot.h"
00039
00040
00041 namespace i = v8::internal;
00042 #define LOG_API(expr) LOG(ApiEntryCall(expr))
00043
00044
00045 namespace v8 {
00046
00047
00048 #define ON_BAILOUT(location, code) \
00049 if (IsDeadCheck(location)) { \
00050 code; \
00051 UNREACHABLE(); \
00052 }
00053
00054
00055 #define EXCEPTION_PREAMBLE() \
00056 thread_local.IncrementCallDepth(); \
00057 ASSERT(!i::Top::external_caught_exception()); \
00058 bool has_pending_exception = false
00059
00060
00061 #define EXCEPTION_BAILOUT_CHECK(value) \
00062 do { \
00063 thread_local.DecrementCallDepth(); \
00064 if (has_pending_exception) { \
00065 if (thread_local.CallDepthIsZero() && i::Top::is_out_of_memory()) { \
00066 if (!thread_local.IgnoreOutOfMemory()) \
00067 i::V8::FatalProcessOutOfMemory(NULL); \
00068 } \
00069 bool call_depth_is_zero = thread_local.CallDepthIsZero(); \
00070 i::Top::optional_reschedule_exception(call_depth_is_zero); \
00071 return value; \
00072 } \
00073 } while (false)
00074
00075
00076
00077
00078
00079 static i::HandleScopeImplementer thread_local;
00080
00081
00082
00083
00084
00085 static bool has_shut_down = false;
00086 static FatalErrorCallback exception_behavior = NULL;
00087
00088
00089 static void DefaultFatalErrorHandler(const char* location,
00090 const char* message) {
00091 API_Fatal(location, message);
00092 }
00093
00094
00095
00096 static FatalErrorCallback& GetFatalErrorHandler() {
00097 if (exception_behavior == NULL) {
00098 exception_behavior = DefaultFatalErrorHandler;
00099 }
00100 return exception_behavior;
00101 }
00102
00103
00104
00105
00106
00107 void i::V8::FatalProcessOutOfMemory(const char* location) {
00108 has_shut_down = true;
00109 FatalErrorCallback callback = GetFatalErrorHandler();
00110 callback(location, "Allocation failed - process out of memory");
00111
00112 UNREACHABLE();
00113 }
00114
00115
00116 void V8::SetFatalErrorHandler(FatalErrorCallback that) {
00117 exception_behavior = that;
00118 }
00119
00120
00121 bool Utils::ReportApiFailure(const char* location, const char* message) {
00122 FatalErrorCallback callback = GetFatalErrorHandler();
00123 callback(location, message);
00124 has_shut_down = true;
00125 return false;
00126 }
00127
00128
00129 bool V8::IsDead() {
00130 return has_shut_down;
00131 }
00132
00133
00134 static inline bool ApiCheck(bool condition,
00135 const char* location,
00136 const char* message) {
00137 return condition ? true : Utils::ReportApiFailure(location, message);
00138 }
00139
00140
00141 static bool ReportV8Dead(const char* location) {
00142 FatalErrorCallback callback = GetFatalErrorHandler();
00143 callback(location, "V8 is no longer useable");
00144 return true;
00145 }
00146
00147
00148 static bool ReportEmptyHandle(const char* location) {
00149 FatalErrorCallback callback = GetFatalErrorHandler();
00150 callback(location, "Reading from empty handle");
00151 return true;
00152 }
00153
00154
00167 static inline bool IsDeadCheck(const char* location) {
00168 return has_shut_down ? ReportV8Dead(location) : false;
00169 }
00170
00171
00172 static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) {
00173 return obj.IsEmpty() ? ReportEmptyHandle(location) : false;
00174 }
00175
00176
00177 static inline bool EmptyCheck(const char* location, v8::Data* obj) {
00178 return (obj == 0) ? ReportEmptyHandle(location) : false;
00179 }
00180
00181
00182
00183
00184 static i::StringInputBuffer write_input_buffer;
00185
00186
00187 static void EnsureInitialized(const char* location) {
00188 if (IsDeadCheck(location)) return;
00189 ApiCheck(v8::V8::Initialize(), location, "Error initializing V8");
00190 }
00191
00192
00193 v8::Handle<v8::Primitive> ImplementationUtilities::Undefined() {
00194 if (IsDeadCheck("v8::Undefined()")) return v8::Handle<v8::Primitive>();
00195 EnsureInitialized("v8::Undefined()");
00196 return v8::Handle<Primitive>(ToApi<Primitive>(i::Factory::undefined_value()));
00197 }
00198
00199
00200 v8::Handle<v8::Primitive> ImplementationUtilities::Null() {
00201 if (IsDeadCheck("v8::Null()")) return v8::Handle<v8::Primitive>();
00202 EnsureInitialized("v8::Null()");
00203 return v8::Handle<Primitive>(ToApi<Primitive>(i::Factory::null_value()));
00204 }
00205
00206
00207 v8::Handle<v8::Boolean> ImplementationUtilities::True() {
00208 if (IsDeadCheck("v8::True()")) return v8::Handle<v8::Boolean>();
00209 EnsureInitialized("v8::True()");
00210 return v8::Handle<v8::Boolean>(ToApi<Boolean>(i::Factory::true_value()));
00211 }
00212
00213
00214 v8::Handle<v8::Boolean> ImplementationUtilities::False() {
00215 if (IsDeadCheck("v8::False()")) return v8::Handle<v8::Boolean>();
00216 EnsureInitialized("v8::False()");
00217 return v8::Handle<v8::Boolean>(ToApi<Boolean>(i::Factory::false_value()));
00218 }
00219
00220
00221 void V8::SetFlagsFromString(const char* str, int length) {
00222 i::FlagList::SetFlagsFromString(str, length);
00223 }
00224
00225
00226 void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
00227 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
00228 }
00229
00230
00231 v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {
00232 if (IsDeadCheck("v8::ThrowException()")) return v8::Handle<Value>();
00233
00234
00235 if (value.IsEmpty()) {
00236 i::Top::ScheduleThrow(i::Heap::undefined_value());
00237 } else {
00238 i::Top::ScheduleThrow(*Utils::OpenHandle(*value));
00239 }
00240 return v8::Undefined();
00241 }
00242
00243
00244 RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
00245
00246
00247 RegisteredExtension::RegisteredExtension(Extension* extension)
00248 : extension_(extension), state_(UNVISITED) { }
00249
00250
00251 void RegisteredExtension::Register(RegisteredExtension* that) {
00252 that->next_ = RegisteredExtension::first_extension_;
00253 RegisteredExtension::first_extension_ = that;
00254 }
00255
00256
00257 void RegisterExtension(Extension* that) {
00258 RegisteredExtension* extension = new RegisteredExtension(that);
00259 RegisteredExtension::Register(extension);
00260 }
00261
00262
00263 Extension::Extension(const char* name,
00264 const char* source,
00265 int dep_count,
00266 const char** deps)
00267 : name_(name),
00268 source_(source),
00269 dep_count_(dep_count),
00270 deps_(deps),
00271 auto_enable_(false) { }
00272
00273
00274 v8::Handle<Primitive> Undefined() {
00275 LOG_API("Undefined");
00276 return ImplementationUtilities::Undefined();
00277 }
00278
00279
00280 v8::Handle<Primitive> Null() {
00281 LOG_API("Null");
00282 return ImplementationUtilities::Null();
00283 }
00284
00285
00286 v8::Handle<Boolean> True() {
00287 LOG_API("True");
00288 return ImplementationUtilities::True();
00289 }
00290
00291
00292 v8::Handle<Boolean> False() {
00293 LOG_API("False");
00294 return ImplementationUtilities::False();
00295 }
00296
00297
00298 ResourceConstraints::ResourceConstraints()
00299 : max_young_space_size_(0),
00300 max_old_space_size_(0),
00301 stack_limit_(NULL) { }
00302
00303
00304 bool SetResourceConstraints(ResourceConstraints* constraints) {
00305 bool result = i::Heap::ConfigureHeap(constraints->max_young_space_size(),
00306 constraints->max_old_space_size());
00307 if (!result) return false;
00308 if (constraints->stack_limit() != NULL) {
00309 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints->stack_limit());
00310 i::StackGuard::SetStackLimit(limit);
00311 }
00312 return true;
00313 }
00314
00315
00316 void** V8::GlobalizeReference(void** obj) {
00317 LOG_API("Persistent::New");
00318 if (IsDeadCheck("V8::Persistent::New")) return NULL;
00319 i::Handle<i::Object> result =
00320 i::GlobalHandles::Create(*reinterpret_cast<i::Object**>(obj));
00321 return reinterpret_cast<void**>(result.location());
00322 }
00323
00324
00325 void V8::MakeWeak(void** object, void* parameters,
00326 WeakReferenceCallback callback) {
00327 LOG_API("MakeWeak");
00328 i::GlobalHandles::MakeWeak(reinterpret_cast<i::Object**>(object), parameters,
00329 callback);
00330 }
00331
00332
00333 void V8::ClearWeak(void** obj) {
00334 LOG_API("ClearWeak");
00335 i::GlobalHandles::ClearWeakness(reinterpret_cast<i::Object**>(obj));
00336 }
00337
00338
00339 bool V8::IsGlobalNearDeath(void** obj) {
00340 LOG_API("IsGlobalNearDeath");
00341 if (has_shut_down) return false;
00342 return i::GlobalHandles::IsNearDeath(reinterpret_cast<i::Object**>(obj));
00343 }
00344
00345
00346 bool V8::IsGlobalWeak(void** obj) {
00347 LOG_API("IsGlobalWeak");
00348 if (has_shut_down) return false;
00349 return i::GlobalHandles::IsWeak(reinterpret_cast<i::Object**>(obj));
00350 }
00351
00352
00353 void V8::DisposeGlobal(void** obj) {
00354 LOG_API("DisposeGlobal");
00355 if (has_shut_down) return;
00356 i::GlobalHandles::Destroy(reinterpret_cast<i::Object**>(obj));
00357 }
00358
00359
00360
00361
00362 HandleScope::Data HandleScope::current_ = { -1, NULL, NULL };
00363
00364
00365 int HandleScope::NumberOfHandles() {
00366 int n = thread_local.Blocks()->length();
00367 if (n == 0) return 0;
00368 return ((n - 1) * i::kHandleBlockSize) +
00369 (current_.next - thread_local.Blocks()->last());
00370 }
00371
00372
00373 void** v8::HandleScope::CreateHandle(void* value) {
00374 void** result = current_.next;
00375 if (result == current_.limit) {
00376
00377
00378 if (!ApiCheck(current_.extensions >= 0,
00379 "v8::HandleScope::CreateHandle()",
00380 "Cannot create a handle without a HandleScope")) {
00381 return NULL;
00382 }
00383
00384
00385 if (!thread_local.Blocks()->is_empty()) {
00386 void** limit = &thread_local.Blocks()->last()[i::kHandleBlockSize];
00387 if (current_.limit != limit) {
00388 current_.limit = limit;
00389 }
00390 }
00391
00392
00393
00394 if (result == current_.limit) {
00395
00396 result = thread_local.GetSpareOrNewBlock();
00397
00398
00399 thread_local.Blocks()->Add(result);
00400 current_.extensions++;
00401 current_.limit = &result[i::kHandleBlockSize];
00402 }
00403 }
00404
00405
00406
00407 ASSERT(result < current_.limit);
00408 current_.next = result + 1;
00409 *result = value;
00410 return result;
00411 }
00412
00413
00414 void Context::Enter() {
00415 if (IsDeadCheck("v8::Context::Enter()")) return;
00416 i::Handle<i::Context> env = Utils::OpenHandle(this);
00417 thread_local.EnterContext(env);
00418
00419 thread_local.SaveContext(i::GlobalHandles::Create(i::Top::context()));
00420 i::Top::set_context(*env);
00421 }
00422
00423
00424 void Context::Exit() {
00425 if (has_shut_down) return;
00426 if (!ApiCheck(thread_local.LeaveLastContext(),
00427 "v8::Context::Exit()",
00428 "Cannot exit non-entered context")) {
00429 return;
00430 }
00431
00432
00433 i::Handle<i::Object> last_context = thread_local.RestoreContext();
00434 i::Top::set_context(static_cast<i::Context*>(*last_context));
00435 i::GlobalHandles::Destroy(last_context.location());
00436 }
00437
00438
00439 void v8::HandleScope::DeleteExtensions() {
00440 ASSERT(current_.extensions != 0);
00441 thread_local.DeleteExtensions(current_.extensions);
00442 }
00443
00444
00445 void HandleScope::ZapRange(void** start, void** end) {
00446 if (start == NULL) return;
00447 for (void** p = start; p < end; p++) {
00448 *p = reinterpret_cast<void*>(v8::internal::kHandleZapValue);
00449 }
00450 }
00451
00452
00453 void** v8::HandleScope::RawClose(void** value) {
00454 if (!ApiCheck(!is_closed_,
00455 "v8::HandleScope::Close()",
00456 "Local scope has already been closed")) {
00457 return 0;
00458 }
00459 LOG_API("CloseHandleScope");
00460
00461
00462 i::Object* result = reinterpret_cast<i::Object*>(*value);
00463 is_closed_ = true;
00464 RestorePreviousState();
00465
00466
00467 i::Handle<i::Object> handle(result);
00468 return reinterpret_cast<void**>(handle.location());
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 NeanderObject::NeanderObject(int size) {
00481 EnsureInitialized("v8::Nowhere");
00482 value_ = i::Factory::NewNeanderObject();
00483 i::Handle<i::FixedArray> elements = i::Factory::NewFixedArray(size);
00484 value_->set_elements(*elements);
00485 }
00486
00487
00488 int NeanderObject::size() {
00489 return i::FixedArray::cast(value_->elements())->length();
00490 }
00491
00492
00493 NeanderArray::NeanderArray() : obj_(2) {
00494 obj_.set(0, i::Smi::FromInt(0));
00495 }
00496
00497
00498 int NeanderArray::length() {
00499 return i::Smi::cast(obj_.get(0))->value();
00500 }
00501
00502
00503 i::Object* NeanderArray::get(int offset) {
00504 ASSERT(0 <= offset);
00505 ASSERT(offset < length());
00506 return obj_.get(offset + 1);
00507 }
00508
00509
00510
00511
00512
00513
00514
00515 void NeanderArray::add(i::Handle<i::Object> value) {
00516 int length = this->length();
00517 int size = obj_.size();
00518 if (length == size - 1) {
00519 i::Handle<i::FixedArray> new_elms = i::Factory::NewFixedArray(2 * size);
00520 for (int i = 0; i < length; i++)
00521 new_elms->set(i + 1, get(i));
00522 obj_.value()->set_elements(*new_elms);
00523 }
00524 obj_.set(length + 1, *value);
00525 obj_.set(0, i::Smi::FromInt(length + 1));
00526 }
00527
00528
00529 void NeanderArray::set(int index, i::Object* value) {
00530 if (index < 0 || index >= this->length()) return;
00531 obj_.set(index + 1, value);
00532 }
00533
00534
00535
00536
00537
00538 static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
00539 that->set_tag(i::Smi::FromInt(type));
00540 }
00541
00542
00543 void Template::Set(v8::Handle<String> name, v8::Handle<Data> value,
00544 v8::PropertyAttribute attribute) {
00545 if (IsDeadCheck("v8::Template::SetProperty()")) return;
00546 HandleScope scope;
00547 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_list());
00548 if (list->IsUndefined()) {
00549 list = NeanderArray().value();
00550 Utils::OpenHandle(this)->set_property_list(*list);
00551 }
00552 NeanderArray array(list);
00553 array.add(Utils::OpenHandle(*name));
00554 array.add(Utils::OpenHandle(*value));
00555 array.add(Utils::OpenHandle(*v8::Integer::New(attribute)));
00556 }
00557
00558
00559
00560 static void InitializeFunctionTemplate(
00561 i::Handle<i::FunctionTemplateInfo> info) {
00562 info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
00563 info->set_flag(0);
00564 }
00565
00566
00567 Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
00568 if (IsDeadCheck("v8::FunctionTemplate::PrototypeTemplate()")) {
00569 return Local<ObjectTemplate>();
00570 }
00571 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template());
00572 if (result->IsUndefined()) {
00573 result = Utils::OpenHandle(*ObjectTemplate::New());
00574 Utils::OpenHandle(this)->set_prototype_template(*result);
00575 }
00576 return Local<ObjectTemplate>(ToApi<ObjectTemplate>(result));
00577 }
00578
00579
00580 void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
00581 if (IsDeadCheck("v8::FunctionTemplate::Inherit()")) return;
00582 Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
00583 }
00584
00585
00586
00587
00588 static int next_serial_number = 0;
00589
00590
00591 Local<FunctionTemplate> FunctionTemplate::New(InvocationCallback callback,
00592 v8::Handle<Value> data, v8::Handle<Signature> signature) {
00593 EnsureInitialized("v8::FunctionTemplate::New()");
00594 LOG_API("FunctionTemplate::New");
00595 i::Handle<i::Struct> struct_obj =
00596 i::Factory::NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
00597 i::Handle<i::FunctionTemplateInfo> obj =
00598 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
00599 InitializeFunctionTemplate(obj);
00600 obj->set_serial_number(i::Smi::FromInt(next_serial_number++));
00601 if (callback != 0) {
00602 if (data.IsEmpty()) data = v8::Undefined();
00603 Utils::ToLocal(obj)->SetCallHandler(callback, data);
00604 }
00605 obj->set_undetectable(false);
00606 obj->set_needs_access_check(false);
00607
00608 if (!signature.IsEmpty())
00609 obj->set_signature(*Utils::OpenHandle(*signature));
00610 return Utils::ToLocal(obj);
00611 }
00612
00613
00614 Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
00615 int argc, Handle<FunctionTemplate> argv[]) {
00616 EnsureInitialized("v8::Signature::New()");
00617 LOG_API("Signature::New");
00618 i::Handle<i::Struct> struct_obj =
00619 i::Factory::NewStruct(i::SIGNATURE_INFO_TYPE);
00620 i::Handle<i::SignatureInfo> obj =
00621 i::Handle<i::SignatureInfo>::cast(struct_obj);
00622 if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
00623 if (argc > 0) {
00624 i::Handle<i::FixedArray> args = i::Factory::NewFixedArray(argc);
00625 for (int i = 0; i < argc; i++) {
00626 if (!argv[i].IsEmpty())
00627 args->set(i, *Utils::OpenHandle(*argv[i]));
00628 }
00629 obj->set_args(*args);
00630 }
00631 return Utils::ToLocal(obj);
00632 }
00633
00634
00635 Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
00636 Handle<FunctionTemplate> types[1] = { type };
00637 return TypeSwitch::New(1, types);
00638 }
00639
00640
00641 Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
00642 EnsureInitialized("v8::TypeSwitch::New()");
00643 LOG_API("TypeSwitch::New");
00644 i::Handle<i::FixedArray> vector = i::Factory::NewFixedArray(argc);
00645 for (int i = 0; i < argc; i++)
00646 vector->set(i, *Utils::OpenHandle(*types[i]));
00647 i::Handle<i::Struct> struct_obj =
00648 i::Factory::NewStruct(i::TYPE_SWITCH_INFO_TYPE);
00649 i::Handle<i::TypeSwitchInfo> obj =
00650 i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
00651 obj->set_types(*vector);
00652 return Utils::ToLocal(obj);
00653 }
00654
00655
00656 int TypeSwitch::match(v8::Handle<Value> value) {
00657 LOG_API("TypeSwitch::match");
00658 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
00659 i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
00660 i::FixedArray* types = i::FixedArray::cast(info->types());
00661 for (int i = 0; i < types->length(); i++) {
00662 if (obj->IsInstanceOf(i::FunctionTemplateInfo::cast(types->get(i))))
00663 return i + 1;
00664 }
00665 return 0;
00666 }
00667
00668
00669 void FunctionTemplate::SetCallHandler(InvocationCallback callback,
00670 v8::Handle<Value> data) {
00671 if (IsDeadCheck("v8::FunctionTemplate::SetCallHandler()")) return;
00672 HandleScope scope;
00673 i::Handle<i::Struct> struct_obj =
00674 i::Factory::NewStruct(i::CALL_HANDLER_INFO_TYPE);
00675 i::Handle<i::CallHandlerInfo> obj =
00676 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
00677 obj->set_callback(*FromCData(callback));
00678 if (data.IsEmpty()) data = v8::Undefined();
00679 obj->set_data(*Utils::OpenHandle(*data));
00680 Utils::OpenHandle(this)->set_call_code(*obj);
00681 }
00682
00683
00684 void FunctionTemplate::AddInstancePropertyAccessor(
00685 v8::Handle<String> name,
00686 AccessorGetter getter,
00687 AccessorSetter setter,
00688 v8::Handle<Value> data,
00689 v8::AccessControl settings,
00690 v8::PropertyAttribute attributes) {
00691 if (IsDeadCheck("v8::FunctionTemplate::AddInstancePropertyAccessor()")) {
00692 return;
00693 }
00694 HandleScope scope;
00695 i::Handle<i::AccessorInfo> obj = i::Factory::NewAccessorInfo();
00696 ASSERT(getter != NULL);
00697 obj->set_getter(*FromCData(getter));
00698 obj->set_setter(*FromCData(setter));
00699 if (data.IsEmpty()) data = v8::Undefined();
00700 obj->set_data(*Utils::OpenHandle(*data));
00701 obj->set_name(*Utils::OpenHandle(*name));
00702 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
00703 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
00704 obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
00705
00706 i::Handle<i::Object> list(Utils::OpenHandle(this)->property_accessors());
00707 if (list->IsUndefined()) {
00708 list = NeanderArray().value();
00709 Utils::OpenHandle(this)->set_property_accessors(*list);
00710 }
00711 NeanderArray array(list);
00712 array.add(obj);
00713 }
00714
00715
00716 Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
00717 if (IsDeadCheck("v8::FunctionTemplate::InstanceTemplate()")
00718 || EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this))
00719 return Local<ObjectTemplate>();
00720 if (Utils::OpenHandle(this)->instance_template()->IsUndefined()) {
00721 Local<ObjectTemplate> templ =
00722 ObjectTemplate::New(v8::Handle<FunctionTemplate>(this));
00723 Utils::OpenHandle(this)->set_instance_template(*Utils::OpenHandle(*templ));
00724 }
00725 i::Handle<i::ObjectTemplateInfo> result(i::ObjectTemplateInfo::cast(
00726 Utils::OpenHandle(this)->instance_template()));
00727 return Utils::ToLocal(result);
00728 }
00729
00730
00731 void FunctionTemplate::SetClassName(Handle<String> name) {
00732 if (IsDeadCheck("v8::FunctionTemplate::SetClassName()")) return;
00733 Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
00734 }
00735
00736
00737 void FunctionTemplate::SetHiddenPrototype(bool value) {
00738 if (IsDeadCheck("v8::FunctionTemplate::SetHiddenPrototype()")) return;
00739 Utils::OpenHandle(this)->set_hidden_prototype(value);
00740 }
00741
00742
00743 void FunctionTemplate::SetNamedInstancePropertyHandler(
00744 NamedPropertyGetter getter,
00745 NamedPropertySetter setter,
00746 NamedPropertyQuery query,
00747 NamedPropertyDeleter remover,
00748 NamedPropertyEnumerator enumerator,
00749 Handle<Value> data) {
00750 if (IsDeadCheck("v8::FunctionTemplate::SetNamedInstancePropertyHandler()")) {
00751 return;
00752 }
00753 HandleScope scope;
00754 i::Handle<i::Struct> struct_obj =
00755 i::Factory::NewStruct(i::INTERCEPTOR_INFO_TYPE);
00756 i::Handle<i::InterceptorInfo> obj =
00757 i::Handle<i::InterceptorInfo>::cast(struct_obj);
00758 if (getter != 0) obj->set_getter(*FromCData(getter));
00759 if (setter != 0) obj->set_setter(*FromCData(setter));
00760 if (query != 0) obj->set_query(*FromCData(query));
00761 if (remover != 0) obj->set_deleter(*FromCData(remover));
00762 if (enumerator != 0) obj->set_enumerator(*FromCData(enumerator));
00763 if (data.IsEmpty()) data = v8::Undefined();
00764 obj->set_data(*Utils::OpenHandle(*data));
00765 Utils::OpenHandle(this)->set_named_property_handler(*obj);
00766 }
00767
00768
00769 void FunctionTemplate::SetIndexedInstancePropertyHandler(
00770 IndexedPropertyGetter getter,
00771 IndexedPropertySetter setter,
00772 IndexedPropertyQuery query,
00773 IndexedPropertyDeleter remover,
00774 IndexedPropertyEnumerator enumerator,
00775 Handle<Value> data) {
00776 if (IsDeadCheck(
00777 "v8::FunctionTemplate::SetIndexedInstancePropertyHandler()")) {
00778 return;
00779 }
00780 HandleScope scope;
00781 i::Handle<i::Struct> struct_obj =
00782 i::Factory::NewStruct(i::INTERCEPTOR_INFO_TYPE);
00783 i::Handle<i::InterceptorInfo> obj =
00784 i::Handle<i::InterceptorInfo>::cast(struct_obj);
00785 if (getter != 0) obj->set_getter(*FromCData(getter));
00786 if (setter != 0) obj->set_setter(*FromCData(setter));
00787 if (query != 0) obj->set_query(*FromCData(query));
00788 if (remover != 0) obj->set_deleter(*FromCData(remover));
00789 if (enumerator != 0) obj->set_enumerator(*FromCData(enumerator));
00790 if (data.IsEmpty()) data = v8::Undefined();
00791 obj->set_data(*Utils::OpenHandle(*data));
00792 Utils::OpenHandle(this)->set_indexed_property_handler(*obj);
00793 }
00794
00795
00796 void FunctionTemplate::SetInstanceCallAsFunctionHandler(
00797 InvocationCallback callback,
00798 Handle<Value> data) {
00799 if (IsDeadCheck("v8::FunctionTemplate::SetInstanceCallAsFunctionHandler()")) {
00800 return;
00801 }
00802 HandleScope scope;
00803 i::Handle<i::Struct> struct_obj =
00804 i::Factory::NewStruct(i::CALL_HANDLER_INFO_TYPE);
00805 i::Handle<i::CallHandlerInfo> obj =
00806 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
00807 obj->set_callback(*FromCData(callback));
00808 if (data.IsEmpty()) data = v8::Undefined();
00809 obj->set_data(*Utils::OpenHandle(*data));
00810 Utils::OpenHandle(this)->set_instance_call_handler(*obj);
00811 }
00812
00813
00814
00815
00816
00817 Local<ObjectTemplate> ObjectTemplate::New() {
00818 return New(Local<FunctionTemplate>());
00819 }
00820
00821
00822 Local<ObjectTemplate> ObjectTemplate::New(
00823 v8::Handle<FunctionTemplate> constructor) {
00824 if (IsDeadCheck("v8::ObjectTemplate::New()")) return Local<ObjectTemplate>();
00825 EnsureInitialized("v8::ObjectTemplate::New()");
00826 LOG_API("ObjectTemplate::New");
00827 i::Handle<i::Struct> struct_obj =
00828 i::Factory::NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
00829 i::Handle<i::ObjectTemplateInfo> obj =
00830 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
00831 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
00832 if (!constructor.IsEmpty())
00833 obj->set_constructor(*Utils::OpenHandle(*constructor));
00834 obj->set_internal_field_count(i::Smi::FromInt(0));
00835 return Utils::ToLocal(obj);
00836 }
00837
00838
00839
00840
00841 static void EnsureConstructor(ObjectTemplate* object_template) {
00842 if (Utils::OpenHandle(object_template)->constructor()->IsUndefined()) {
00843 Local<FunctionTemplate> templ = FunctionTemplate::New();
00844 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
00845 constructor->set_instance_template(*Utils::OpenHandle(object_template));
00846 Utils::OpenHandle(object_template)->set_constructor(*constructor);
00847 }
00848 }
00849
00850
00851 void ObjectTemplate::SetAccessor(v8::Handle<String> name,
00852 AccessorGetter getter,
00853 AccessorSetter setter,
00854 v8::Handle<Value> data,
00855 AccessControl settings,
00856 PropertyAttribute attribute) {
00857 if (IsDeadCheck("v8::ObjectTemplate::SetAccessor()")) return;
00858 HandleScope scope;
00859 EnsureConstructor(this);
00860 i::FunctionTemplateInfo* constructor =
00861 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
00862 i::Handle<i::FunctionTemplateInfo> cons(constructor);
00863 Utils::ToLocal(cons)->AddInstancePropertyAccessor(name,
00864 getter,
00865 setter,
00866 data,
00867 settings,
00868 attribute);
00869 }
00870
00871
00872 void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter,
00873 NamedPropertySetter setter,
00874 NamedPropertyQuery query,
00875 NamedPropertyDeleter remover,
00876 NamedPropertyEnumerator enumerator,
00877 Handle<Value> data) {
00878 if (IsDeadCheck("v8::ObjectTemplate::SetNamedPropertyHandler()")) return;
00879 HandleScope scope;
00880 EnsureConstructor(this);
00881 i::FunctionTemplateInfo* constructor =
00882 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
00883 i::Handle<i::FunctionTemplateInfo> cons(constructor);
00884 Utils::ToLocal(cons)->SetNamedInstancePropertyHandler(getter,
00885 setter,
00886 query,
00887 remover,
00888 enumerator,
00889 data);
00890 }
00891
00892
00893 void ObjectTemplate::MarkAsUndetectable() {
00894 if (IsDeadCheck("v8::ObjectTemplate::MarkAsUndetectable()")) return;
00895 HandleScope scope;
00896 EnsureConstructor(this);
00897 i::FunctionTemplateInfo* constructor =
00898 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
00899 i::Handle<i::FunctionTemplateInfo> cons(constructor);
00900 cons->set_undetectable(true);
00901 }
00902
00903
00904 void ObjectTemplate::SetAccessCheckCallbacks(
00905 NamedSecurityCallback named_callback,
00906 IndexedSecurityCallback indexed_callback,
00907 Handle<Value> data,
00908 bool turned_on_by_default) {
00909 if (IsDeadCheck("v8::ObjectTemplate::SetAccessCheckCallbacks()")) return;
00910 HandleScope scope;
00911 EnsureConstructor(this);
00912
00913 i::Handle<i::Struct> struct_info =
00914 i::Factory::NewStruct(i::ACCESS_CHECK_INFO_TYPE);
00915 i::Handle<i::AccessCheckInfo> info =
00916 i::Handle<i::AccessCheckInfo>::cast(struct_info);
00917 info->set_named_callback(*FromCData(named_callback));
00918 info->set_indexed_callback(*FromCData(indexed_callback));
00919 if (data.IsEmpty()) data = v8::Undefined();
00920 info->set_data(*Utils::OpenHandle(*data));
00921
00922 i::FunctionTemplateInfo* constructor =
00923 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
00924 i::Handle<i::FunctionTemplateInfo> cons(constructor);
00925 cons->set_access_check_info(*info);
00926 cons->set_needs_access_check(turned_on_by_default);
00927 }
00928
00929
00930 void ObjectTemplate::SetIndexedPropertyHandler(
00931 IndexedPropertyGetter getter,
00932 IndexedPropertySetter setter,
00933 IndexedPropertyQuery query,
00934 IndexedPropertyDeleter remover,
00935 IndexedPropertyEnumerator enumerator,
00936 Handle<Value> data) {
00937 if (IsDeadCheck("v8::ObjectTemplate::SetIndexedPropertyHandler()")) return;
00938 HandleScope scope;
00939 EnsureConstructor(this);
00940 i::FunctionTemplateInfo* constructor =
00941 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
00942 i::Handle<i::FunctionTemplateInfo> cons(constructor);
00943 Utils::ToLocal(cons)->SetIndexedInstancePropertyHandler(getter,
00944 setter,
00945 query,
00946 remover,
00947 enumerator,
00948 data);
00949 }
00950
00951
00952 void ObjectTemplate::SetCallAsFunctionHandler(InvocationCallback callback,
00953 Handle<Value> data) {
00954 if (IsDeadCheck("v8::ObjectTemplate::SetCallAsFunctionHandler()")) return;
00955 HandleScope scope;
00956 EnsureConstructor(this);
00957 i::FunctionTemplateInfo* constructor =
00958 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
00959 i::Handle<i::FunctionTemplateInfo> cons(constructor);
00960 Utils::ToLocal(cons)->SetInstanceCallAsFunctionHandler(callback, data);
00961 }
00962
00963
00964 int ObjectTemplate::InternalFieldCount() {
00965 if (IsDeadCheck("v8::ObjectTemplate::InternalFieldCount()")) {
00966 return 0;
00967 }
00968 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
00969 }
00970
00971
00972 void ObjectTemplate::SetInternalFieldCount(int value) {
00973 if (IsDeadCheck("v8::ObjectTemplate::SetInternalFieldCount()")) return;
00974 if (!ApiCheck(i::Smi::IsValid(value),
00975 "v8::ObjectTemplate::SetInternalFieldCount()",
00976 "Invalid internal field count")) {
00977 return;
00978 }
00979 if (value > 0) {
00980
00981
00982
00983 EnsureConstructor(this);
00984 }
00985 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
00986 }
00987
00988
00989
00990
00991
00992 ScriptData* ScriptData::PreCompile(const char* input, int length) {
00993 unibrow::Utf8InputBuffer<> buf(input, length);
00994 return i::PreParse(&buf, NULL);
00995 }
00996
00997
00998 ScriptData* ScriptData::New(unsigned* data, int length) {
00999 return new i::ScriptDataImpl(i::Vector<unsigned>(data, length));
01000 }
01001
01002
01003
01004
01005
01006 Local<Script> Script::Compile(v8::Handle<String> source,
01007 v8::ScriptOrigin* origin,
01008 v8::ScriptData* script_data) {
01009 ON_BAILOUT("v8::Script::Compile()", return Local<Script>());
01010 LOG_API("Script::Compile");
01011 i::Handle<i::String> str = Utils::OpenHandle(*source);
01012 i::Handle<i::Object> name_obj;
01013 int line_offset = 0;
01014 int column_offset = 0;
01015 if (origin != NULL) {
01016 if (!origin->ResourceName().IsEmpty()) {
01017 name_obj = Utils::OpenHandle(*origin->ResourceName());
01018 }
01019 if (!origin->ResourceLineOffset().IsEmpty()) {
01020 line_offset = static_cast<int>(origin->ResourceLineOffset()->Value());
01021 }
01022 if (!origin->ResourceColumnOffset().IsEmpty()) {
01023 column_offset = static_cast<int>(origin->ResourceColumnOffset()->Value());
01024 }
01025 }
01026 EXCEPTION_PREAMBLE();
01027 i::ScriptDataImpl* pre_data = static_cast<i::ScriptDataImpl*>(script_data);
01028
01029
01030 ASSERT(pre_data == NULL || pre_data->SanityCheck());
01031
01032 if (pre_data != NULL && !pre_data->SanityCheck())
01033 pre_data = NULL;
01034 i::Handle<i::JSFunction> boilerplate = i::Compiler::Compile(str,
01035 name_obj,
01036 line_offset,
01037 column_offset,
01038 NULL,
01039 pre_data);
01040 has_pending_exception = boilerplate.is_null();
01041 EXCEPTION_BAILOUT_CHECK(Local<Script>());
01042 i::Handle<i::JSFunction> result =
01043 i::Factory::NewFunctionFromBoilerplate(boilerplate,
01044 i::Top::global_context());
01045 return Local<Script>(ToApi<Script>(result));
01046 }
01047
01048
01049 Local<Script> Script::Compile(v8::Handle<String> source,
01050 v8::Handle<Value> file_name) {
01051 ScriptOrigin origin(file_name);
01052 return Compile(source, &origin);
01053 }
01054
01055
01056 Local<Value> Script::Run() {
01057 ON_BAILOUT("v8::Script::Run()", return Local<Value>());
01058 LOG_API("Script::Run");
01059 i::Object* raw_result = NULL;
01060 {
01061 HandleScope scope;
01062 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
01063 EXCEPTION_PREAMBLE();
01064 i::Handle<i::Object> receiver(i::Top::context()->global_proxy());
01065 i::Handle<i::Object> result =
01066 i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
01067 EXCEPTION_BAILOUT_CHECK(Local<Value>());
01068 raw_result = *result;
01069 }
01070 i::Handle<i::Object> result(raw_result);
01071 return Utils::ToLocal(result);
01072 }
01073
01074
01075
01076
01077
01078 v8::TryCatch::TryCatch()
01079 : next_(i::Top::try_catch_handler()),
01080 exception_(i::Heap::the_hole_value()),
01081 message_(i::Smi::FromInt(0)),
01082 is_verbose_(false),
01083 capture_message_(true) {
01084 i::Top::RegisterTryCatchHandler(this);
01085 }
01086
01087
01088 v8::TryCatch::~TryCatch() {
01089 i::Top::UnregisterTryCatchHandler(this);
01090 }
01091
01092
01093 bool v8::TryCatch::HasCaught() const {
01094 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
01095 }
01096
01097
01098 v8::Local<Value> v8::TryCatch::Exception() const {
01099 if (HasCaught()) {
01100
01101 i::Object* exception = reinterpret_cast<i::Object*>(exception_);
01102 return v8::Utils::ToLocal(i::Handle<i::Object>(exception));
01103 } else {
01104 return v8::Local<Value>();
01105 }
01106 }
01107
01108
01109 v8::Local<v8::Message> v8::TryCatch::Message() const {
01110 if (HasCaught() && message_ != i::Smi::FromInt(0)) {
01111 i::Object* message = reinterpret_cast<i::Object*>(message_);
01112 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message));
01113 } else {
01114 return v8::Local<v8::Message>();
01115 }
01116 }
01117
01118
01119 void v8::TryCatch::Reset() {
01120 exception_ = i::Heap::the_hole_value();
01121 message_ = i::Smi::FromInt(0);
01122 }
01123
01124
01125 void v8::TryCatch::SetVerbose(bool value) {
01126 is_verbose_ = value;
01127 }
01128
01129
01130 void v8::TryCatch::SetCaptureMessage(bool value) {
01131 capture_message_ = value;
01132 }
01133
01134
01135
01136
01137
01138 Local<String> Message::Get() {
01139 ON_BAILOUT("v8::Message::Get()", return Local<String>());
01140 HandleScope scope;
01141 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01142 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(obj);
01143 Local<String> result = Utils::ToLocal(raw_result);
01144 return scope.Close(result);
01145 }
01146
01147
01148 v8::Handle<Value> Message::GetScriptResourceName() {
01149 if (IsDeadCheck("v8::Message::GetScriptResourceName()")) {
01150 return Local<String>();
01151 }
01152 HandleScope scope;
01153 i::Handle<i::JSObject> obj =
01154 i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
01155
01156 i::Handle<i::JSValue> script =
01157 i::Handle<i::JSValue>::cast(GetProperty(obj, "script"));
01158 i::Handle<i::Object> resource_name(i::Script::cast(script->value())->name());
01159 return scope.Close(Utils::ToLocal(resource_name));
01160 }
01161
01162
01163 static i::Handle<i::Object> CallV8HeapFunction(const char* name,
01164 i::Handle<i::Object> recv,
01165 int argc,
01166 i::Object** argv[],
01167 bool* has_pending_exception) {
01168 i::Handle<i::String> fmt_str = i::Factory::LookupAsciiSymbol(name);
01169 i::Object* object_fun = i::Top::builtins()->GetProperty(*fmt_str);
01170 i::Handle<i::JSFunction> fun =
01171 i::Handle<i::JSFunction>(i::JSFunction::cast(object_fun));
01172 i::Handle<i::Object> value =
01173 i::Execution::Call(fun, recv, argc, argv, has_pending_exception);
01174 return value;
01175 }
01176
01177
01178 static i::Handle<i::Object> CallV8HeapFunction(const char* name,
01179 i::Handle<i::Object> data,
01180 bool* has_pending_exception) {
01181 i::Object** argv[1] = { data.location() };
01182 return CallV8HeapFunction(name,
01183 i::Top::builtins(),
01184 1,
01185 argv,
01186 has_pending_exception);
01187 }
01188
01189
01190 int Message::GetLineNumber() {
01191 ON_BAILOUT("v8::Message::GetLineNumber()", return -1);
01192 HandleScope scope;
01193 EXCEPTION_PREAMBLE();
01194 i::Handle<i::Object> result = CallV8HeapFunction("GetLineNumber",
01195 Utils::OpenHandle(this),
01196 &has_pending_exception);
01197 EXCEPTION_BAILOUT_CHECK(0);
01198 return static_cast<int>(result->Number());
01199 }
01200
01201
01202 int Message::GetStartPosition() {
01203 if (IsDeadCheck("v8::Message::GetStartPosition()")) return 0;
01204 HandleScope scope;
01205
01206 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
01207 return static_cast<int>(GetProperty(data_obj, "startPos")->Number());
01208 }
01209
01210
01211 int Message::GetEndPosition() {
01212 if (IsDeadCheck("v8::Message::GetEndPosition()")) return 0;
01213 HandleScope scope;
01214 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
01215 return static_cast<int>(GetProperty(data_obj, "endPos")->Number());
01216 }
01217
01218
01219 int Message::GetStartColumn() {
01220 if (IsDeadCheck("v8::Message::GetStartColumn()")) return 0;
01221 HandleScope scope;
01222 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
01223 EXCEPTION_PREAMBLE();
01224 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
01225 "GetPositionInLine",
01226 data_obj,
01227 &has_pending_exception);
01228 EXCEPTION_BAILOUT_CHECK(0);
01229 return static_cast<int>(start_col_obj->Number());
01230 }
01231
01232
01233 int Message::GetEndColumn() {
01234 if (IsDeadCheck("v8::Message::GetEndColumn()")) return 0;
01235 HandleScope scope;
01236 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
01237 EXCEPTION_PREAMBLE();
01238 i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
01239 "GetPositionInLine",
01240 data_obj,
01241 &has_pending_exception);
01242 EXCEPTION_BAILOUT_CHECK(0);
01243 int start = static_cast<int>(GetProperty(data_obj, "startPos")->Number());
01244 int end = static_cast<int>(GetProperty(data_obj, "endPos")->Number());
01245 return static_cast<int>(start_col_obj->Number()) + (end - start);
01246 }
01247
01248
01249 Local<String> Message::GetSourceLine() {
01250 ON_BAILOUT("v8::Message::GetSourceLine()", return Local<String>());
01251 HandleScope scope;
01252 EXCEPTION_PREAMBLE();
01253 i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
01254 Utils::OpenHandle(this),
01255 &has_pending_exception);
01256 EXCEPTION_BAILOUT_CHECK(Local<v8::String>());
01257 if (result->IsString()) {
01258 return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
01259 } else {
01260 return Local<String>();
01261 }
01262 }
01263
01264
01265 void Message::PrintCurrentStackTrace(FILE* out) {
01266 if (IsDeadCheck("v8::Message::PrintCurrentStackTrace()")) return;
01267 i::Top::PrintCurrentStackTrace(out);
01268 }
01269
01270
01271
01272
01273 bool Value::IsUndefined() {
01274 if (IsDeadCheck("v8::Value::IsUndefined()")) return false;
01275 return Utils::OpenHandle(this)->IsUndefined();
01276 }
01277
01278
01279 bool Value::IsNull() {
01280 if (IsDeadCheck("v8::Value::IsNull()")) return false;
01281 return Utils::OpenHandle(this)->IsNull();
01282 }
01283
01284
01285 bool Value::IsTrue() {
01286 if (IsDeadCheck("v8::Value::IsTrue()")) return false;
01287 return Utils::OpenHandle(this)->IsTrue();
01288 }
01289
01290
01291 bool Value::IsFalse() {
01292 if (IsDeadCheck("v8::Value::IsFalse()")) return false;
01293 return Utils::OpenHandle(this)->IsFalse();
01294 }
01295
01296
01297 bool Value::IsFunction() {
01298 if (IsDeadCheck("v8::Value::IsFunction()")) return false;
01299 return Utils::OpenHandle(this)->IsJSFunction();
01300 }
01301
01302
01303 bool Value::IsString() {
01304 if (IsDeadCheck("v8::Value::IsString()")) return false;
01305 return Utils::OpenHandle(this)->IsString();
01306 }
01307
01308
01309 bool Value::IsArray() {
01310 if (IsDeadCheck("v8::Value::IsArray()")) return false;
01311 return Utils::OpenHandle(this)->IsJSArray();
01312 }
01313
01314
01315 bool Value::IsObject() {
01316 if (IsDeadCheck("v8::Value::IsObject()")) return false;
01317 return Utils::OpenHandle(this)->IsJSObject();
01318 }
01319
01320
01321 bool Value::IsNumber() {
01322 if (IsDeadCheck("v8::Value::IsNumber()")) return false;
01323 return Utils::OpenHandle(this)->IsNumber();
01324 }
01325
01326
01327 bool Value::IsBoolean() {
01328 if (IsDeadCheck("v8::Value::IsBoolean()")) return false;
01329 return Utils::OpenHandle(this)->IsBoolean();
01330 }
01331
01332
01333 bool Value::IsExternal() {
01334 if (IsDeadCheck("v8::Value::IsExternal()")) return false;
01335 return Utils::OpenHandle(this)->IsProxy();
01336 }
01337
01338
01339 bool Value::IsInt32() {
01340 if (IsDeadCheck("v8::Value::IsInt32()")) return false;
01341 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01342 if (obj->IsSmi()) return true;
01343 if (obj->IsNumber()) {
01344 double value = obj->Number();
01345 return i::FastI2D(i::FastD2I(value)) == value;
01346 }
01347 return false;
01348 }
01349
01350
01351 bool Value::IsDate() {
01352 if (IsDeadCheck("v8::Value::IsDate()")) return false;
01353 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01354 return obj->HasSpecificClassOf(i::Heap::Date_symbol());
01355 }
01356
01357
01358 Local<String> Value::ToString() {
01359 if (IsDeadCheck("v8::Value::ToString()")) return Local<String>();
01360 LOG_API("ToString");
01361 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01362 i::Handle<i::Object> str;
01363 if (obj->IsString()) {
01364 str = obj;
01365 } else {
01366 EXCEPTION_PREAMBLE();
01367 str = i::Execution::ToString(obj, &has_pending_exception);
01368 EXCEPTION_BAILOUT_CHECK(Local<String>());
01369 }
01370 return Local<String>(ToApi<String>(str));
01371 }
01372
01373
01374 Local<String> Value::ToDetailString() {
01375 if (IsDeadCheck("v8::Value::ToDetailString()")) return Local<String>();
01376 LOG_API("ToDetailString");
01377 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01378 i::Handle<i::Object> str;
01379 if (obj->IsString()) {
01380 str = obj;
01381 } else {
01382 EXCEPTION_PREAMBLE();
01383 str = i::Execution::ToDetailString(obj, &has_pending_exception);
01384 EXCEPTION_BAILOUT_CHECK(Local<String>());
01385 }
01386 return Local<String>(ToApi<String>(str));
01387 }
01388
01389
01390 Local<v8::Object> Value::ToObject() {
01391 if (IsDeadCheck("v8::Value::ToObject()")) return Local<v8::Object>();
01392 LOG_API("ToObject");
01393 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01394 i::Handle<i::Object> val;
01395 if (obj->IsJSObject()) {
01396 val = obj;
01397 } else {
01398 EXCEPTION_PREAMBLE();
01399 val = i::Execution::ToObject(obj, &has_pending_exception);
01400 EXCEPTION_BAILOUT_CHECK(Local<v8::Object>());
01401 }
01402 return Local<v8::Object>(ToApi<Object>(val));
01403 }
01404
01405
01406 Local<Boolean> Value::ToBoolean() {
01407 if (IsDeadCheck("v8::Value::ToBoolean()")) return Local<Boolean>();
01408 LOG_API("ToBoolean");
01409 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01410 i::Handle<i::Object> val =
01411 obj->IsBoolean() ? obj : i::Execution::ToBoolean(obj);
01412 return Local<Boolean>(ToApi<Boolean>(val));
01413 }
01414
01415
01416 Local<Number> Value::ToNumber() {
01417 if (IsDeadCheck("v8::Value::ToNumber()")) return Local<Number>();
01418 LOG_API("ToNumber");
01419 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01420 i::Handle<i::Object> num;
01421 if (obj->IsNumber()) {
01422 num = obj;
01423 } else {
01424 EXCEPTION_PREAMBLE();
01425 num = i::Execution::ToNumber(obj, &has_pending_exception);
01426 EXCEPTION_BAILOUT_CHECK(Local<Number>());
01427 }
01428 return Local<Number>(ToApi<Number>(num));
01429 }
01430
01431
01432 Local<Integer> Value::ToInteger() {
01433 if (IsDeadCheck("v8::Value::ToInteger()")) return Local<Integer>();
01434 LOG_API("ToInteger");
01435 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01436 i::Handle<i::Object> num;
01437 if (obj->IsSmi()) {
01438 num = obj;
01439 } else {
01440 EXCEPTION_PREAMBLE();
01441 num = i::Execution::ToInteger(obj, &has_pending_exception);
01442 EXCEPTION_BAILOUT_CHECK(Local<Integer>());
01443 }
01444 return Local<Integer>(ToApi<Integer>(num));
01445 }
01446
01447
01448 External* External::Cast(v8::Value* that) {
01449 if (IsDeadCheck("v8::External::Cast()")) return 0;
01450 i::Handle<i::Object> obj = Utils::OpenHandle(that);
01451 ApiCheck(obj->IsProxy(),
01452 "v8::External::Cast()",
01453 "Could not convert to external");
01454 return static_cast<External*>(that);
01455 }
01456
01457
01458 v8::Object* v8::Object::Cast(Value* that) {
01459 if (IsDeadCheck("v8::Object::Cast()")) return 0;
01460 i::Handle<i::Object> obj = Utils::OpenHandle(that);
01461 ApiCheck(obj->IsJSObject(),
01462 "v8::Object::Cast()",
01463 "Could not convert to object");
01464 return static_cast<v8::Object*>(that);
01465 }
01466
01467
01468 v8::Function* v8::Function::Cast(Value* that) {
01469 if (IsDeadCheck("v8::Function::Cast()")) return 0;
01470 i::Handle<i::Object> obj = Utils::OpenHandle(that);
01471 ApiCheck(obj->IsJSFunction(),
01472 "v8::Function::Cast()",
01473 "Could not convert to function");
01474 return static_cast<v8::Function*>(that);
01475 }
01476
01477
01478 v8::String* v8::String::Cast(v8::Value* that) {
01479 if (IsDeadCheck("v8::String::Cast()")) return 0;
01480 i::Handle<i::Object> obj = Utils::OpenHandle(that);
01481 ApiCheck(obj->IsString(),
01482 "v8::String::Cast()",
01483 "Could not convert to string");
01484 return static_cast<v8::String*>(that);
01485 }
01486
01487
01488 v8::Number* v8::Number::Cast(v8::Value* that) {
01489 if (IsDeadCheck("v8::Number::Cast()")) return 0;
01490 i::Handle<i::Object> obj = Utils::OpenHandle(that);
01491 ApiCheck(obj->IsNumber(),
01492 "v8::Number::Cast()",
01493 "Could not convert to number");
01494 return static_cast<v8::Number*>(that);
01495 }
01496
01497
01498 v8::Integer* v8::Integer::Cast(v8::Value* that) {
01499 if (IsDeadCheck("v8::Integer::Cast()")) return 0;
01500 i::Handle<i::Object> obj = Utils::OpenHandle(that);
01501 ApiCheck(obj->IsNumber(),
01502 "v8::Integer::Cast()",
01503 "Could not convert to number");
01504 return static_cast<v8::Integer*>(that);
01505 }
01506
01507
01508 v8::Array* v8::Array::Cast(Value* that) {
01509 if (IsDeadCheck("v8::Array::Cast()")) return 0;
01510 i::Handle<i::Object> obj = Utils::OpenHandle(that);
01511 ApiCheck(obj->IsJSArray(),
01512 "v8::Array::Cast()",
01513 "Could not convert to array");
01514 return static_cast<v8::Array*>(that);
01515 }
01516
01517
01518 v8::Date* v8::Date::Cast(v8::Value* that) {
01519 if (IsDeadCheck("v8::Date::Cast()")) return 0;
01520 i::Handle<i::Object> obj = Utils::OpenHandle(that);
01521 ApiCheck(obj->HasSpecificClassOf(i::Heap::Date_symbol()),
01522 "v8::Date::Cast()",
01523 "Could not convert to date");
01524 return static_cast<v8::Date*>(that);
01525 }
01526
01527
01528 bool Value::BooleanValue() {
01529 if (IsDeadCheck("v8::Value::BooleanValue()")) return false;
01530 LOG_API("BooleanValue");
01531 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01532 i::Handle<i::Object> value =
01533 obj->IsBoolean() ? obj : i::Execution::ToBoolean(obj);
01534 return value->IsTrue();
01535 }
01536
01537
01538 double Value::NumberValue() {
01539 if (IsDeadCheck("v8::Value::NumberValue()")) return i::OS::nan_value();
01540 LOG_API("NumberValue");
01541 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01542 i::Handle<i::Object> num;
01543 if (obj->IsNumber()) {
01544 num = obj;
01545 } else {
01546 EXCEPTION_PREAMBLE();
01547 num = i::Execution::ToNumber(obj, &has_pending_exception);
01548 EXCEPTION_BAILOUT_CHECK(i::OS::nan_value());
01549 }
01550 return num->Number();
01551 }
01552
01553
01554 int64_t Value::IntegerValue() {
01555 if (IsDeadCheck("v8::Value::IntegerValue()")) return 0;
01556 LOG_API("IntegerValue");
01557 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01558 i::Handle<i::Object> num;
01559 if (obj->IsNumber()) {
01560 num = obj;
01561 } else {
01562 EXCEPTION_PREAMBLE();
01563 num = i::Execution::ToInteger(obj, &has_pending_exception);
01564 EXCEPTION_BAILOUT_CHECK(0);
01565 }
01566 if (num->IsSmi()) {
01567 return i::Smi::cast(*num)->value();
01568 } else {
01569 return static_cast<int64_t>(num->Number());
01570 }
01571 }
01572
01573
01574 Local<Int32> Value::ToInt32() {
01575 if (IsDeadCheck("v8::Value::ToInt32()")) return Local<Int32>();
01576 LOG_API("ToInt32");
01577 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01578 i::Handle<i::Object> num;
01579 if (obj->IsSmi()) {
01580 num = obj;
01581 } else {
01582 EXCEPTION_PREAMBLE();
01583 num = i::Execution::ToInt32(obj, &has_pending_exception);
01584 EXCEPTION_BAILOUT_CHECK(Local<Int32>());
01585 }
01586 return Local<Int32>(ToApi<Int32>(num));
01587 }
01588
01589
01590 Local<Uint32> Value::ToUint32() {
01591 if (IsDeadCheck("v8::Value::ToUint32()")) return Local<Uint32>();
01592 LOG_API("ToUInt32");
01593 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01594 i::Handle<i::Object> num;
01595 if (obj->IsSmi()) {
01596 num = obj;
01597 } else {
01598 EXCEPTION_PREAMBLE();
01599 num = i::Execution::ToUint32(obj, &has_pending_exception);
01600 EXCEPTION_BAILOUT_CHECK(Local<Uint32>());
01601 }
01602 return Local<Uint32>(ToApi<Uint32>(num));
01603 }
01604
01605
01606 Local<Uint32> Value::ToArrayIndex() {
01607 if (IsDeadCheck("v8::Value::ToArrayIndex()")) return Local<Uint32>();
01608 LOG_API("ToArrayIndex");
01609 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01610 if (obj->IsSmi()) {
01611 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
01612 return Local<Uint32>();
01613 }
01614 EXCEPTION_PREAMBLE();
01615 i::Handle<i::Object> string_obj =
01616 i::Execution::ToString(obj, &has_pending_exception);
01617 EXCEPTION_BAILOUT_CHECK(Local<Uint32>());
01618 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
01619 uint32_t index;
01620 if (str->AsArrayIndex(&index)) {
01621 i::Handle<i::Object> value;
01622 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
01623 value = i::Handle<i::Object>(i::Smi::FromInt(index));
01624 } else {
01625 value = i::Factory::NewNumber(index);
01626 }
01627 return Utils::Uint32ToLocal(value);
01628 }
01629 return Local<Uint32>();
01630 }
01631
01632
01633 int32_t Value::Int32Value() {
01634 if (IsDeadCheck("v8::Value::Int32Value()")) return 0;
01635 LOG_API("Int32Value");
01636 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01637 if (obj->IsSmi()) {
01638 return i::Smi::cast(*obj)->value();
01639 } else {
01640 LOG_API("Int32Value (slow)");
01641 EXCEPTION_PREAMBLE();
01642 i::Handle<i::Object> num =
01643 i::Execution::ToInt32(obj, &has_pending_exception);
01644 EXCEPTION_BAILOUT_CHECK(0);
01645 if (num->IsSmi()) {
01646 return i::Smi::cast(*num)->value();
01647 } else {
01648 return static_cast<int32_t>(num->Number());
01649 }
01650 }
01651 }
01652
01653
01654 bool Value::Equals(Handle<Value> that) {
01655 if (IsDeadCheck("v8::Value::Equals()")
01656 || EmptyCheck("v8::Value::Equals()", this)
01657 || EmptyCheck("v8::Value::Equals()", that))
01658 return false;
01659 LOG_API("Equals");
01660 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01661 i::Handle<i::Object> other = Utils::OpenHandle(*that);
01662 i::Object** args[1] = { other.location() };
01663 EXCEPTION_PREAMBLE();
01664 i::Handle<i::Object> result =
01665 CallV8HeapFunction("EQUALS", obj, 1, args, &has_pending_exception);
01666 EXCEPTION_BAILOUT_CHECK(false);
01667 return *result == i::Smi::FromInt(i::EQUAL);
01668 }
01669
01670
01671 bool Value::StrictEquals(Handle<Value> that) {
01672 if (IsDeadCheck("v8::Value::StrictEquals()")
01673 || EmptyCheck("v8::Value::StrictEquals()", this)
01674 || EmptyCheck("v8::Value::StrictEquals()", that))
01675 return false;
01676 LOG_API("StrictEquals");
01677 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01678 i::Handle<i::Object> other = Utils::OpenHandle(*that);
01679
01680 if (obj->IsHeapNumber()) {
01681 if (!other->IsNumber()) return false;
01682 double x = obj->Number();
01683 double y = other->Number();
01684
01685 return x == y && !isnan(x) && !isnan(y);
01686 } else if (*obj == *other) {
01687 return true;
01688 } else if (obj->IsSmi()) {
01689 return other->IsNumber() && obj->Number() == other->Number();
01690 } else if (obj->IsString()) {
01691 return other->IsString() &&
01692 i::String::cast(*obj)->Equals(i::String::cast(*other));
01693 } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
01694 return other->IsUndefined() || other->IsUndetectableObject();
01695 } else {
01696 return false;
01697 }
01698 }
01699
01700
01701 uint32_t Value::Uint32Value() {
01702 if (IsDeadCheck("v8::Value::Uint32Value()")) return 0;
01703 LOG_API("Uint32Value");
01704 i::Handle<i::Object> obj = Utils::OpenHandle(this);
01705 if (obj->IsSmi()) {
01706 return i::Smi::cast(*obj)->value();
01707 } else {
01708 EXCEPTION_PREAMBLE();
01709 i::Handle<i::Object> num =
01710 i::Execution::ToUint32(obj, &has_pending_exception);
01711 EXCEPTION_BAILOUT_CHECK(0);
01712 if (num->IsSmi()) {
01713 return i::Smi::cast(*num)->value();
01714 } else {
01715 return static_cast<uint32_t>(num->Number());
01716 }
01717 }
01718 }
01719
01720
01721 bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
01722 v8::PropertyAttribute attribs) {
01723 ON_BAILOUT("v8::Object::Set()", return false);
01724 i::Handle<i::Object> self = Utils::OpenHandle(this);
01725 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
01726 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
01727 EXCEPTION_PREAMBLE();
01728 i::Handle<i::Object> obj = i::SetProperty(
01729 self,
01730 key_obj,
01731 value_obj,
01732 static_cast<PropertyAttributes>(attribs));
01733 has_pending_exception = obj.is_null();
01734 EXCEPTION_BAILOUT_CHECK(false);
01735 return true;
01736 }
01737
01738
01739 Local<Value> v8::Object::Get(v8::Handle<Value> key) {
01740 ON_BAILOUT("v8::Object::Get()", return Local<v8::Value>());
01741 i::Handle<i::Object> self = Utils::OpenHandle(this);
01742 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
01743 EXCEPTION_PREAMBLE();
01744 i::Handle<i::Object> result = i::GetProperty(self, key_obj);
01745 has_pending_exception = result.is_null();
01746 EXCEPTION_BAILOUT_CHECK(Local<Value>());
01747 return Utils::ToLocal(result);
01748 }
01749
01750
01751 Local<Value> v8::Object::GetPrototype() {
01752 ON_BAILOUT("v8::Object::GetPrototype()", return Local<v8::Value>());
01753 i::Handle<i::Object> self = Utils::OpenHandle(this);
01754 i::Handle<i::Object> result = i::GetPrototype(self);
01755 return Utils::ToLocal(result);
01756 }
01757
01758
01759 Local<Array> v8::Object::GetPropertyNames() {
01760 ON_BAILOUT("v8::Object::GetPropertyNames()", return Local<v8::Array>());
01761 v8::HandleScope scope;
01762 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
01763 i::Handle<i::FixedArray> value = i::GetKeysInFixedArrayFor(self);
01764
01765
01766
01767 i::Handle<i::FixedArray> elms = i::Factory::CopyFixedArray(value);
01768 i::Handle<i::JSArray> result = i::Factory::NewJSArrayWithElements(elms);
01769 return scope.Close(Utils::ToLocal(result));
01770 }
01771
01772
01773 Local<String> v8::Object::ObjectProtoToString() {
01774 ON_BAILOUT("v8::Object::ObjectProtoToString()", return Local<v8::String>());
01775 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
01776
01777 i::Handle<i::Object> name(self->class_name());
01778
01779
01780
01781
01782
01783
01784 if (!name->IsString()) {
01785 return v8::String::New("[object ]");
01786
01787 } else {
01788 i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
01789 if (class_name->IsEqualTo(i::CStrVector("Arguments"))) {
01790 return v8::String::New("[object Object]");
01791
01792 } else {
01793 const char* prefix = "[object ";
01794 Local<String> str = Utils::ToLocal(class_name);
01795 const char* postfix = "]";
01796
01797 size_t prefix_len = strlen(prefix);
01798 size_t str_len = str->Length();
01799 size_t postfix_len = strlen(postfix);
01800
01801 size_t buf_len = prefix_len + str_len + postfix_len;
01802 char* buf = i::NewArray<char>(buf_len);
01803
01804
01805 char* ptr = buf;
01806 memcpy(ptr, prefix, prefix_len * v8::internal::kCharSize);
01807 ptr += prefix_len;
01808
01809
01810 str->WriteAscii(ptr, 0, str_len);
01811 ptr += str_len;
01812
01813
01814 memcpy(ptr, postfix, postfix_len * v8::internal::kCharSize);
01815
01816
01817 Local<String> result = v8::String::New(buf, buf_len);
01818 i::DeleteArray(buf);
01819 return result;
01820 }
01821 }
01822 }
01823
01824
01825 bool v8::Object::Delete(v8::Handle<String> key) {
01826 ON_BAILOUT("v8::Object::Delete()", return false);
01827 HandleScope scope;
01828 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
01829 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
01830 return i::DeleteProperty(self, key_obj)->IsTrue();
01831 }
01832
01833
01834 bool v8::Object::Has(v8::Handle<String> key) {
01835 ON_BAILOUT("v8::Object::Has()", return false);
01836 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
01837 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
01838 return self->HasProperty(*key_obj);
01839 }
01840
01841
01842 bool v8::Object::Delete(uint32_t index) {
01843 ON_BAILOUT("v8::Object::DeleteProperty()", return false);
01844 HandleScope scope;
01845 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
01846 return i::DeleteElement(self, index)->IsTrue();
01847 }
01848
01849
01850 bool v8::Object::Has(uint32_t index) {
01851 ON_BAILOUT("v8::Object::HasProperty()", return false);
01852 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
01853 return self->HasElement(index);
01854 }
01855
01856
01857 bool v8::Object::HasRealNamedProperty(Handle<String> key) {
01858 ON_BAILOUT("v8::Object::HasRealNamedProperty()", return false);
01859 return Utils::OpenHandle(this)->HasRealNamedProperty(
01860 *Utils::OpenHandle(*key));
01861 }
01862
01863
01864 bool v8::Object::HasRealIndexedProperty(uint32_t index) {
01865 ON_BAILOUT("v8::Object::HasRealIndexedProperty()", return false);
01866 return Utils::OpenHandle(this)->HasRealElementProperty(index);
01867 }
01868
01869
01870 bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
01871 ON_BAILOUT("v8::Object::HasRealNamedCallbackProperty()", return false);
01872 return Utils::OpenHandle(this)->HasRealNamedCallbackProperty(
01873 *Utils::OpenHandle(*key));
01874 }
01875
01876
01877 bool v8::Object::HasNamedLookupInterceptor() {
01878 ON_BAILOUT("v8::Object::HasNamedLookupInterceptor()", return false);
01879 return Utils::OpenHandle(this)->HasNamedInterceptor();
01880 }
01881
01882
01883 bool v8::Object::HasIndexedLookupInterceptor() {
01884 ON_BAILOUT("v8::Object::HasIndexedLookupInterceptor()", return false);
01885 return Utils::OpenHandle(this)->HasIndexedInterceptor();
01886 }
01887
01888
01889 Handle<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
01890 Handle<String> key) {
01891 ON_BAILOUT("v8::Object::GetRealNamedPropertyInPrototypeChain()",
01892 return Local<Value>());
01893 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
01894 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
01895 i::LookupResult lookup;
01896 self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
01897 if (lookup.IsValid()) {
01898 PropertyAttributes attributes;
01899 i::Handle<i::Object> result(self_obj->GetProperty(*self_obj,
01900 &lookup,
01901 *key_obj,
01902 &attributes));
01903 return Utils::ToLocal(result);
01904 }
01905 return Local<Value>();
01906 }
01907
01908
01909
01910
01911
01912 void v8::Object::TurnOnAccessCheck() {
01913 ON_BAILOUT("v8::Object::TurnOnAccessCheck()", return);
01914 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
01915
01916 i::Handle<i::Map> new_map =
01917 i::Factory::CopyMapDropTransitions(i::Handle<i::Map>(obj->map()));
01918 new_map->set_is_access_check_needed();
01919 obj->set_map(*new_map);
01920 }
01921
01922
01923 Local<v8::Object> Function::NewInstance() {
01924 return NewInstance(0, NULL);
01925 }
01926
01927
01928 Local<v8::Object> Function::NewInstance(int argc,
01929 v8::Handle<v8::Value> argv[]) {
01930 ON_BAILOUT("v8::Function::NewInstance()", return Local<v8::Object>());
01931 LOG_API("Function::NewInstance");
01932 HandleScope scope;
01933 i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
01934 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
01935 i::Object*** args = reinterpret_cast<i::Object***>(argv);
01936 EXCEPTION_PREAMBLE();
01937 i::Handle<i::Object> returned =
01938 i::Execution::New(function, argc, args, &has_pending_exception);
01939 EXCEPTION_BAILOUT_CHECK(Local<v8::Object>());
01940 return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
01941 }
01942
01943
01944 Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
01945 v8::Handle<v8::Value> argv[]) {
01946 ON_BAILOUT("v8::Function::Call()", return Local<v8::Value>());
01947 LOG_API("Function::Call");
01948 i::Object* raw_result = NULL;
01949 {
01950 HandleScope scope;
01951 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
01952 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
01953 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
01954 i::Object*** args = reinterpret_cast<i::Object***>(argv);
01955 EXCEPTION_PREAMBLE();
01956 i::Handle<i::Object> returned =
01957 i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
01958 EXCEPTION_BAILOUT_CHECK(Local<Object>());
01959 raw_result = *returned;
01960 }
01961 i::Handle<i::Object> result(raw_result);
01962 return Utils::ToLocal(result);
01963 }
01964
01965
01966 void Function::SetName(v8::Handle<v8::String> name) {
01967 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
01968 func->shared()->set_name(*Utils::OpenHandle(*name));
01969 }
01970
01971
01972 Handle<Value> Function::GetName() {
01973 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
01974 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name()));
01975 }
01976
01977
01978 int String::Length() {
01979 if (IsDeadCheck("v8::String::Length()")) return 0;
01980 return Utils::OpenHandle(this)->length();
01981 }
01982
01983
01984 int String::Utf8Length() {
01985 if (IsDeadCheck("v8::String::Utf8Length()")) return 0;
01986 return Utils::OpenHandle(this)->Utf8Length();
01987 }
01988
01989
01990 int String::WriteUtf8(char* buffer, int capacity) {
01991 if (IsDeadCheck("v8::String::WriteUtf8()")) return 0;
01992 LOG_API("String::WriteUtf8");
01993 i::Handle<i::String> str = Utils::OpenHandle(this);
01994 write_input_buffer.Reset(0, *str);
01995 int len = str->length();
01996
01997
01998
01999 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1);
02000 int i;
02001 int pos = 0;
02002 for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) {
02003 i::uc32 c = write_input_buffer.GetNext();
02004 int written = unibrow::Utf8::Encode(buffer + pos, c);
02005 pos += written;
02006 }
02007 if (i < len) {
02008
02009
02010
02011 char intermediate[unibrow::Utf8::kMaxEncodedSize];
02012 for (; i < len && pos < capacity; i++) {
02013 i::uc32 c = write_input_buffer.GetNext();
02014 int written = unibrow::Utf8::Encode(intermediate, c);
02015 if (pos + written <= capacity) {
02016 for (int j = 0; j < written; j++)
02017 buffer[pos + j] = intermediate[j];
02018 pos += written;
02019 } else {
02020
02021 break;
02022 }
02023 }
02024 }
02025 if (i == len && (capacity == -1 || pos < capacity))
02026 buffer[pos++] = '\0';
02027 return pos;
02028 }
02029
02030
02031 int String::WriteAscii(char* buffer, int start, int length) {
02032 if (IsDeadCheck("v8::String::WriteAscii()")) return 0;
02033 LOG_API("String::WriteAscii");
02034 ASSERT(start >= 0 && length >= -1);
02035 i::Handle<i::String> str = Utils::OpenHandle(this);
02036
02037
02038 str->TryFlatten();
02039 int end = length;
02040 if ( (length == -1) || (length > str->length() - start) )
02041 end = str->length() - start;
02042 if (end < 0) return 0;
02043 write_input_buffer.Reset(start, *str);
02044 int i;
02045 for (i = 0; i < end; i++) {
02046 char c = static_cast<char>(write_input_buffer.GetNext());
02047 if (c == '\0') c = ' ';
02048 buffer[i] = c;
02049 }
02050 if (length == -1 || i < length)
02051 buffer[i] = '\0';
02052 return i;
02053 }
02054
02055
02056 int String::Write(uint16_t* buffer, int start, int length) {
02057 if (IsDeadCheck("v8::String::Write()")) return 0;
02058 LOG_API("String::Write");
02059 ASSERT(start >= 0 && length >= -1);
02060 i::Handle<i::String> str = Utils::OpenHandle(this);
02061
02062
02063 str->TryFlatten();
02064 int end = length;
02065 if ( (length == -1) || (length > str->length() - start) )
02066 end = str->length() - start;
02067 if (end < 0) return 0;
02068 write_input_buffer.Reset(start, *str);
02069 int i;
02070 for (i = 0; i < end; i++)
02071 buffer[i] = write_input_buffer.GetNext();
02072 if (length == -1 || i < length)
02073 buffer[i] = '\0';
02074 return i;
02075 }
02076
02077
02078 bool v8::String::IsExternal() {
02079 EnsureInitialized("v8::String::IsExternal()");
02080 i::Handle<i::String> str = Utils::OpenHandle(this);
02081 return str->IsExternalTwoByteString();
02082 }
02083
02084
02085 bool v8::String::IsExternalAscii() {
02086 EnsureInitialized("v8::String::IsExternalAscii()");
02087 i::Handle<i::String> str = Utils::OpenHandle(this);
02088 return str->IsExternalAsciiString();
02089 }
02090
02091
02092 v8::String::ExternalStringResource* v8::String::GetExternalStringResource() {
02093 EnsureInitialized("v8::String::GetExternalStringResource()");
02094 i::Handle<i::String> str = Utils::OpenHandle(this);
02095 ASSERT(str->IsExternalTwoByteString());
02096 void* resource = i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
02097 return reinterpret_cast<ExternalStringResource*>(resource);
02098 }
02099
02100
02101 v8::String::ExternalAsciiStringResource*
02102 v8::String::GetExternalAsciiStringResource() {
02103 EnsureInitialized("v8::String::GetExternalAsciiStringResource()");
02104 i::Handle<i::String> str = Utils::OpenHandle(this);
02105 ASSERT(str->IsExternalAsciiString());
02106 void* resource = i::Handle<i::ExternalAsciiString>::cast(str)->resource();
02107 return reinterpret_cast<ExternalAsciiStringResource*>(resource);
02108 }
02109
02110
02111 double Number::Value() {
02112 if (IsDeadCheck("v8::Number::Value()")) return 0;
02113 i::Handle<i::Object> obj = Utils::OpenHandle(this);
02114 return obj->Number();
02115 }
02116
02117
02118 bool Boolean::Value() {
02119 if (IsDeadCheck("v8::Boolean::Value()")) return false;
02120 i::Handle<i::Object> obj = Utils::OpenHandle(this);
02121 return obj->IsTrue();
02122 }
02123
02124
02125 int64_t Integer::Value() {
02126 if (IsDeadCheck("v8::Integer::Value()")) return 0;
02127 i::Handle<i::Object> obj = Utils::OpenHandle(this);
02128 if (obj->IsSmi()) {
02129 return i::Smi::cast(*obj)->value();
02130 } else {
02131 return static_cast<int64_t>(obj->Number());
02132 }
02133 }
02134
02135
02136 int32_t Int32::Value() {
02137 if (IsDeadCheck("v8::Int32::Value()")) return 0;
02138 i::Handle<i::Object> obj = Utils::OpenHandle(this);
02139 if (obj->IsSmi()) {
02140 return i::Smi::cast(*obj)->value();
02141 } else {
02142 return static_cast<int32_t>(obj->Number());
02143 }
02144 }
02145
02146
02147 void* External::Value() {
02148 if (IsDeadCheck("v8::External::Value()")) return 0;
02149 i::Handle<i::Object> obj = Utils::OpenHandle(this);
02150 return reinterpret_cast<void*>(i::Proxy::cast(*obj)->proxy());
02151 }
02152
02153
02154 int v8::Object::InternalFieldCount() {
02155 if (IsDeadCheck("v8::Object::InternalFieldCount()")) return 0;
02156 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
02157 return obj->GetInternalFieldCount();
02158 }
02159
02160
02161 Local<Value> v8::Object::GetInternalField(int index) {
02162 if (IsDeadCheck("v8::Object::GetInternalField()")) return Local<Value>();
02163 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
02164 if (!ApiCheck(index < obj->GetInternalFieldCount(),
02165 "v8::Object::GetInternalField()",
02166 "Reading internal field out of bounds")) {
02167 return Local<Value>();
02168 }
02169 i::Handle<i::Object> value(obj->GetInternalField(index));
02170 return Utils::ToLocal(value);
02171 }
02172
02173
02174 void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
02175 if (IsDeadCheck("v8::Object::SetInternalField()")) return;
02176 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
02177 if (!ApiCheck(index < obj->GetInternalFieldCount(),
02178 "v8::Object::SetInternalField()",
02179 "Writing internal field out of bounds")) {
02180 return;
02181 }
02182 i::Handle<i::Object> val = Utils::OpenHandle(*value);
02183 obj->SetInternalField(index, *val);
02184 }
02185
02186
02187
02188
02189 bool v8::V8::Initialize() {
02190 if (i::V8::HasBeenSetup()) return true;
02191 HandleScope scope;
02192 if (i::Snapshot::Initialize()) {
02193 i::Serializer::disable();
02194 return true;
02195 } else {
02196 return i::V8::Initialize(NULL);
02197 }
02198 }
02199
02200
02201 const char* v8::V8::GetVersion() {
02202 return "0.4.2.1";
02203 }
02204
02205
02206 static i::Handle<i::FunctionTemplateInfo>
02207 EnsureConstructor(i::Handle<i::ObjectTemplateInfo> templ) {
02208 if (templ->constructor()->IsUndefined()) {
02209 Local<FunctionTemplate> constructor = FunctionTemplate::New();
02210 Utils::OpenHandle(*constructor)->set_instance_template(*templ);
02211 templ->set_constructor(*Utils::OpenHandle(*constructor));
02212 }
02213 return i::Handle<i::FunctionTemplateInfo>(
02214 i::FunctionTemplateInfo::cast(templ->constructor()));
02215 }
02216
02217
02218 Persistent<Context> v8::Context::New(
02219 v8::ExtensionConfiguration* extensions,
02220 v8::Handle<ObjectTemplate> global_template,
02221 v8::Handle<Value> global_object) {
02222 EnsureInitialized("v8::Context::New()");
02223 LOG_API("Context::New");
02224 ON_BAILOUT("v8::Context::New()", return Persistent<Context>());
02225
02226
02227 if (!global_template.IsEmpty()) {
02228 i::Handle<i::FunctionTemplateInfo> constructor =
02229 EnsureConstructor(Utils::OpenHandle(*global_template));
02230
02231
02232 Local<ObjectTemplate> proxy_template = ObjectTemplate::New();
02233
02234 i::Handle<i::FunctionTemplateInfo> proxy_constructor =
02235 EnsureConstructor(Utils::OpenHandle(*proxy_template));
02236
02237
02238
02239 proxy_constructor->set_prototype_template(
02240 *Utils::OpenHandle(*global_template));
02241
02242
02243 if (!constructor->access_check_info()->IsUndefined()) {
02244 proxy_constructor->set_access_check_info(
02245 constructor->access_check_info());
02246 proxy_constructor->set_needs_access_check(true);
02247
02248
02249 constructor->set_needs_access_check(false);
02250 constructor->set_access_check_info(i::Heap::undefined_value());
02251 }
02252
02253 global_template = proxy_template;
02254 }
02255
02256 i::Handle<i::Context> env = i::Bootstrapper::CreateEnvironment(
02257 Utils::OpenHandle(*global_object),
02258 global_template, extensions);
02259 if (!ApiCheck(!env.is_null(),
02260 "v8::Context::New()",
02261 "Could not initialize environment"))
02262 return Persistent<Context>();
02263 return Persistent<Context>(Utils::ToLocal(env));
02264 }
02265
02266
02267 void v8::Context::SetSecurityToken(Handle<Value> token) {
02268 if (IsDeadCheck("v8::Context::SetSecurityToken()")) return;
02269 i::Handle<i::Context> env = Utils::OpenHandle(this);
02270 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
02271 env->set_security_token(*token_handle);
02272 }
02273
02274
02275 void v8::Context::UseDefaultSecurityToken() {
02276 if (IsDeadCheck("v8::Context::UseDefaultSecurityToken()")) return;
02277 i::Handle<i::Context> env = Utils::OpenHandle(this);
02278 env->set_security_token(env->global());
02279 }
02280
02281
02282 Handle<Value> v8::Context::GetSecurityToken() {
02283 if (IsDeadCheck("v8::Context::GetSecurityToken()")) return Handle<Value>();
02284 i::Handle<i::Context> env = Utils::OpenHandle(this);
02285 i::Object* security_token = env->security_token();
02286 i::Handle<i::Object> token_handle(security_token);
02287 return Utils::ToLocal(token_handle);
02288 }
02289
02290
02291 bool Context::HasOutOfMemoryException() {
02292 i::Handle<i::Context> env = Utils::OpenHandle(this);
02293 return env->has_out_of_memory();
02294 }
02295
02296
02297 bool Context::InContext() {
02298 return i::Top::context() != NULL;
02299 }
02300
02301
02302 v8::Local<v8::Context> Context::GetEntered() {
02303 if (IsDeadCheck("v8::Context::GetEntered()")) return Local<Context>();
02304 i::Handle<i::Object> last = thread_local.LastEnteredContext();
02305 if (last.is_null()) return Local<Context>();
02306 i::Handle<i::Context> context = i::Handle<i::Context>::cast(last);
02307 return Utils::ToLocal(context);
02308 }
02309
02310
02311 v8::Local<v8::Context> Context::GetCurrent() {
02312 if (IsDeadCheck("v8::Context::GetCurrent()")) return Local<Context>();
02313 i::Handle<i::Context> context(i::Top::global_context());
02314 return Utils::ToLocal(context);
02315 }
02316
02317
02318 v8::Local<v8::Object> Context::Global() {
02319 if (IsDeadCheck("v8::Context::Global()")) return Local<v8::Object>();
02320 i::Object** ctx = reinterpret_cast<i::Object**>(this);
02321 i::Handle<i::Context> context =
02322 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
02323 i::Handle<i::Object> global(context->global_proxy());
02324 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
02325 }
02326
02327
02328 void Context::DetachGlobal() {
02329 if (IsDeadCheck("v8::Context::DetachGlobal()")) return;
02330 i::Object** ctx = reinterpret_cast<i::Object**>(this);
02331 i::Handle<i::Context> context =
02332 i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
02333 i::Bootstrapper::DetachGlobal(context);
02334 }
02335
02336
02337 Local<v8::Object> ObjectTemplate::NewInstance() {
02338 ON_BAILOUT("v8::ObjectTemplate::NewInstance()", return Local<v8::Object>());
02339 LOG_API("ObjectTemplate::NewInstance");
02340 EXCEPTION_PREAMBLE();
02341 i::Handle<i::Object> obj =
02342 i::Execution::InstantiateObject(Utils::OpenHandle(this),
02343 &has_pending_exception);
02344 EXCEPTION_BAILOUT_CHECK(Local<v8::Object>());
02345 return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
02346 }
02347
02348
02349 Local<v8::Function> FunctionTemplate::GetFunction() {
02350 ON_BAILOUT("v8::FunctionTemplate::GetFunction()",
02351 return Local<v8::Function>());
02352 LOG_API("FunctionTemplate::GetFunction");
02353 EXCEPTION_PREAMBLE();
02354 i::Handle<i::Object> obj =
02355 i::Execution::InstantiateFunction(Utils::OpenHandle(this),
02356 &has_pending_exception);
02357 EXCEPTION_BAILOUT_CHECK(Local<v8::Function>());
02358 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
02359 }
02360
02361
02362 bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
02363 ON_BAILOUT("v8::FunctionTemplate::HasInstanceOf()", return false);
02364 i::Object* obj = *Utils::OpenHandle(*value);
02365 return obj->IsInstanceOf(*Utils::OpenHandle(this));
02366 }
02367
02368
02369 Local<External> v8::External::New(void* data) {
02370 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
02371 LOG_API("External::New");
02372 EnsureInitialized("v8::External::New()");
02373 i::Handle<i::Proxy> obj = i::Factory::NewProxy(static_cast<i::Address>(data));
02374 return Utils::ToLocal(obj);
02375 }
02376
02377
02378 Local<String> v8::String::New(const char* data, int length) {
02379 EnsureInitialized("v8::String::New()");
02380 LOG_API("String::New(char)");
02381 if (length == -1) length = strlen(data);
02382 i::Handle<i::String> result =
02383 i::Factory::NewStringFromUtf8(i::Vector<const char>(data, length));
02384 return Utils::ToLocal(result);
02385 }
02386
02387
02388 Local<String> v8::String::NewUndetectable(const char* data, int length) {
02389 EnsureInitialized("v8::String::NewUndetectable()");
02390 LOG_API("String::NewUndetectable(char)");
02391 if (length == -1) length = strlen(data);
02392 i::Handle<i::String> result =
02393 i::Factory::NewStringFromUtf8(i::Vector<const char>(data, length));
02394 result->MarkAsUndetectable();
02395 return Utils::ToLocal(result);
02396 }
02397
02398
02399 static int TwoByteStringLength(const uint16_t* data) {
02400 int length = 0;
02401 while (data[length] != '\0') length++;
02402 return length;
02403 }
02404
02405
02406 Local<String> v8::String::New(const uint16_t* data, int length) {
02407 EnsureInitialized("v8::String::New()");
02408 LOG_API("String::New(uint16_)");
02409 if (length == -1) length = TwoByteStringLength(data);
02410 i::Handle<i::String> result =
02411 i::Factory::NewStringFromTwoByte(i::Vector<const uint16_t>(data, length));
02412 return Utils::ToLocal(result);
02413 }
02414
02415
02416 Local<String> v8::String::NewUndetectable(const uint16_t* data, int length) {
02417 EnsureInitialized("v8::String::NewUndetectable()");
02418 LOG_API("String::NewUndetectable(uint16_)");
02419 if (length == -1) length = TwoByteStringLength(data);
02420 i::Handle<i::String> result =
02421 i::Factory::NewStringFromTwoByte(i::Vector<const uint16_t>(data, length));
02422 result->MarkAsUndetectable();
02423 return Utils::ToLocal(result);
02424 }
02425
02426
02427 i::Handle<i::String> NewExternalStringHandle(
02428 v8::String::ExternalStringResource* resource) {
02429 i::Handle<i::String> result =
02430 i::Factory::NewExternalStringFromTwoByte(resource);
02431 return result;
02432 }
02433
02434
02435 i::Handle<i::String> NewExternalAsciiStringHandle(
02436 v8::String::ExternalAsciiStringResource* resource) {
02437 i::Handle<i::String> result =
02438 i::Factory::NewExternalStringFromAscii(resource);
02439 return result;
02440 }
02441
02442
02443 static void DisposeExternalString(v8::Persistent<v8::Value> obj,
02444 void* parameter) {
02445 v8::String::ExternalStringResource* resource =
02446 reinterpret_cast<v8::String::ExternalStringResource*>(parameter);
02447 const size_t total_size = resource->length() * sizeof(*resource->data());
02448 i::Counters::total_external_string_memory.Decrement(total_size);
02449 delete resource;
02450 obj.Dispose();
02451 }
02452
02453
02454 static void DisposeExternalAsciiString(v8::Persistent<v8::Value> obj,
02455 void* parameter) {
02456 v8::String::ExternalAsciiStringResource* resource =
02457 reinterpret_cast<v8::String::ExternalAsciiStringResource*>(parameter);
02458 const size_t total_size = resource->length() * sizeof(*resource->data());
02459 i::Counters::total_external_string_memory.Decrement(total_size);
02460 delete resource;
02461 obj.Dispose();
02462 }
02463
02464
02465 Local<String> v8::String::NewExternal(
02466 v8::String::ExternalStringResource* resource) {
02467 EnsureInitialized("v8::String::NewExternal()");
02468 LOG_API("String::NewExternal");
02469 const size_t total_size = resource->length() * sizeof(*resource->data());
02470 i::Counters::total_external_string_memory.Increment(total_size);
02471 i::Handle<i::String> result = NewExternalStringHandle(resource);
02472 i::Handle<i::Object> handle = i::GlobalHandles::Create(*result);
02473 i::GlobalHandles::MakeWeak(handle.location(),
02474 resource,
02475 &DisposeExternalString);
02476 return Utils::ToLocal(result);
02477 }
02478
02479
02480 Local<String> v8::String::NewExternal(
02481 v8::String::ExternalAsciiStringResource* resource) {
02482 EnsureInitialized("v8::String::NewExternal()");
02483 LOG_API("String::NewExternal");
02484 const size_t total_size = resource->length() * sizeof(*resource->data());
02485 i::Counters::total_external_string_memory.Increment(total_size);
02486 i::Handle<i::String> result = NewExternalAsciiStringHandle(resource);
02487 i::Handle<i::Object> handle = i::GlobalHandles::Create(*result);
02488 i::GlobalHandles::MakeWeak(handle.location(),
02489 resource,
02490 &DisposeExternalAsciiString);
02491 return Utils::ToLocal(result);
02492 }
02493
02494
02495 Local<v8::Object> v8::Object::New() {
02496 EnsureInitialized("v8::Object::New()");
02497 LOG_API("Object::New");
02498 i::Handle<i::JSObject> obj =
02499 i::Factory::NewJSObject(i::Top::object_function());
02500 return Utils::ToLocal(obj);
02501 }
02502
02503
02504 Local<v8::Value> v8::Date::New(double time) {
02505 EnsureInitialized("v8::Date::New()");
02506 LOG_API("Date::New");
02507 EXCEPTION_PREAMBLE();
02508 i::Handle<i::Object> obj =
02509 i::Execution::NewDate(time, &has_pending_exception);
02510 EXCEPTION_BAILOUT_CHECK(Local<v8::Value>());
02511 return Utils::ToLocal(obj);
02512 }
02513
02514
02515 double v8::Date::NumberValue() {
02516 if (IsDeadCheck("v8::Date::NumberValue()")) return 0;
02517 LOG_API("Date::NumberValue");
02518 i::Handle<i::Object> obj = Utils::OpenHandle(this);
02519 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
02520 return jsvalue->value()->Number();
02521 }
02522
02523
02524 Local<v8::Array> v8::Array::New(int length) {
02525 EnsureInitialized("v8::Array::New()");
02526 LOG_API("Array::New");
02527 i::Handle<i::JSArray> obj = i::Factory::NewJSArray(length);
02528 return Utils::ToLocal(obj);
02529 }
02530
02531
02532 uint32_t v8::Array::Length() {
02533 if (IsDeadCheck("v8::Array::Length()")) return 0;
02534 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
02535 i::Object* length = obj->length();
02536 if (length->IsSmi()) {
02537 return i::Smi::cast(length)->value();
02538 } else {
02539 return static_cast<uint32_t>(length->Number());
02540 }
02541 }
02542
02543
02544 Local<String> v8::String::NewSymbol(const char* data, int length) {
02545 EnsureInitialized("v8::String::NewSymbol()");
02546 LOG_API("String::NewSymbol(char)");
02547 if (length == -1) length = strlen(data);
02548 i::Handle<i::String> result =
02549 i::Factory::LookupSymbol(i::Vector<const char>(data, length));
02550 return Utils::ToLocal(result);
02551 }
02552
02553
02554 Local<Number> v8::Number::New(double value) {
02555 EnsureInitialized("v8::Number::New()");
02556 i::Handle<i::Object> result = i::Factory::NewNumber(value);
02557 return Utils::NumberToLocal(result);
02558 }
02559
02560
02561 Local<Integer> v8::Integer::New(int32_t value) {
02562 EnsureInitialized("v8::Integer::New()");
02563 if (i::Smi::IsValid(value)) {
02564 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value)));
02565 }
02566 i::Handle<i::Object> result = i::Factory::NewNumber(value);
02567 return Utils::IntegerToLocal(result);
02568 }
02569
02570
02571 void V8::IgnoreOutOfMemoryException() {
02572 thread_local.SetIgnoreOutOfMemory(true);
02573 }
02574
02575
02576 bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
02577 EnsureInitialized("v8::V8::AddMessageListener()");
02578 ON_BAILOUT("v8::V8::AddMessageListener()", return false);
02579 HandleScope scope;
02580 NeanderArray listeners(i::Factory::message_listeners());
02581 NeanderObject obj(2);
02582 obj.set(0, *i::Factory::NewProxy(FUNCTION_ADDR(that)));
02583 obj.set(1, data.IsEmpty() ?
02584 i::Heap::undefined_value() :
02585 *Utils::OpenHandle(*data));
02586 listeners.add(obj.value());
02587 return true;
02588 }
02589
02590
02591 void V8::RemoveMessageListeners(MessageCallback that) {
02592 EnsureInitialized("v8::V8::RemoveMessageListener()");
02593 ON_BAILOUT("v8::V8::RemoveMessageListeners()", return);
02594 HandleScope scope;
02595 NeanderArray listeners(i::Factory::message_listeners());
02596 for (int i = 0; i < listeners.length(); i++) {
02597 if (listeners.get(i)->IsUndefined()) continue;
02598
02599 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
02600 i::Handle<i::Proxy> callback_obj(i::Proxy::cast(listener.get(0)));
02601 if (callback_obj->proxy() == FUNCTION_ADDR(that)) {
02602 listeners.set(i, i::Heap::undefined_value());
02603 }
02604 }
02605 }
02606
02607
02608 void V8::SetCounterFunction(CounterLookupCallback callback) {
02609 if (IsDeadCheck("v8::V8::SetCounterFunction()")) return;
02610 i::StatsTable::SetCounterFunction(callback);
02611 }
02612
02613
02614 void V8::EnableSlidingStateWindow() {
02615 if (IsDeadCheck("v8::V8::EnableSlidingStateWindow()")) return;
02616 i::Logger::EnableSlidingStateWindow();
02617 }
02618
02619
02620 void V8::SetFailedAccessCheckCallbackFunction(
02621 FailedAccessCheckCallback callback) {
02622 if (IsDeadCheck("v8::V8::SetFailedAccessCheckCallbackFunction()")) return;
02623 i::Top::SetFailedAccessCheckCallback(callback);
02624 }
02625
02626
02627 void V8::AddObjectToGroup(void* group_id, Persistent<Object> obj) {
02628 if (IsDeadCheck("v8::V8::AddObjectToGroup()")) return;
02629 i::GlobalHandles::AddToGroup(group_id, reinterpret_cast<i::Object**>(*obj));
02630 }
02631
02632
02633 int V8::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
02634 if (IsDeadCheck("v8::V8::AdjustAmountOfExternalAllocatedMemory()")) return 0;
02635 return i::Heap::AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
02636 }
02637
02638
02639 void V8::SetGlobalGCPrologueCallback(GCCallback callback) {
02640 if (IsDeadCheck("v8::V8::SetGlobalGCPrologueCallback()")) return;
02641 i::Heap::SetGlobalGCPrologueCallback(callback);
02642 }
02643
02644
02645 void V8::SetGlobalGCEpilogueCallback(GCCallback callback) {
02646 if (IsDeadCheck("v8::V8::SetGlobalGCEpilogueCallback()")) return;
02647 i::Heap::SetGlobalGCEpilogueCallback(callback);
02648 }
02649
02650
02651 String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj) {
02652 EnsureInitialized("v8::String::Utf8Value::Utf8Value()");
02653 if (obj.IsEmpty()) {
02654 str_ = NULL;
02655 length_ = 0;
02656 return;
02657 }
02658 HandleScope scope;
02659 TryCatch try_catch;
02660 Handle<String> str = obj->ToString();
02661 if (str.IsEmpty()) {
02662 str_ = NULL;
02663 length_ = 0;
02664 } else {
02665 length_ = str->Utf8Length();
02666 str_ = i::NewArray<char>(length_ + 1);
02667 str->WriteUtf8(str_);
02668 }
02669 }
02670
02671
02672 String::Utf8Value::~Utf8Value() {
02673 i::DeleteArray(str_);
02674 }
02675
02676
02677 String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj) {
02678 EnsureInitialized("v8::String::AsciiValue::AsciiValue()");
02679 if (obj.IsEmpty()) {
02680 str_ = NULL;
02681 length_ = 0;
02682 return;
02683 }
02684 HandleScope scope;
02685 TryCatch try_catch;
02686 Handle<String> str = obj->ToString();
02687 if (str.IsEmpty()) {
02688 str_ = NULL;
02689 length_ = 0;
02690 } else {
02691 length_ = str->Length();
02692 str_ = i::NewArray<char>(length_ + 1);
02693 str->WriteAscii(str_);
02694 }
02695 }
02696
02697
02698 String::AsciiValue::~AsciiValue() {
02699 i::DeleteArray(str_);
02700 }
02701
02702
02703 String::Value::Value(v8::Handle<v8::Value> obj) {
02704 EnsureInitialized("v8::String::Value::Value()");
02705 if (obj.IsEmpty()) {
02706 str_ = NULL;
02707 length_ = 0;
02708 return;
02709 }
02710 HandleScope scope;
02711 TryCatch try_catch;
02712 Handle<String> str = obj->ToString();
02713 if (str.IsEmpty()) {
02714 str_ = NULL;
02715 length_ = 0;
02716 } else {
02717 length_ = str->Length();
02718 str_ = i::NewArray<uint16_t>(length_ + 1);
02719 str->Write(str_);
02720 }
02721 }
02722
02723
02724 String::Value::~Value() {
02725 i::DeleteArray(str_);
02726 }
02727
02728 Local<Value> Exception::RangeError(v8::Handle<v8::String> raw_message) {
02729 LOG_API("RangeError");
02730 ON_BAILOUT("v8::Exception::RangeError()", return Local<Value>());
02731 i::Object* error;
02732 {
02733 HandleScope scope;
02734 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
02735 i::Handle<i::Object> result = i::Factory::NewRangeError(message);
02736 error = *result;
02737 }
02738 i::Handle<i::Object> result(error);
02739 return Utils::ToLocal(result);
02740 }
02741
02742 Local<Value> Exception::ReferenceError(v8::Handle<v8::String> raw_message) {
02743 LOG_API("ReferenceError");
02744 ON_BAILOUT("v8::Exception::ReferenceError()", return Local<Value>());
02745 i::Object* error;
02746 {
02747 HandleScope scope;
02748 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
02749 i::Handle<i::Object> result = i::Factory::NewReferenceError(message);
02750 error = *result;
02751 }
02752 i::Handle<i::Object> result(error);
02753 return Utils::ToLocal(result);
02754 }
02755
02756 Local<Value> Exception::SyntaxError(v8::Handle<v8::String> raw_message) {
02757 LOG_API("SyntaxError");
02758 ON_BAILOUT("v8::Exception::SyntaxError()", return Local<Value>());
02759 i::Object* error;
02760 {
02761 HandleScope scope;
02762 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
02763 i::Handle<i::Object> result = i::Factory::NewSyntaxError(message);
02764 error = *result;
02765 }
02766 i::Handle<i::Object> result(error);
02767 return Utils::ToLocal(result);
02768 }
02769
02770 Local<Value> Exception::TypeError(v8::Handle<v8::String> raw_message) {
02771 LOG_API("TypeError");
02772 ON_BAILOUT("v8::Exception::TypeError()", return Local<Value>());
02773 i::Object* error;
02774 {
02775 HandleScope scope;
02776 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
02777 i::Handle<i::Object> result = i::Factory::NewTypeError(message);
02778 error = *result;
02779 }
02780 i::Handle<i::Object> result(error);
02781 return Utils::ToLocal(result);
02782 }
02783
02784 Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
02785 LOG_API("Error");
02786 ON_BAILOUT("v8::Exception::Error()", return Local<Value>());
02787 i::Object* error;
02788 {
02789 HandleScope scope;
02790 i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
02791 i::Handle<i::Object> result = i::Factory::NewError(message);
02792 error = *result;
02793 }
02794 i::Handle<i::Object> result(error);
02795 return Utils::ToLocal(result);
02796 }
02797
02798
02799
02800
02801
02802 bool Debug::AddDebugEventListener(DebugEventCallback that, Handle<Value> data) {
02803 EnsureInitialized("v8::Debug::AddDebugEventListener()");
02804 ON_BAILOUT("v8::Debug::AddDebugEventListener()", return false);
02805 HandleScope scope;
02806 NeanderArray listeners(i::Factory::debug_event_listeners());
02807 NeanderObject obj(2);
02808 obj.set(0, *i::Factory::NewProxy(FUNCTION_ADDR(that)));
02809 obj.set(1, data.IsEmpty() ?
02810 i::Heap::undefined_value() :
02811 *Utils::OpenHandle(*data));
02812 listeners.add(obj.value());
02813 i::Debugger::UpdateActiveDebugger();
02814 return true;
02815 }
02816
02817
02818 bool Debug::AddDebugEventListener(v8::Handle<v8::Function> that,
02819 Handle<Value> data) {
02820 ON_BAILOUT("v8::Debug::AddDebugEventListener()", return false);
02821 HandleScope scope;
02822 NeanderArray listeners(i::Factory::debug_event_listeners());
02823 NeanderObject obj(2);
02824 obj.set(0, *Utils::OpenHandle(*that));
02825 obj.set(1, data.IsEmpty() ?
02826 i::Heap::undefined_value() :
02827 *Utils::OpenHandle(*data));
02828 listeners.add(obj.value());
02829 i::Debugger::UpdateActiveDebugger();
02830 return true;
02831 }
02832
02833
02834 void Debug::RemoveDebugEventListener(DebugEventCallback that) {
02835 EnsureInitialized("v8::Debug::RemoveDebugEventListener()");
02836 ON_BAILOUT("v8::Debug::RemoveDebugEventListener()", return);
02837 HandleScope scope;
02838 NeanderArray listeners(i::Factory::debug_event_listeners());
02839 for (int i = 0; i < listeners.length(); i++) {
02840 if (listeners.get(i)->IsUndefined()) continue;
02841
02842 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
02843
02844 if (listener.get(0)->IsProxy()) {
02845 i::Handle<i::Proxy> callback_obj(i::Proxy::cast(listener.get(0)));
02846 if (callback_obj->proxy() == FUNCTION_ADDR(that)) {
02847 listeners.set(i, i::Heap::undefined_value());
02848 }
02849 }
02850 }
02851 i::Debugger::UpdateActiveDebugger();
02852 }
02853
02854
02855 void Debug::RemoveDebugEventListener(v8::Handle<v8::Function> that) {
02856 ON_BAILOUT("v8::Debug::RemoveDebugEventListener()", return);
02857 HandleScope scope;
02858 NeanderArray listeners(i::Factory::debug_event_listeners());
02859 for (int i = 0; i < listeners.length(); i++) {
02860 if (listeners.get(i)->IsUndefined()) continue;
02861
02862 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
02863
02864
02865 if (listener.get(0)->IsJSFunction()) {
02866 i::JSFunction* callback = i::JSFunction::cast(listener.get(0));
02867 i::Handle<i::JSFunction> callback_fun(callback);
02868 if (callback_fun.is_identical_to(Utils::OpenHandle(*that))) {
02869 listeners.set(i, i::Heap::undefined_value());
02870 }
02871 }
02872 }
02873 i::Debugger::UpdateActiveDebugger();
02874 }
02875
02876
02877 void Debug::DebugBreak() {
02878 if (!i::V8::HasBeenSetup()) return;
02879 i::StackGuard::DebugBreak();
02880 }
02881
02882
02883 void Debug::SetMessageHandler(v8::DebugMessageHandler handler, void* data) {
02884 EnsureInitialized("v8::Debug::SetMessageHandler");
02885 i::Debugger::SetMessageHandler(handler, data);
02886 }
02887
02888
02889 void Debug::SendCommand(const uint16_t* command, int length) {
02890 if (!i::V8::HasBeenSetup()) return;
02891 i::Debugger::ProcessCommand(i::Vector<const uint16_t>(command, length));
02892 }
02893
02894
02895 namespace internal {
02896
02897
02898 HandleScopeImplementer* HandleScopeImplementer::instance() {
02899 return &thread_local;
02900 }
02901
02902
02903 char* HandleScopeImplementer::ArchiveThread(char* storage) {
02904 return thread_local.ArchiveThreadHelper(storage);
02905 }
02906
02907
02908 char* HandleScopeImplementer::ArchiveThreadHelper(char* storage) {
02909 ImplementationUtilities::HandleScopeData* current =
02910 ImplementationUtilities::CurrentHandleScope();
02911 handle_scope_data_ = *current;
02912 memcpy(storage, this, sizeof(*this));
02913
02914 Initialize();
02915 current->Initialize();
02916
02917 return storage + ArchiveSpacePerThread();
02918 }
02919
02920
02921 int HandleScopeImplementer::ArchiveSpacePerThread() {
02922 return sizeof(thread_local);
02923 }
02924
02925
02926 char* HandleScopeImplementer::RestoreThread(char* storage) {
02927 return thread_local.RestoreThreadHelper(storage);
02928 }
02929
02930
02931 char* HandleScopeImplementer::RestoreThreadHelper(char* storage) {
02932 memcpy(this, storage, sizeof(*this));
02933 *ImplementationUtilities::CurrentHandleScope() = handle_scope_data_;
02934 return storage + ArchiveSpacePerThread();
02935 }
02936
02937
02938 void HandleScopeImplementer::Iterate(
02939 ObjectVisitor* v,
02940 List<void**>* blocks,
02941 ImplementationUtilities::HandleScopeData* handle_data) {
02942
02943 for (int i = blocks->length() - 2; i >= 0; --i) {
02944 Object** block =
02945 reinterpret_cast<Object**>(blocks->at(i));
02946 v->VisitPointers(block, &block[kHandleBlockSize]);
02947 }
02948
02949
02950 if (!blocks->is_empty()) {
02951 v->VisitPointers(reinterpret_cast<Object**>(blocks->last()),
02952 reinterpret_cast<Object**>(handle_data->next));
02953 }
02954 }
02955
02956
02957 void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
02958 ImplementationUtilities::HandleScopeData* current =
02959 ImplementationUtilities::CurrentHandleScope();
02960 Iterate(v, thread_local.Blocks(), current);
02961 }
02962
02963
02964 char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
02965 HandleScopeImplementer* thread_local =
02966 reinterpret_cast<HandleScopeImplementer*>(storage);
02967 List<void**>* blocks_of_archived_thread = thread_local->Blocks();
02968 ImplementationUtilities::HandleScopeData* handle_data_of_archived_thread =
02969 &thread_local->handle_scope_data_;
02970 Iterate(v, blocks_of_archived_thread, handle_data_of_archived_thread);
02971
02972 return storage + ArchiveSpacePerThread();
02973 }
02974
02975 } }