Home | History | Annotate | Download | only in src
      1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 "use strict";
      6 
      7 // This file contains infrastructure used by the API.  See
      8 // v8natives.js for an explanation of these files are processed and
      9 // loaded.
     10 
     11 
     12 function CreateDate(time) {
     13   var date = new $Date();
     14   date.setTime(time);
     15   return date;
     16 }
     17 
     18 
     19 var kApiFunctionCache = new InternalArray();
     20 var functionCache = kApiFunctionCache;
     21 
     22 
     23 function Instantiate(data, name) {
     24   if (!%IsTemplate(data)) return data;
     25   var tag = %GetTemplateField(data, kApiTagOffset);
     26   switch (tag) {
     27     case kFunctionTag:
     28       return InstantiateFunction(data, name);
     29     case kNewObjectTag:
     30       var Constructor = %GetTemplateField(data, kApiConstructorOffset);
     31       // Note: Do not directly use a function template as a condition, our
     32       // internal ToBoolean doesn't handle that!
     33       var result;
     34       if (typeof Constructor === 'undefined') {
     35         result = {};
     36         ConfigureTemplateInstance(result, data);
     37       } else {
     38         // ConfigureTemplateInstance is implicitly called before calling the API
     39         // constructor in HandleApiCall.
     40         result = new (Instantiate(Constructor))();
     41         result = %ToFastProperties(result);
     42       }
     43       return result;
     44     default:
     45       throw 'Unknown API tag <' + tag + '>';
     46   }
     47 }
     48 
     49 
     50 function InstantiateFunction(data, name) {
     51   // We need a reference to kApiFunctionCache in the stack frame
     52   // if we need to bail out from a stack overflow.
     53   var cache = kApiFunctionCache;
     54   var serialNumber = %GetTemplateField(data, kApiSerialNumberOffset);
     55   var isFunctionCached =
     56    (serialNumber in cache) && (cache[serialNumber] != kUninitialized);
     57   if (!isFunctionCached) {
     58     try {
     59       var flags = %GetTemplateField(data, kApiFlagOffset);
     60       var prototype;
     61       if (!(flags & (1 << kRemovePrototypeBit))) {
     62         var template = %GetTemplateField(data, kApiPrototypeTemplateOffset);
     63         prototype = typeof template === 'undefined'
     64             ?  {} : Instantiate(template);
     65 
     66         var parent = %GetTemplateField(data, kApiParentTemplateOffset);
     67         // Note: Do not directly use a function template as a condition, our
     68         // internal ToBoolean doesn't handle that!
     69         if (typeof parent !== 'undefined') {
     70           var parent_fun = Instantiate(parent);
     71           %InternalSetPrototype(prototype, parent_fun.prototype);
     72         }
     73       }
     74       var fun = %CreateApiFunction(data, prototype);
     75       if (IS_STRING(name)) %FunctionSetName(fun, name);
     76       var doNotCache = flags & (1 << kDoNotCacheBit);
     77       if (!doNotCache) cache[serialNumber] = fun;
     78       ConfigureTemplateInstance(fun, data);
     79       if (doNotCache) return fun;
     80     } catch (e) {
     81       cache[serialNumber] = kUninitialized;
     82       throw e;
     83     }
     84   }
     85   return cache[serialNumber];
     86 }
     87 
     88 
     89 function ConfigureTemplateInstance(obj, data) {
     90   var properties = %GetTemplateField(data, kApiPropertyListOffset);
     91   if (!properties) return;
     92   // Disable access checks while instantiating the object.
     93   var requires_access_checks = %DisableAccessChecks(obj);
     94   try {
     95     for (var i = 1; i < properties[0];) {
     96       var length = properties[i];
     97       if (length == 3) {
     98         var name = properties[i + 1];
     99         var prop_data = properties[i + 2];
    100         var attributes = properties[i + 3];
    101         var value = Instantiate(prop_data, name);
    102         %AddPropertyForTemplate(obj, name, value, attributes);
    103       } else if (length == 4 || length == 5) {
    104         // TODO(verwaest): The 5th value used to be access_control. Remove once
    105         // the bindings are updated.
    106         var name = properties[i + 1];
    107         var getter = properties[i + 2];
    108         var setter = properties[i + 3];
    109         var attribute = properties[i + 4];
    110         %DefineApiAccessorProperty(obj, name, getter, setter, attribute);
    111       } else {
    112         throw "Bad properties array";
    113       }
    114       i += length + 1;
    115     }
    116   } finally {
    117     if (requires_access_checks) %EnableAccessChecks(obj);
    118   }
    119 }
    120