Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(366)

Side by Side Diff: src/api.cc

Issue 11190050: Heavy cleanup of the external pointer API. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 // Deprecated API entries use other deprecated entries, too.
29 #define V8_DISABLE_DEPRECATIONS 1
30
28 #include "api.h" 31 #include "api.h"
29 32
30 #include <math.h> // For isnan. 33 #include <math.h> // For isnan.
31 #include <string.h> // For memcpy, strlen. 34 #include <string.h> // For memcpy, strlen.
32 #include "../include/v8-debug.h" 35 #include "../include/v8-debug.h"
33 #include "../include/v8-profiler.h" 36 #include "../include/v8-profiler.h"
34 #include "../include/v8-testing.h" 37 #include "../include/v8-testing.h"
35 #include "bootstrapper.h" 38 #include "bootstrapper.h"
36 #include "code-stubs.h" 39 #include "code-stubs.h"
37 #include "compiler.h" 40 #include "compiler.h"
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 } 769 }
767 770
768 // Content of 'last_context' could be NULL. 771 // Content of 'last_context' could be NULL.
769 i::Context* last_context = 772 i::Context* last_context =
770 isolate->handle_scope_implementer()->RestoreContext(); 773 isolate->handle_scope_implementer()->RestoreContext();
771 isolate->set_context(last_context); 774 isolate->set_context(last_context);
772 isolate->set_context_exit_happened(true); 775 isolate->set_context_exit_happened(true);
773 } 776 }
774 777
775 778
776 void Context::SetData(v8::Handle<Value> data) { 779 static void* DecodeSmiToAligned(i::Object* value, const char* location) {
777 i::Handle<i::Context> env = Utils::OpenHandle(this); 780 ApiCheck(value->IsSmi(), location, "Not a Smi");
778 i::Isolate* isolate = env->GetIsolate(); 781 return reinterpret_cast<void*>(value);
779 if (IsDeadCheck(isolate, "v8::Context::SetData()")) return;
780 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data);
781 ASSERT(env->IsNativeContext());
782 if (env->IsNativeContext()) {
783 env->set_data(*raw_data);
784 }
785 } 782 }
786 783
787 784
788 v8::Local<v8::Value> Context::GetData() { 785 static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) {
789 i::Handle<i::Context> env = Utils::OpenHandle(this); 786 i::Smi* smi = reinterpret_cast<i::Smi*>(value);
790 i::Isolate* isolate = env->GetIsolate(); 787 ApiCheck(smi->IsSmi(), location, "Pointer is not aligned");
791 if (IsDeadCheck(isolate, "v8::Context::GetData()")) { 788 return smi;
792 return Local<Value>(); 789 }
790
791
792 static i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
793 int index,
794 bool can_grow,
795 const char* location) {
796 i::Handle<i::Context> env = Utils::OpenHandle(context);
797 bool ok = !IsDeadCheck(env->GetIsolate(), location) &&
798 ApiCheck(env->IsNativeContext(), location, "Not a native context") &&
799 ApiCheck(index >= 0, location, "Negative index");
800 if (!ok) return i::Handle<i::FixedArray>();
801 i::Handle<i::FixedArray> data(env->embedder_data());
802 if (index < data->length()) return data;
803 if (!can_grow) {
804 Utils::ReportApiFailure(location, "Index too large");
805 return i::Handle<i::FixedArray>();
793 } 806 }
794 ASSERT(env->IsNativeContext()); 807 int new_size = i::Max(index, data->length() << 1) + 1;
795 if (!env->IsNativeContext()) { 808 data = env->GetIsolate()->factory()->CopySizeFixedArray(data, new_size);
796 return Local<Value>(); 809 env->set_embedder_data(*data);
797 } 810 return data;
798 i::Handle<i::Object> result(env->data(), isolate); 811 }
812
813
814 v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
815 const char* location = "v8::Context::GetEmbedderData()";
816 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
817 if (data.is_null()) return Local<Value>();
818 i::Handle<i::Object> result(data->get(index), data->GetIsolate());
799 return Utils::ToLocal(result); 819 return Utils::ToLocal(result);
800 } 820 }
801 821
802 822
823 void Context::SetEmbedderData(int index, v8::Handle<Value> value) {
824 const char* location = "v8::Context::SetEmbedderData()";
825 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
826 if (data.is_null()) return;
827 data->set(index, *Utils::OpenHandle(*value));
Michael Starzinger 2012/10/25 09:41:53 Even though this pattern is safe, GCMole might rep
Sven Panne 2012/10/25 14:23:08 Done.
828 ASSERT_EQ(*Utils::OpenHandle(*value),
829 *Utils::OpenHandle(*GetEmbedderData(index)));
830 }
831
832
833 void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
834 const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
835 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
836 if (data.is_null()) return NULL;
837 return DecodeSmiToAligned(data->get(index), location);
838 }
839
840
841 void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
842 const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
843 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
844 data->set(index, EncodeAlignedAsSmi(value, location));
845 ASSERT_EQ(value, GetAlignedPointerFromEmbedderData(index));
846 }
847
848
803 i::Object** v8::HandleScope::RawClose(i::Object** value) { 849 i::Object** v8::HandleScope::RawClose(i::Object** value) {
804 if (!ApiCheck(!is_closed_, 850 if (!ApiCheck(!is_closed_,
805 "v8::HandleScope::Close()", 851 "v8::HandleScope::Close()",
806 "Local scope has already been closed")) { 852 "Local scope has already been closed")) {
807 return 0; 853 return 0;
808 } 854 }
809 LOG_API(isolate_, "CloseHandleScope"); 855 LOG_API(isolate_, "CloseHandleScope");
810 856
811 // Read the result before popping the handle block. 857 // Read the result before popping the handle block.
812 i::Object* result = NULL; 858 i::Object* result = NULL;
(...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after
2191 return false; 2237 return false;
2192 } 2238 }
2193 return Utils::OpenHandle(this)->IsBoolean(); 2239 return Utils::OpenHandle(this)->IsBoolean();
2194 } 2240 }
2195 2241
2196 2242
2197 bool Value::IsExternal() const { 2243 bool Value::IsExternal() const {
2198 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) { 2244 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) {
2199 return false; 2245 return false;
2200 } 2246 }
2201 return Utils::OpenHandle(this)->IsForeign(); 2247 return Utils::OpenHandle(this)->IsExternal();
2202 } 2248 }
2203 2249
2204 2250
2205 bool Value::IsInt32() const { 2251 bool Value::IsInt32() const {
2206 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false; 2252 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false;
2207 i::Handle<i::Object> obj = Utils::OpenHandle(this); 2253 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2208 if (obj->IsSmi()) return true; 2254 if (obj->IsSmi()) return true;
2209 if (obj->IsNumber()) { 2255 if (obj->IsNumber()) {
2210 double value = obj->Number(); 2256 double value = obj->Number();
2211 static const i::DoubleRepresentation minus_zero(-0.0); 2257 static const i::DoubleRepresentation minus_zero(-0.0);
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
2420 EXCEPTION_PREAMBLE(isolate); 2466 EXCEPTION_PREAMBLE(isolate);
2421 num = i::Execution::ToInteger(obj, &has_pending_exception); 2467 num = i::Execution::ToInteger(obj, &has_pending_exception);
2422 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>()); 2468 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
2423 } 2469 }
2424 return Local<Integer>(ToApi<Integer>(num)); 2470 return Local<Integer>(ToApi<Integer>(num));
2425 } 2471 }
2426 2472
2427 2473
2428 void External::CheckCast(v8::Value* that) { 2474 void External::CheckCast(v8::Value* that) {
2429 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return; 2475 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return;
2430 i::Handle<i::Object> obj = Utils::OpenHandle(that); 2476 ApiCheck(Utils::OpenHandle(that)->IsExternal(),
2431 ApiCheck(obj->IsForeign(),
2432 "v8::External::Cast()", 2477 "v8::External::Cast()",
2433 "Could not convert to external"); 2478 "Could not convert to external");
2434 } 2479 }
2435 2480
2436 2481
2437 void v8::Object::CheckCast(Value* that) { 2482 void v8::Object::CheckCast(Value* that) {
2438 if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return; 2483 if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return;
2439 i::Handle<i::Object> obj = Utils::OpenHandle(that); 2484 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2440 ApiCheck(obj->IsJSObject(), 2485 ApiCheck(obj->IsJSObject(),
2441 "v8::Object::Cast()", 2486 "v8::Object::Cast()",
(...skipping 1742 matching lines...) Expand 10 before | Expand all | Expand 10 after
4184 4229
4185 int v8::Object::InternalFieldCount() { 4230 int v8::Object::InternalFieldCount() {
4186 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); 4231 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4187 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) { 4232 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) {
4188 return 0; 4233 return 0;
4189 } 4234 }
4190 return obj->GetInternalFieldCount(); 4235 return obj->GetInternalFieldCount();
4191 } 4236 }
4192 4237
4193 4238
4194 Local<Value> v8::Object::CheckedGetInternalField(int index) { 4239 static bool ObjectFieldOK(i::Handle<i::JSObject> obj,
Michael Starzinger 2012/10/25 09:41:53 Can we call this InternalFieldOK?
Sven Panne 2012/10/25 14:23:08 Done.
4240 int index,
4241 const char* location) {
4242 return !IsDeadCheck(obj->GetIsolate(), location) &&
4243 ApiCheck(index < obj->GetInternalFieldCount(),
4244 location,
4245 "Internal field out of bounds");
4246 }
4247
4248
4249 Local<Value> v8::Object::SlowGetInternalField(int index) {
4195 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); 4250 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4196 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) { 4251 const char* location = "v8::Object::GetInternalField()";
4197 return Local<Value>(); 4252 if (!ObjectFieldOK(obj, index, location)) return Local<Value>();
4198 } 4253 i::Handle<i::Object> value(obj->GetInternalField(index), obj->GetIsolate());
4199 if (!ApiCheck(index < obj->GetInternalFieldCount(), 4254 return Utils::ToLocal(value);
4200 "v8::Object::GetInternalField()",
4201 "Reading internal field out of bounds")) {
4202 return Local<Value>();
4203 }
4204 i::Handle<i::Object> value(obj->GetInternalField(index));
4205 Local<Value> result = Utils::ToLocal(value);
4206 #ifdef DEBUG
4207 Local<Value> unchecked = UncheckedGetInternalField(index);
4208 ASSERT(unchecked.IsEmpty() || (unchecked == result));
4209 #endif
4210 return result;
4211 } 4255 }
4212 4256
4213 4257
4214 void v8::Object::SetInternalField(int index, v8::Handle<Value> value) { 4258 void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
4215 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); 4259 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4216 i::Isolate* isolate = obj->GetIsolate(); 4260 const char* location = "v8::Object::SetInternalField()";
4217 if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) { 4261 if (!ObjectFieldOK(obj, index, location)) return;
4218 return; 4262 obj->SetInternalField(index, *Utils::OpenHandle(*value));
Michael Starzinger 2012/10/25 09:41:53 Even though this pattern is safe, GCMole might rep
Sven Panne 2012/10/25 14:23:08 Done.
4219 } 4263 ASSERT_EQ(value, GetInternalField(index));
4220 if (!ApiCheck(index < obj->GetInternalFieldCount(),
4221 "v8::Object::SetInternalField()",
4222 "Writing internal field out of bounds")) {
4223 return;
4224 }
4225 ENTER_V8(isolate);
4226 i::Handle<i::Object> val = Utils::OpenHandle(*value);
4227 obj->SetInternalField(index, *val);
4228 } 4264 }
4229 4265
4230 4266
4231 static bool CanBeEncodedAsSmi(void* ptr) { 4267 void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
4232 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr); 4268 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4233 return ((address & i::kEncodablePointerMask) == 0); 4269 const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
4270 if (!ObjectFieldOK(obj, index, location)) return NULL;
4271 return DecodeSmiToAligned(obj->GetInternalField(index), location);
4234 } 4272 }
4235 4273
4236 4274
4237 static i::Smi* EncodeAsSmi(void* ptr) { 4275 void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
4238 ASSERT(CanBeEncodedAsSmi(ptr)); 4276 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4239 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr); 4277 const char* location = "v8::Object::SetAlignedPointerInInternalField()";
4240 i::Smi* result = reinterpret_cast<i::Smi*>(address << i::kPointerToSmiShift); 4278 if (!ObjectFieldOK(obj, index, location)) return;
4241 ASSERT(i::Internals::HasSmiTag(result)); 4279 obj->SetInternalField(index, EncodeAlignedAsSmi(value, location));
4242 ASSERT_EQ(result, i::Smi::FromInt(result->value())); 4280 ASSERT_EQ(value, GetAlignedPointerFromInternalField(index));
4243 ASSERT_EQ(ptr, i::Internals::GetExternalPointerFromSmi(result));
4244 return result;
4245 } 4281 }
4246 4282
4247 4283
4248 void v8::Object::SetPointerInInternalField(int index, void* value) { 4284 static void* ExternalValue(i::Object* obj) {
4249 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 4285 // Obscure semantics for undefined, but somehow checked in our unit tests...
4250 ENTER_V8(isolate); 4286 if (obj->IsUndefined()) return NULL;
4251 if (CanBeEncodedAsSmi(value)) { 4287 i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0);
4252 Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value)); 4288 return i::Foreign::cast(foreign)->foreign_address();
4253 } else {
4254 HandleScope scope;
4255 i::Handle<i::Foreign> foreign =
4256 isolate->factory()->NewForeign(
4257 reinterpret_cast<i::Address>(value), i::TENURED);
4258 if (!foreign.is_null()) {
4259 Utils::OpenHandle(this)->SetInternalField(index, *foreign);
4260 }
4261 }
4262 ASSERT_EQ(value, GetPointerFromInternalField(index));
4263 } 4289 }
4264 4290
4265 4291
4292 void* Object::GetPointerFromInternalField(int index) {
4293 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4294 const char* location = "v8::Object::GetPointerFromInternalField()";
4295 if (!ObjectFieldOK(obj, index, location)) return NULL;
4296 return ExternalValue(obj->GetInternalField(index));
4297 }
4298
4299
4266 // --- E n v i r o n m e n t --- 4300 // --- E n v i r o n m e n t ---
4267 4301
4268 4302
4269 bool v8::V8::Initialize() { 4303 bool v8::V8::Initialize() {
4270 i::Isolate* isolate = i::Isolate::UncheckedCurrent(); 4304 i::Isolate* isolate = i::Isolate::UncheckedCurrent();
4271 if (isolate != NULL && isolate->IsInitialized()) { 4305 if (isolate != NULL && isolate->IsInitialized()) {
4272 return true; 4306 return true;
4273 } 4307 }
4274 return InitializeHelper(); 4308 return InitializeHelper();
4275 } 4309 }
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
4691 4725
4692 4726
4693 bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) { 4727 bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
4694 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()", 4728 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
4695 return false); 4729 return false);
4696 i::Object* obj = *Utils::OpenHandle(*value); 4730 i::Object* obj = *Utils::OpenHandle(*value);
4697 return obj->IsInstanceOf(*Utils::OpenHandle(this)); 4731 return obj->IsInstanceOf(*Utils::OpenHandle(this));
4698 } 4732 }
4699 4733
4700 4734
4701 static Local<External> ExternalNewImpl(void* data) { 4735 Local<External> v8::External::New(void* value) {
4702 return Utils::ToLocal(FACTORY->NewForeign(static_cast<i::Address>(data))); 4736 STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
4703 }
4704
4705 static void* ExternalValueImpl(i::Handle<i::Object> obj) {
4706 return reinterpret_cast<void*>(i::Foreign::cast(*obj)->foreign_address());
4707 }
4708
4709
4710 Local<Value> v8::External::Wrap(void* data) {
4711 i::Isolate* isolate = i::Isolate::Current();
4712 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
4713 EnsureInitializedForIsolate(isolate, "v8::External::Wrap()");
4714 LOG_API(isolate, "External::Wrap");
4715 ENTER_V8(isolate);
4716
4717 v8::Local<v8::Value> result = CanBeEncodedAsSmi(data)
4718 ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data)))
4719 : v8::Local<v8::Value>(ExternalNewImpl(data));
4720
4721 ASSERT_EQ(data, Unwrap(result));
4722 return result;
4723 }
4724
4725
4726 void* v8::Object::SlowGetPointerFromInternalField(int index) {
4727 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4728 i::Object* value = obj->GetInternalField(index);
4729 if (value->IsSmi()) {
4730 return i::Internals::GetExternalPointerFromSmi(value);
4731 } else if (value->IsForeign()) {
4732 return reinterpret_cast<void*>(i::Foreign::cast(value)->foreign_address());
4733 } else {
4734 return NULL;
4735 }
4736 }
4737
4738
4739 void* v8::External::FullUnwrap(v8::Handle<v8::Value> wrapper) {
4740 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Unwrap()")) return 0;
4741 i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper);
4742 void* result;
4743 if (obj->IsSmi()) {
4744 result = i::Internals::GetExternalPointerFromSmi(*obj);
4745 } else if (obj->IsForeign()) {
4746 result = ExternalValueImpl(obj);
4747 } else {
4748 result = NULL;
4749 }
4750 ASSERT_EQ(result, QuickUnwrap(wrapper));
4751 return result;
4752 }
4753
4754
4755 Local<External> v8::External::New(void* data) {
4756 STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
4757 i::Isolate* isolate = i::Isolate::Current(); 4737 i::Isolate* isolate = i::Isolate::Current();
4758 EnsureInitializedForIsolate(isolate, "v8::External::New()"); 4738 EnsureInitializedForIsolate(isolate, "v8::External::New()");
4759 LOG_API(isolate, "External::New"); 4739 LOG_API(isolate, "External::New");
4760 ENTER_V8(isolate); 4740 ENTER_V8(isolate);
4761 return ExternalNewImpl(data); 4741 i::Handle<i::JSObject> external = isolate->factory()->NewExternal(value);
4742 // TODO(svenpanne) This should somehow be Utils::ToLocal.
Michael Starzinger 2012/10/25 09:41:53 You can get a ToLocal by calling it ExternalToLoca
Sven Panne 2012/10/25 14:23:08 Ooops, forgot that TODO. Good point, one can even
4743 return Local<External>(reinterpret_cast<External*>(external.location()));
4762 } 4744 }
4763 4745
4764 4746
4765 void* External::Value() const { 4747 void* External::Value() const {
4766 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return 0; 4748 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return NULL;
4767 i::Handle<i::Object> obj = Utils::OpenHandle(this); 4749 return ExternalValue(*Utils::OpenHandle(this));
4768 return ExternalValueImpl(obj);
4769 } 4750 }
4770 4751
4771 4752
4772 Local<String> v8::String::Empty() { 4753 Local<String> v8::String::Empty() {
4773 i::Isolate* isolate = i::Isolate::Current(); 4754 i::Isolate* isolate = i::Isolate::Current();
4774 if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) { 4755 if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) {
4775 return v8::Local<String>(); 4756 return v8::Local<String>();
4776 } 4757 }
4777 LOG_API(isolate, "String::Empty()"); 4758 LOG_API(isolate, "String::Empty()");
4778 return Utils::ToLocal(isolate->factory()->empty_symbol()); 4759 return Utils::ToLocal(isolate->factory()->empty_symbol());
(...skipping 1860 matching lines...) Expand 10 before | Expand all | Expand 10 after
6639 6620
6640 v->VisitPointers(blocks_.first(), first_block_limit_); 6621 v->VisitPointers(blocks_.first(), first_block_limit_);
6641 6622
6642 for (int i = 1; i < blocks_.length(); i++) { 6623 for (int i = 1; i < blocks_.length(); i++) {
6643 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]); 6624 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]);
6644 } 6625 }
6645 } 6626 }
6646 6627
6647 6628
6648 } } // namespace v8::internal 6629 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698