OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/api-natives.h" | 5 #include "src/api-natives.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/isolate-inl.h" | 8 #include "src/isolate-inl.h" |
9 #include "src/lookup.h" | 9 #include "src/lookup.h" |
10 #include "src/messages.h" | 10 #include "src/messages.h" |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 auto prop_data = handle(GetIntrinsic(isolate, intrinsic), isolate); | 259 auto prop_data = handle(GetIntrinsic(isolate, intrinsic), isolate); |
260 | 260 |
261 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, | 261 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, |
262 prop_data, attributes), | 262 prop_data, attributes), |
263 JSObject); | 263 JSObject); |
264 } | 264 } |
265 } | 265 } |
266 return obj; | 266 return obj; |
267 } | 267 } |
268 | 268 |
269 void CacheTemplateInstantiation(Isolate* isolate, Handle<Smi> serial_number, | 269 void CacheTemplateInstantiation(Isolate* isolate, uint32_t serial_number, |
270 Handle<JSObject> object) { | 270 Handle<JSObject> object) { |
271 auto cache = isolate->template_instantiations_cache(); | 271 auto cache = isolate->template_instantiations_cache(); |
272 auto new_cache = UnseededNumberDictionary::AtNumberPut( | 272 auto new_cache = |
273 cache, static_cast<uint32_t>(serial_number->value()), object); | 273 UnseededNumberDictionary::AtNumberPut(cache, serial_number, object); |
274 isolate->native_context()->set_template_instantiations_cache(*new_cache); | 274 isolate->native_context()->set_template_instantiations_cache(*new_cache); |
275 } | 275 } |
276 | 276 |
277 void UncacheTemplateInstantiation(Isolate* isolate, Handle<Smi> serial_number) { | 277 void UncacheTemplateInstantiation(Isolate* isolate, uint32_t serial_number) { |
278 auto cache = isolate->template_instantiations_cache(); | 278 auto cache = isolate->template_instantiations_cache(); |
279 int entry = cache->FindEntry(static_cast<uint32_t>(serial_number->value())); | 279 int entry = cache->FindEntry(serial_number); |
280 DCHECK(entry != UnseededNumberDictionary::kNotFound); | 280 DCHECK(entry != UnseededNumberDictionary::kNotFound); |
281 Handle<Object> result = | 281 Handle<Object> result = |
282 UnseededNumberDictionary::DeleteProperty(cache, entry); | 282 UnseededNumberDictionary::DeleteProperty(cache, entry); |
283 USE(result); | 283 USE(result); |
284 DCHECK(result->IsTrue()); | 284 DCHECK(result->IsTrue()); |
285 auto new_cache = UnseededNumberDictionary::Shrink(cache, entry); | 285 auto new_cache = UnseededNumberDictionary::Shrink(cache, entry); |
286 isolate->native_context()->set_template_instantiations_cache(*new_cache); | 286 isolate->native_context()->set_template_instantiations_cache(*new_cache); |
287 } | 287 } |
288 | 288 |
289 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate, | 289 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate, |
290 Handle<ObjectTemplateInfo> info, | 290 Handle<ObjectTemplateInfo> info, |
291 bool is_hidden_prototype) { | 291 bool is_hidden_prototype) { |
292 // Fast path. | 292 // Fast path. |
293 Handle<JSObject> result; | 293 Handle<JSObject> result; |
294 auto serial_number = handle(Smi::cast(info->serial_number()), isolate); | 294 uint32_t serial_number = |
295 if (serial_number->value()) { | 295 static_cast<uint32_t>(Smi::cast(info->serial_number())->value()); |
| 296 if (serial_number) { |
296 // Probe cache. | 297 // Probe cache. |
297 auto cache = isolate->template_instantiations_cache(); | 298 auto cache = isolate->template_instantiations_cache(); |
298 int entry = cache->FindEntry(static_cast<uint32_t>(serial_number->value())); | 299 int entry = cache->FindEntry(serial_number); |
299 if (entry != UnseededNumberDictionary::kNotFound) { | 300 if (entry != UnseededNumberDictionary::kNotFound) { |
300 Object* boilerplate = cache->ValueAt(entry); | 301 Object* boilerplate = cache->ValueAt(entry); |
301 result = handle(JSObject::cast(boilerplate), isolate); | 302 result = handle(JSObject::cast(boilerplate), isolate); |
302 ASSIGN_RETURN_ON_EXCEPTION( | 303 ASSIGN_RETURN_ON_EXCEPTION( |
303 isolate, result, JSObject::DeepCopyApiBoilerplate(result), JSObject); | 304 isolate, result, JSObject::DeepCopyApiBoilerplate(result), JSObject); |
304 return result; | 305 return result; |
305 } | 306 } |
306 } | 307 } |
307 // Enter a new scope. Recursion could otherwise create a lot of handles. | 308 // Enter a new scope. Recursion could otherwise create a lot of handles. |
308 HandleScope scope(isolate); | 309 HandleScope scope(isolate); |
309 auto constructor = handle(info->constructor(), isolate); | 310 auto constructor = handle(info->constructor(), isolate); |
310 Handle<JSFunction> cons; | 311 Handle<JSFunction> cons; |
311 if (constructor->IsUndefined()) { | 312 if (constructor->IsUndefined()) { |
312 cons = isolate->object_function(); | 313 cons = isolate->object_function(); |
313 } else { | 314 } else { |
314 auto cons_templ = Handle<FunctionTemplateInfo>::cast(constructor); | 315 auto cons_templ = Handle<FunctionTemplateInfo>::cast(constructor); |
315 ASSIGN_RETURN_ON_EXCEPTION( | 316 ASSIGN_RETURN_ON_EXCEPTION( |
316 isolate, cons, InstantiateFunction(isolate, cons_templ), JSFunction); | 317 isolate, cons, InstantiateFunction(isolate, cons_templ), JSFunction); |
317 } | 318 } |
318 auto object = isolate->factory()->NewJSObject(cons); | 319 auto object = isolate->factory()->NewJSObject(cons); |
319 ASSIGN_RETURN_ON_EXCEPTION( | 320 ASSIGN_RETURN_ON_EXCEPTION( |
320 isolate, result, | 321 isolate, result, |
321 ConfigureInstance(isolate, object, info, is_hidden_prototype), | 322 ConfigureInstance(isolate, object, info, is_hidden_prototype), |
322 JSFunction); | 323 JSFunction); |
323 // TODO(dcarney): is this necessary? | 324 // TODO(dcarney): is this necessary? |
324 JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject"); | 325 JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject"); |
325 | 326 |
326 if (serial_number->value()) { | 327 if (serial_number) { |
327 CacheTemplateInstantiation(isolate, serial_number, result); | 328 CacheTemplateInstantiation(isolate, serial_number, result); |
328 ASSIGN_RETURN_ON_EXCEPTION( | 329 ASSIGN_RETURN_ON_EXCEPTION( |
329 isolate, result, JSObject::DeepCopyApiBoilerplate(result), JSObject); | 330 isolate, result, JSObject::DeepCopyApiBoilerplate(result), JSObject); |
330 } | 331 } |
331 return scope.CloseAndEscape(result); | 332 return scope.CloseAndEscape(result); |
332 } | 333 } |
333 | 334 |
334 | 335 |
335 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate, | 336 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate, |
336 Handle<FunctionTemplateInfo> data, | 337 Handle<FunctionTemplateInfo> data, |
337 Handle<Name> name) { | 338 Handle<Name> name) { |
338 auto serial_number = handle(Smi::cast(data->serial_number()), isolate); | 339 uint32_t serial_number = |
339 if (serial_number->value()) { | 340 static_cast<uint32_t>(Smi::cast(data->serial_number())->value()); |
| 341 if (serial_number) { |
340 // Probe cache. | 342 // Probe cache. |
341 auto cache = isolate->template_instantiations_cache(); | 343 auto cache = isolate->template_instantiations_cache(); |
342 int entry = cache->FindEntry(static_cast<uint32_t>(serial_number->value())); | 344 int entry = cache->FindEntry(serial_number); |
343 if (entry != UnseededNumberDictionary::kNotFound) { | 345 if (entry != UnseededNumberDictionary::kNotFound) { |
344 Object* element = cache->ValueAt(entry); | 346 Object* element = cache->ValueAt(entry); |
345 return handle(JSFunction::cast(element), isolate); | 347 return handle(JSFunction::cast(element), isolate); |
346 } | 348 } |
347 } | 349 } |
348 // Enter a new scope. Recursion could otherwise create a lot of handles. | 350 // Enter a new scope. Recursion could otherwise create a lot of handles. |
349 HandleScope scope(isolate); | 351 HandleScope scope(isolate); |
350 Handle<JSObject> prototype; | 352 Handle<JSObject> prototype; |
351 if (!data->remove_prototype()) { | 353 if (!data->remove_prototype()) { |
352 auto prototype_templ = handle(data->prototype_template(), isolate); | 354 auto prototype_templ = handle(data->prototype_template(), isolate); |
(...skipping 25 matching lines...) Expand all Loading... |
378 MAYBE_RETURN(JSObject::SetPrototype(prototype, parent_prototype, false, | 380 MAYBE_RETURN(JSObject::SetPrototype(prototype, parent_prototype, false, |
379 Object::THROW_ON_ERROR), | 381 Object::THROW_ON_ERROR), |
380 MaybeHandle<JSFunction>()); | 382 MaybeHandle<JSFunction>()); |
381 } | 383 } |
382 } | 384 } |
383 auto function = ApiNatives::CreateApiFunction( | 385 auto function = ApiNatives::CreateApiFunction( |
384 isolate, data, prototype, ApiNatives::JavaScriptObjectType); | 386 isolate, data, prototype, ApiNatives::JavaScriptObjectType); |
385 if (!name.is_null() && name->IsString()) { | 387 if (!name.is_null() && name->IsString()) { |
386 function->shared()->set_name(*name); | 388 function->shared()->set_name(*name); |
387 } | 389 } |
388 if (serial_number->value()) { | 390 if (serial_number) { |
389 // Cache the function. | 391 // Cache the function. |
390 CacheTemplateInstantiation(isolate, serial_number, function); | 392 CacheTemplateInstantiation(isolate, serial_number, function); |
391 } | 393 } |
392 auto result = | 394 auto result = |
393 ConfigureInstance(isolate, function, data, data->hidden_prototype()); | 395 ConfigureInstance(isolate, function, data, data->hidden_prototype()); |
394 if (result.is_null()) { | 396 if (result.is_null()) { |
395 // Uncache on error. | 397 // Uncache on error. |
396 if (serial_number->value()) { | 398 if (serial_number) { |
397 UncacheTemplateInstantiation(isolate, serial_number); | 399 UncacheTemplateInstantiation(isolate, serial_number); |
398 } | 400 } |
399 return MaybeHandle<JSFunction>(); | 401 return MaybeHandle<JSFunction>(); |
400 } | 402 } |
401 return scope.CloseAndEscape(function); | 403 return scope.CloseAndEscape(function); |
402 } | 404 } |
403 | 405 |
404 | 406 |
405 class InvokeScope { | 407 class InvokeScope { |
406 public: | 408 public: |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 map->set_is_callable(); | 621 map->set_is_callable(); |
620 map->set_is_constructor(true); | 622 map->set_is_constructor(true); |
621 } | 623 } |
622 | 624 |
623 DCHECK(result->shared()->IsApiFunction()); | 625 DCHECK(result->shared()->IsApiFunction()); |
624 return result; | 626 return result; |
625 } | 627 } |
626 | 628 |
627 } // namespace internal | 629 } // namespace internal |
628 } // namespace v8 | 630 } // namespace v8 |
OLD | NEW |