| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 | 41 |
| 42 template<typename Map> | 42 template<typename Map> |
| 43 static void disposeMapWithUnsafePersistentValues(Map* map) | 43 static void disposeMapWithUnsafePersistentValues(Map* map) |
| 44 { | 44 { |
| 45 typename Map::iterator it = map->begin(); | 45 typename Map::iterator it = map->begin(); |
| 46 for (; it != map->end(); ++it) | 46 for (; it != map->end(); ++it) |
| 47 it->value.dispose(); | 47 it->value.dispose(); |
| 48 map->clear(); | 48 map->clear(); |
| 49 } | 49 } |
| 50 | 50 |
| 51 class V8PerContextDataHolder { |
| 52 WTF_MAKE_NONCOPYABLE(V8PerContextDataHolder); |
| 53 public: |
| 54 static void install(v8::Handle<v8::Context> context, DOMWrapperWorld* world) |
| 55 { |
| 56 new V8PerContextDataHolder(context, world); |
| 57 } |
| 58 |
| 59 static V8PerContextDataHolder* from(v8::Handle<v8::Context> context) |
| 60 { |
| 61 V8PerContextDataHolder* holder = static_cast<V8PerContextDataHolder*>(co
ntext->GetAlignedPointerFromEmbedderData(v8ContextPerContextDataIndex)); |
| 62 // |holder| must not be 0 because V8PerContextDataHolder is kept alive a
s long as the |context| is alive. |
| 63 // Here we have a handle to the |context|, which means that the V8PerCon
textDataHolder is alive. |
| 64 ASSERT(holder); |
| 65 return holder; |
| 66 } |
| 67 |
| 68 V8PerContextData* perContextData() const { return m_perContextData; } |
| 69 void setPerContextData(V8PerContextData* data) { m_perContextData = data; } |
| 70 DOMWrapperWorld* world() const { return m_world; } |
| 71 |
| 72 private: |
| 73 V8PerContextDataHolder(v8::Handle<v8::Context> context, DOMWrapperWorld* wor
ld) |
| 74 : m_context(v8::Isolate::GetCurrent(), context) |
| 75 , m_perContextData(0) |
| 76 , m_world(world) |
| 77 { |
| 78 m_context.setWeak(this, &V8PerContextDataHolder::weakCallback); |
| 79 context->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, t
his); |
| 80 } |
| 81 |
| 82 ~V8PerContextDataHolder() { } |
| 83 |
| 84 static void weakCallback(const v8::WeakCallbackData<v8::Context, V8PerContex
tDataHolder>& data) |
| 85 { |
| 86 data.GetValue()->SetAlignedPointerInEmbedderData(v8ContextPerContextData
Index, 0); |
| 87 delete data.GetParameter(); |
| 88 } |
| 89 |
| 90 ScopedPersistent<v8::Context> m_context; |
| 91 V8PerContextData* m_perContextData; |
| 92 // This should not be a RefPtr. Otherwise, it creates a cycle: |
| 93 // V8PerContextData => DOMWrapperWorld => DOMDataStore => global objects |
| 94 // => Window or WorkerGlobalScope => V8PerContextData. |
| 95 DOMWrapperWorld* m_world; |
| 96 }; |
| 97 |
| 98 V8PerContextData::V8PerContextData(v8::Handle<v8::Context> context, DOMWrapperWo
rld* world) |
| 99 : m_activityLogger(0) |
| 100 , m_isolate(context->GetIsolate()) |
| 101 , m_contextHolder(adoptPtr(new gin::ContextHolder(context->GetIsolate()))) |
| 102 , m_context(m_isolate, context) |
| 103 , m_customElementBindings(adoptPtr(new CustomElementBindingMap())) |
| 104 { |
| 105 m_contextHolder->SetContext(context); |
| 106 V8PerContextDataHolder::install(context, world); |
| 107 V8PerContextDataHolder::from(context)->setPerContextData(this); |
| 108 |
| 109 v8::Context::Scope contextScope(context); |
| 110 ASSERT(m_errorPrototype.isEmpty()); |
| 111 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(context->Global
()->Get(v8AtomicString(m_isolate, "Error"))); |
| 112 ASSERT(!object.IsEmpty()); |
| 113 v8::Handle<v8::Value> prototypeValue = object->Get(v8AtomicString(m_isolate,
"prototype")); |
| 114 ASSERT(!prototypeValue.IsEmpty()); |
| 115 m_errorPrototype.set(m_isolate, prototypeValue); |
| 116 } |
| 117 |
| 51 V8PerContextData::~V8PerContextData() | 118 V8PerContextData::~V8PerContextData() |
| 52 { | 119 { |
| 53 v8::HandleScope handleScope(m_isolate); | 120 v8::HandleScope handleScope(m_isolate); |
| 54 V8PerContextDataHolder::from(m_context.newLocal(m_isolate))->setPerContextDa
ta(0); | 121 V8PerContextDataHolder::from(m_context.newLocal(m_isolate))->setPerContextDa
ta(0); |
| 55 | 122 |
| 56 disposeMapWithUnsafePersistentValues(&m_wrapperBoilerplates); | 123 disposeMapWithUnsafePersistentValues(&m_wrapperBoilerplates); |
| 57 disposeMapWithUnsafePersistentValues(&m_constructorMap); | 124 disposeMapWithUnsafePersistentValues(&m_constructorMap); |
| 58 m_customElementBindings.clear(); | |
| 59 } | 125 } |
| 60 | 126 |
| 61 #define V8_STORE_PRIMORDIAL(name, Name) \ | 127 V8PerContextData* V8PerContextData::from(v8::Handle<v8::Context> context) |
| 62 { \ | 128 { |
| 63 ASSERT(m_##name##Prototype.isEmpty()); \ | 129 return V8PerContextDataHolder::from(context)->perContextData(); |
| 64 v8::Handle<v8::String> symbol = v8AtomicString(m_isolate, #Name); \ | |
| 65 if (symbol.IsEmpty()) \ | |
| 66 return false; \ | |
| 67 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(m_context.newLo
cal(m_isolate)->Global()->Get(symbol)); \ | |
| 68 if (object.IsEmpty()) \ | |
| 69 return false; \ | |
| 70 v8::Handle<v8::Value> prototypeValue = object->Get(prototypeString); \ | |
| 71 if (prototypeValue.IsEmpty()) \ | |
| 72 return false; \ | |
| 73 m_##name##Prototype.set(m_isolate, prototypeValue); \ | |
| 74 } | 130 } |
| 75 | 131 |
| 76 bool V8PerContextData::init() | 132 DOMWrapperWorld* V8PerContextData::world(v8::Handle<v8::Context> context) |
| 77 { | 133 { |
| 78 v8::Handle<v8::Context> context = m_context.newLocal(m_isolate); | 134 DOMWrapperWorld* world = V8PerContextDataHolder::from(context)->world(); |
| 79 V8PerContextDataHolder::from(context)->setPerContextData(this); | 135 ASSERT(world); |
| 80 | 136 return world; |
| 81 v8::Handle<v8::String> prototypeString = v8AtomicString(m_isolate, "prototyp
e"); | |
| 82 if (prototypeString.IsEmpty()) | |
| 83 return false; | |
| 84 | |
| 85 V8_STORE_PRIMORDIAL(error, Error); | |
| 86 | |
| 87 return true; | |
| 88 } | 137 } |
| 89 | 138 |
| 90 #undef V8_STORE_PRIMORDIAL | |
| 91 | |
| 92 v8::Local<v8::Object> V8PerContextData::createWrapperFromCacheSlowCase(const Wra
pperTypeInfo* type) | 139 v8::Local<v8::Object> V8PerContextData::createWrapperFromCacheSlowCase(const Wra
pperTypeInfo* type) |
| 93 { | 140 { |
| 94 ASSERT(!m_errorPrototype.isEmpty()); | 141 ASSERT(!m_errorPrototype.isEmpty()); |
| 95 | 142 |
| 96 v8::Context::Scope scope(m_context.newLocal(m_isolate)); | 143 v8::Context::Scope scope(context()); |
| 97 v8::Local<v8::Function> function = constructorForType(type); | 144 v8::Local<v8::Function> function = constructorForType(type); |
| 98 v8::Local<v8::Object> instanceTemplate = V8ObjectConstructor::newInstance(fu
nction); | 145 v8::Local<v8::Object> instanceTemplate = V8ObjectConstructor::newInstance(fu
nction); |
| 99 if (!instanceTemplate.IsEmpty()) { | 146 if (!instanceTemplate.IsEmpty()) { |
| 100 m_wrapperBoilerplates.set(type, UnsafePersistent<v8::Object>(m_isolate,
instanceTemplate)); | 147 m_wrapperBoilerplates.set(type, UnsafePersistent<v8::Object>(m_isolate,
instanceTemplate)); |
| 101 return instanceTemplate->Clone(); | 148 return instanceTemplate->Clone(); |
| 102 } | 149 } |
| 103 return v8::Local<v8::Object>(); | 150 return v8::Local<v8::Object>(); |
| 104 } | 151 } |
| 105 | 152 |
| 106 v8::Local<v8::Function> V8PerContextData::constructorForTypeSlowCase(const Wrapp
erTypeInfo* type) | 153 v8::Local<v8::Function> V8PerContextData::constructorForTypeSlowCase(const Wrapp
erTypeInfo* type) |
| 107 { | 154 { |
| 108 ASSERT(!m_errorPrototype.isEmpty()); | 155 ASSERT(!m_errorPrototype.isEmpty()); |
| 109 | 156 |
| 110 v8::Context::Scope scope(m_context.newLocal(m_isolate)); | 157 v8::Context::Scope scope(context()); |
| 111 v8::Handle<v8::FunctionTemplate> functionTemplate = type->domTemplate(m_isol
ate, worldType(m_isolate)); | 158 v8::Handle<v8::FunctionTemplate> functionTemplate = type->domTemplate(m_isol
ate, worldType(m_isolate)); |
| 112 // Getting the function might fail if we're running out of stack or memory. | 159 // Getting the function might fail if we're running out of stack or memory. |
| 113 v8::TryCatch tryCatch; | 160 v8::TryCatch tryCatch; |
| 114 v8::Local<v8::Function> function = functionTemplate->GetFunction(); | 161 v8::Local<v8::Function> function = functionTemplate->GetFunction(); |
| 115 if (function.IsEmpty()) | 162 if (function.IsEmpty()) |
| 116 return v8::Local<v8::Function>(); | 163 return v8::Local<v8::Function>(); |
| 117 | 164 |
| 118 if (type->parentClass) { | 165 if (type->parentClass) { |
| 119 v8::Local<v8::Object> prototypeTemplate = constructorForType(type->paren
tClass); | 166 v8::Local<v8::Object> prototypeTemplate = constructorForType(type->paren
tClass); |
| 120 if (prototypeTemplate.IsEmpty()) | 167 if (prototypeTemplate.IsEmpty()) |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 if (!data->IsString()) | 259 if (!data->IsString()) |
| 213 return -1; | 260 return -1; |
| 214 v8::String::Utf8Value utf8(data); | 261 v8::String::Utf8Value utf8(data); |
| 215 char* comma = strnstr(*utf8, ",", utf8.length()); | 262 char* comma = strnstr(*utf8, ",", utf8.length()); |
| 216 if (!comma) | 263 if (!comma) |
| 217 return -1; | 264 return -1; |
| 218 return atoi(comma + 1); | 265 return atoi(comma + 1); |
| 219 } | 266 } |
| 220 | 267 |
| 221 } // namespace WebCore | 268 } // namespace WebCore |
| OLD | NEW |