Do not cache functions until we know they are fully constructed. This is needed in...
authorolehougaard <olehougaard@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 13 Jan 2009 07:13:33 +0000 (07:13 +0000)
committerolehougaard <olehougaard@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 13 Jan 2009 07:13:33 +0000 (07:13 +0000)
Review URL: http://codereview.chromium.org/17354

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1056 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/apinatives.js
src/execution.cc

index 8ae80e7c04e44a5abab95ccc15cb9e4a9b02956a..d7d49fcb92f1a187718cbba6037170a2e0436c41 100644 (file)
@@ -59,23 +59,34 @@ function Instantiate(data, name) {
 
 
 function InstantiateFunction(data, name) {
+  // We need a reference to kApiFunctionCache in the stack frame
+  // if we need to bail out from a stack overflow.
+  var cache = kApiFunctionCache;
   var serialNumber = %GetTemplateField(data, kApiSerialNumberOffset);
-  if (!(serialNumber in kApiFunctionCache)) {
-    kApiFunctionCache[serialNumber] = null;
-    var fun = %CreateApiFunction(data);
-    if (name) %FunctionSetName(fun, name);
-    kApiFunctionCache[serialNumber] = fun;
-    var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
-    fun.prototype = prototype ? Instantiate(prototype) : {};
-    %SetProperty(fun.prototype, "constructor", fun, DONT_ENUM);
-    var parent = %GetTemplateField(data, kApiParentTemplateOffset);
-    if (parent) {
-      var parent_fun = Instantiate(parent);
-      fun.prototype.__proto__ = parent_fun.prototype;
+  var isFunctionCached =
+   (serialNumber in cache) &&
+   (cache[serialNumber] != -1);
+  if (!isFunctionCached) {
+    try {
+      cache[serialNumber] = null;
+      var fun = %CreateApiFunction(data);
+      if (name) %FunctionSetName(fun, name);
+      cache[serialNumber] = fun;
+      var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
+      fun.prototype = prototype ? Instantiate(prototype) : {};
+      %SetProperty(fun.prototype, "constructor", fun, DONT_ENUM);
+      var parent = %GetTemplateField(data, kApiParentTemplateOffset);
+      if (parent) {
+        var parent_fun = Instantiate(parent);
+        fun.prototype.__proto__ = parent_fun.prototype;
+      }
+      ConfigureTemplateInstance(fun, data);
+    } catch (e) {
+      cache[serialNumber] = -1;
+      throw e;
     }
-    ConfigureTemplateInstance(fun, data);
   }
-  return kApiFunctionCache[serialNumber];
+  return cache[serialNumber];
 }
 
 
index 7ccef5ebf86c81d7d04d1986d1c116296176cdc4..cb053143a15f8bf06970059d39b832fe84cb1009 100644 (file)
@@ -439,7 +439,7 @@ Handle<JSFunction> Execution::InstantiateFunction(
   int serial_number = Smi::cast(data->serial_number())->value();
   Object* elm =
       Top::global_context()->function_cache()->GetElement(serial_number);
-  if (!elm->IsUndefined()) return Handle<JSFunction>(JSFunction::cast(elm));
+  if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm));
   // The function has not yet been instantiated in this context; do it.
   Object** args[1] = { Handle<Object>::cast(data).location() };
   Handle<Object> result =