OLD | NEW |
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 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 } | 806 } |
804 | 807 |
805 // Content of 'last_context' could be NULL. | 808 // Content of 'last_context' could be NULL. |
806 i::Context* last_context = | 809 i::Context* last_context = |
807 isolate->handle_scope_implementer()->RestoreContext(); | 810 isolate->handle_scope_implementer()->RestoreContext(); |
808 isolate->set_context(last_context); | 811 isolate->set_context(last_context); |
809 isolate->set_context_exit_happened(true); | 812 isolate->set_context_exit_happened(true); |
810 } | 813 } |
811 | 814 |
812 | 815 |
813 void Context::SetData(v8::Handle<Value> data) { | 816 static void* DecodeSmiToAligned(i::Object* value, const char* location) { |
814 i::Handle<i::Context> env = Utils::OpenHandle(this); | 817 ApiCheck(value->IsSmi(), location, "Not a Smi"); |
815 i::Isolate* isolate = env->GetIsolate(); | 818 return reinterpret_cast<void*>(value); |
816 if (IsDeadCheck(isolate, "v8::Context::SetData()")) return; | |
817 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data); | |
818 ASSERT(env->IsNativeContext()); | |
819 if (env->IsNativeContext()) { | |
820 env->set_data(*raw_data); | |
821 } | |
822 } | 819 } |
823 | 820 |
824 | 821 |
825 v8::Local<v8::Value> Context::GetData() { | 822 static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) { |
826 i::Handle<i::Context> env = Utils::OpenHandle(this); | 823 i::Smi* smi = reinterpret_cast<i::Smi*>(value); |
827 i::Isolate* isolate = env->GetIsolate(); | 824 ApiCheck(smi->IsSmi(), location, "Pointer is not aligned"); |
828 if (IsDeadCheck(isolate, "v8::Context::GetData()")) { | 825 return smi; |
829 return Local<Value>(); | 826 } |
| 827 |
| 828 |
| 829 static i::Handle<i::FixedArray> EmbedderDataFor(Context* context, |
| 830 int index, |
| 831 bool can_grow, |
| 832 const char* location) { |
| 833 i::Handle<i::Context> env = Utils::OpenHandle(context); |
| 834 bool ok = !IsDeadCheck(env->GetIsolate(), location) && |
| 835 ApiCheck(env->IsNativeContext(), location, "Not a native context") && |
| 836 ApiCheck(index >= 0, location, "Negative index"); |
| 837 if (!ok) return i::Handle<i::FixedArray>(); |
| 838 i::Handle<i::FixedArray> data(env->embedder_data()); |
| 839 if (index < data->length()) return data; |
| 840 if (!can_grow) { |
| 841 Utils::ReportApiFailure(location, "Index too large"); |
| 842 return i::Handle<i::FixedArray>(); |
830 } | 843 } |
831 ASSERT(env->IsNativeContext()); | 844 int new_size = i::Max(index, data->length() << 1) + 1; |
832 if (!env->IsNativeContext()) { | 845 data = env->GetIsolate()->factory()->CopySizeFixedArray(data, new_size); |
833 return Local<Value>(); | 846 env->set_embedder_data(*data); |
834 } | 847 return data; |
835 i::Handle<i::Object> result(env->data(), isolate); | 848 } |
| 849 |
| 850 |
| 851 v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) { |
| 852 const char* location = "v8::Context::GetEmbedderData()"; |
| 853 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location); |
| 854 if (data.is_null()) return Local<Value>(); |
| 855 i::Handle<i::Object> result(data->get(index), data->GetIsolate()); |
836 return Utils::ToLocal(result); | 856 return Utils::ToLocal(result); |
837 } | 857 } |
838 | 858 |
839 | 859 |
| 860 void Context::SetEmbedderData(int index, v8::Handle<Value> value) { |
| 861 const char* location = "v8::Context::SetEmbedderData()"; |
| 862 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location); |
| 863 if (data.is_null()) return; |
| 864 i::Handle<i::Object> val = Utils::OpenHandle(*value); |
| 865 data->set(index, *val); |
| 866 ASSERT_EQ(*Utils::OpenHandle(*value), |
| 867 *Utils::OpenHandle(*GetEmbedderData(index))); |
| 868 } |
| 869 |
| 870 |
| 871 void* Context::SlowGetAlignedPointerFromEmbedderData(int index) { |
| 872 const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()"; |
| 873 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location); |
| 874 if (data.is_null()) return NULL; |
| 875 return DecodeSmiToAligned(data->get(index), location); |
| 876 } |
| 877 |
| 878 |
| 879 void Context::SetAlignedPointerInEmbedderData(int index, void* value) { |
| 880 const char* location = "v8::Context::SetAlignedPointerInEmbedderData()"; |
| 881 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location); |
| 882 data->set(index, EncodeAlignedAsSmi(value, location)); |
| 883 ASSERT_EQ(value, GetAlignedPointerFromEmbedderData(index)); |
| 884 } |
| 885 |
| 886 |
840 i::Object** v8::HandleScope::RawClose(i::Object** value) { | 887 i::Object** v8::HandleScope::RawClose(i::Object** value) { |
841 if (!ApiCheck(!is_closed_, | 888 if (!ApiCheck(!is_closed_, |
842 "v8::HandleScope::Close()", | 889 "v8::HandleScope::Close()", |
843 "Local scope has already been closed")) { | 890 "Local scope has already been closed")) { |
844 return 0; | 891 return 0; |
845 } | 892 } |
846 LOG_API(isolate_, "CloseHandleScope"); | 893 LOG_API(isolate_, "CloseHandleScope"); |
847 | 894 |
848 // Read the result before popping the handle block. | 895 // Read the result before popping the handle block. |
849 i::Object* result = NULL; | 896 i::Object* result = NULL; |
(...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2228 return false; | 2275 return false; |
2229 } | 2276 } |
2230 return Utils::OpenHandle(this)->IsBoolean(); | 2277 return Utils::OpenHandle(this)->IsBoolean(); |
2231 } | 2278 } |
2232 | 2279 |
2233 | 2280 |
2234 bool Value::IsExternal() const { | 2281 bool Value::IsExternal() const { |
2235 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) { | 2282 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) { |
2236 return false; | 2283 return false; |
2237 } | 2284 } |
2238 return Utils::OpenHandle(this)->IsForeign(); | 2285 return Utils::OpenHandle(this)->IsExternal(); |
2239 } | 2286 } |
2240 | 2287 |
2241 | 2288 |
2242 bool Value::IsInt32() const { | 2289 bool Value::IsInt32() const { |
2243 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false; | 2290 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false; |
2244 i::Handle<i::Object> obj = Utils::OpenHandle(this); | 2291 i::Handle<i::Object> obj = Utils::OpenHandle(this); |
2245 if (obj->IsSmi()) return true; | 2292 if (obj->IsSmi()) return true; |
2246 if (obj->IsNumber()) { | 2293 if (obj->IsNumber()) { |
2247 double value = obj->Number(); | 2294 double value = obj->Number(); |
2248 static const i::DoubleRepresentation minus_zero(-0.0); | 2295 static const i::DoubleRepresentation minus_zero(-0.0); |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2461 EXCEPTION_PREAMBLE(isolate); | 2508 EXCEPTION_PREAMBLE(isolate); |
2462 num = i::Execution::ToInteger(obj, &has_pending_exception); | 2509 num = i::Execution::ToInteger(obj, &has_pending_exception); |
2463 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>()); | 2510 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>()); |
2464 } | 2511 } |
2465 return Local<Integer>(ToApi<Integer>(num)); | 2512 return Local<Integer>(ToApi<Integer>(num)); |
2466 } | 2513 } |
2467 | 2514 |
2468 | 2515 |
2469 void External::CheckCast(v8::Value* that) { | 2516 void External::CheckCast(v8::Value* that) { |
2470 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return; | 2517 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return; |
2471 i::Handle<i::Object> obj = Utils::OpenHandle(that); | 2518 ApiCheck(Utils::OpenHandle(that)->IsExternal(), |
2472 ApiCheck(obj->IsForeign(), | |
2473 "v8::External::Cast()", | 2519 "v8::External::Cast()", |
2474 "Could not convert to external"); | 2520 "Could not convert to external"); |
2475 } | 2521 } |
2476 | 2522 |
2477 | 2523 |
2478 void v8::Object::CheckCast(Value* that) { | 2524 void v8::Object::CheckCast(Value* that) { |
2479 if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return; | 2525 if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return; |
2480 i::Handle<i::Object> obj = Utils::OpenHandle(that); | 2526 i::Handle<i::Object> obj = Utils::OpenHandle(that); |
2481 ApiCheck(obj->IsJSObject(), | 2527 ApiCheck(obj->IsJSObject(), |
2482 "v8::Object::Cast()", | 2528 "v8::Object::Cast()", |
(...skipping 1743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4226 | 4272 |
4227 int v8::Object::InternalFieldCount() { | 4273 int v8::Object::InternalFieldCount() { |
4228 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 4274 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
4229 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) { | 4275 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) { |
4230 return 0; | 4276 return 0; |
4231 } | 4277 } |
4232 return obj->GetInternalFieldCount(); | 4278 return obj->GetInternalFieldCount(); |
4233 } | 4279 } |
4234 | 4280 |
4235 | 4281 |
4236 Local<Value> v8::Object::CheckedGetInternalField(int index) { | 4282 static bool InternalFieldOK(i::Handle<i::JSObject> obj, |
| 4283 int index, |
| 4284 const char* location) { |
| 4285 return !IsDeadCheck(obj->GetIsolate(), location) && |
| 4286 ApiCheck(index < obj->GetInternalFieldCount(), |
| 4287 location, |
| 4288 "Internal field out of bounds"); |
| 4289 } |
| 4290 |
| 4291 |
| 4292 Local<Value> v8::Object::SlowGetInternalField(int index) { |
4237 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 4293 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
4238 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) { | 4294 const char* location = "v8::Object::GetInternalField()"; |
4239 return Local<Value>(); | 4295 if (!InternalFieldOK(obj, index, location)) return Local<Value>(); |
4240 } | 4296 i::Handle<i::Object> value(obj->GetInternalField(index), obj->GetIsolate()); |
4241 if (!ApiCheck(index < obj->GetInternalFieldCount(), | 4297 return Utils::ToLocal(value); |
4242 "v8::Object::GetInternalField()", | |
4243 "Reading internal field out of bounds")) { | |
4244 return Local<Value>(); | |
4245 } | |
4246 i::Handle<i::Object> value(obj->GetInternalField(index)); | |
4247 Local<Value> result = Utils::ToLocal(value); | |
4248 #ifdef DEBUG | |
4249 Local<Value> unchecked = UncheckedGetInternalField(index); | |
4250 ASSERT(unchecked.IsEmpty() || (unchecked == result)); | |
4251 #endif | |
4252 return result; | |
4253 } | 4298 } |
4254 | 4299 |
4255 | 4300 |
4256 void v8::Object::SetInternalField(int index, v8::Handle<Value> value) { | 4301 void v8::Object::SetInternalField(int index, v8::Handle<Value> value) { |
4257 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 4302 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
4258 i::Isolate* isolate = obj->GetIsolate(); | 4303 const char* location = "v8::Object::SetInternalField()"; |
4259 if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) { | 4304 if (!InternalFieldOK(obj, index, location)) return; |
4260 return; | |
4261 } | |
4262 if (!ApiCheck(index < obj->GetInternalFieldCount(), | |
4263 "v8::Object::SetInternalField()", | |
4264 "Writing internal field out of bounds")) { | |
4265 return; | |
4266 } | |
4267 ENTER_V8(isolate); | |
4268 i::Handle<i::Object> val = Utils::OpenHandle(*value); | 4305 i::Handle<i::Object> val = Utils::OpenHandle(*value); |
4269 obj->SetInternalField(index, *val); | 4306 obj->SetInternalField(index, *val); |
| 4307 ASSERT_EQ(value, GetInternalField(index)); |
4270 } | 4308 } |
4271 | 4309 |
4272 | 4310 |
4273 static bool CanBeEncodedAsSmi(void* ptr) { | 4311 void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) { |
4274 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr); | 4312 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
4275 return ((address & i::kEncodablePointerMask) == 0); | 4313 const char* location = "v8::Object::GetAlignedPointerFromInternalField()"; |
| 4314 if (!InternalFieldOK(obj, index, location)) return NULL; |
| 4315 return DecodeSmiToAligned(obj->GetInternalField(index), location); |
4276 } | 4316 } |
4277 | 4317 |
4278 | 4318 |
4279 static i::Smi* EncodeAsSmi(void* ptr) { | 4319 void v8::Object::SetAlignedPointerInInternalField(int index, void* value) { |
4280 ASSERT(CanBeEncodedAsSmi(ptr)); | 4320 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
4281 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr); | 4321 const char* location = "v8::Object::SetAlignedPointerInInternalField()"; |
4282 i::Smi* result = reinterpret_cast<i::Smi*>(address << i::kPointerToSmiShift); | 4322 if (!InternalFieldOK(obj, index, location)) return; |
4283 ASSERT(i::Internals::HasSmiTag(result)); | 4323 obj->SetInternalField(index, EncodeAlignedAsSmi(value, location)); |
4284 ASSERT_EQ(result, i::Smi::FromInt(result->value())); | 4324 ASSERT_EQ(value, GetAlignedPointerFromInternalField(index)); |
4285 ASSERT_EQ(ptr, i::Internals::GetExternalPointerFromSmi(result)); | |
4286 return result; | |
4287 } | 4325 } |
4288 | 4326 |
4289 | 4327 |
4290 void v8::Object::SetPointerInInternalField(int index, void* value) { | 4328 static void* ExternalValue(i::Object* obj) { |
4291 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 4329 // Obscure semantics for undefined, but somehow checked in our unit tests... |
4292 ENTER_V8(isolate); | 4330 if (obj->IsUndefined()) return NULL; |
4293 if (CanBeEncodedAsSmi(value)) { | 4331 i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0); |
4294 Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value)); | 4332 return i::Foreign::cast(foreign)->foreign_address(); |
4295 } else { | |
4296 HandleScope scope; | |
4297 i::Handle<i::Foreign> foreign = | |
4298 isolate->factory()->NewForeign( | |
4299 reinterpret_cast<i::Address>(value), i::TENURED); | |
4300 if (!foreign.is_null()) { | |
4301 Utils::OpenHandle(this)->SetInternalField(index, *foreign); | |
4302 } | |
4303 } | |
4304 ASSERT_EQ(value, GetPointerFromInternalField(index)); | |
4305 } | 4333 } |
4306 | 4334 |
4307 | 4335 |
| 4336 void* Object::GetPointerFromInternalField(int index) { |
| 4337 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
| 4338 const char* location = "v8::Object::GetPointerFromInternalField()"; |
| 4339 if (!InternalFieldOK(obj, index, location)) return NULL; |
| 4340 return ExternalValue(obj->GetInternalField(index)); |
| 4341 } |
| 4342 |
| 4343 |
4308 // --- E n v i r o n m e n t --- | 4344 // --- E n v i r o n m e n t --- |
4309 | 4345 |
4310 | 4346 |
4311 bool v8::V8::Initialize() { | 4347 bool v8::V8::Initialize() { |
4312 i::Isolate* isolate = i::Isolate::UncheckedCurrent(); | 4348 i::Isolate* isolate = i::Isolate::UncheckedCurrent(); |
4313 if (isolate != NULL && isolate->IsInitialized()) { | 4349 if (isolate != NULL && isolate->IsInitialized()) { |
4314 return true; | 4350 return true; |
4315 } | 4351 } |
4316 return InitializeHelper(); | 4352 return InitializeHelper(); |
4317 } | 4353 } |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4733 | 4769 |
4734 | 4770 |
4735 bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) { | 4771 bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) { |
4736 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()", | 4772 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()", |
4737 return false); | 4773 return false); |
4738 i::Object* obj = *Utils::OpenHandle(*value); | 4774 i::Object* obj = *Utils::OpenHandle(*value); |
4739 return obj->IsInstanceOf(*Utils::OpenHandle(this)); | 4775 return obj->IsInstanceOf(*Utils::OpenHandle(this)); |
4740 } | 4776 } |
4741 | 4777 |
4742 | 4778 |
4743 static Local<External> ExternalNewImpl(void* data) { | 4779 Local<External> v8::External::New(void* value) { |
4744 return Utils::ToLocal(FACTORY->NewForeign(static_cast<i::Address>(data))); | 4780 STATIC_ASSERT(sizeof(value) == sizeof(i::Address)); |
4745 } | |
4746 | |
4747 static void* ExternalValueImpl(i::Handle<i::Object> obj) { | |
4748 return reinterpret_cast<void*>(i::Foreign::cast(*obj)->foreign_address()); | |
4749 } | |
4750 | |
4751 | |
4752 Local<Value> v8::External::Wrap(void* data) { | |
4753 i::Isolate* isolate = i::Isolate::Current(); | |
4754 STATIC_ASSERT(sizeof(data) == sizeof(i::Address)); | |
4755 EnsureInitializedForIsolate(isolate, "v8::External::Wrap()"); | |
4756 LOG_API(isolate, "External::Wrap"); | |
4757 ENTER_V8(isolate); | |
4758 | |
4759 v8::Local<v8::Value> result = CanBeEncodedAsSmi(data) | |
4760 ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data))) | |
4761 : v8::Local<v8::Value>(ExternalNewImpl(data)); | |
4762 | |
4763 ASSERT_EQ(data, Unwrap(result)); | |
4764 return result; | |
4765 } | |
4766 | |
4767 | |
4768 void* v8::Object::SlowGetPointerFromInternalField(int index) { | |
4769 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | |
4770 i::Object* value = obj->GetInternalField(index); | |
4771 if (value->IsSmi()) { | |
4772 return i::Internals::GetExternalPointerFromSmi(value); | |
4773 } else if (value->IsForeign()) { | |
4774 return reinterpret_cast<void*>(i::Foreign::cast(value)->foreign_address()); | |
4775 } else { | |
4776 return NULL; | |
4777 } | |
4778 } | |
4779 | |
4780 | |
4781 void* v8::External::FullUnwrap(v8::Handle<v8::Value> wrapper) { | |
4782 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Unwrap()")) return 0; | |
4783 i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper); | |
4784 void* result; | |
4785 if (obj->IsSmi()) { | |
4786 result = i::Internals::GetExternalPointerFromSmi(*obj); | |
4787 } else if (obj->IsForeign()) { | |
4788 result = ExternalValueImpl(obj); | |
4789 } else { | |
4790 result = NULL; | |
4791 } | |
4792 ASSERT_EQ(result, QuickUnwrap(wrapper)); | |
4793 return result; | |
4794 } | |
4795 | |
4796 | |
4797 Local<External> v8::External::New(void* data) { | |
4798 STATIC_ASSERT(sizeof(data) == sizeof(i::Address)); | |
4799 i::Isolate* isolate = i::Isolate::Current(); | 4781 i::Isolate* isolate = i::Isolate::Current(); |
4800 EnsureInitializedForIsolate(isolate, "v8::External::New()"); | 4782 EnsureInitializedForIsolate(isolate, "v8::External::New()"); |
4801 LOG_API(isolate, "External::New"); | 4783 LOG_API(isolate, "External::New"); |
4802 ENTER_V8(isolate); | 4784 ENTER_V8(isolate); |
4803 return ExternalNewImpl(data); | 4785 i::Handle<i::JSObject> external = isolate->factory()->NewExternal(value); |
| 4786 return Utils::ExternalToLocal(external); |
4804 } | 4787 } |
4805 | 4788 |
4806 | 4789 |
4807 void* External::Value() const { | 4790 void* External::Value() const { |
4808 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return 0; | 4791 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return NULL; |
4809 i::Handle<i::Object> obj = Utils::OpenHandle(this); | 4792 return ExternalValue(*Utils::OpenHandle(this)); |
4810 return ExternalValueImpl(obj); | |
4811 } | 4793 } |
4812 | 4794 |
4813 | 4795 |
4814 Local<String> v8::String::Empty() { | 4796 Local<String> v8::String::Empty() { |
4815 i::Isolate* isolate = i::Isolate::Current(); | 4797 i::Isolate* isolate = i::Isolate::Current(); |
4816 if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) { | 4798 if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) { |
4817 return v8::Local<String>(); | 4799 return v8::Local<String>(); |
4818 } | 4800 } |
4819 LOG_API(isolate, "String::Empty()"); | 4801 LOG_API(isolate, "String::Empty()"); |
4820 return Utils::ToLocal(isolate->factory()->empty_symbol()); | 4802 return Utils::ToLocal(isolate->factory()->empty_symbol()); |
(...skipping 1861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6682 | 6664 |
6683 v->VisitPointers(blocks_.first(), first_block_limit_); | 6665 v->VisitPointers(blocks_.first(), first_block_limit_); |
6684 | 6666 |
6685 for (int i = 1; i < blocks_.length(); i++) { | 6667 for (int i = 1; i < blocks_.length(); i++) { |
6686 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]); | 6668 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]); |
6687 } | 6669 } |
6688 } | 6670 } |
6689 | 6671 |
6690 | 6672 |
6691 } } // namespace v8::internal | 6673 } } // namespace v8::internal |
OLD | NEW |