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 12function CreateDate(time) { 13 var date = new $Date(); 14 date.setTime(time); 15 return date; 16} 17 18 19var kApiFunctionCache = new InternalArray(); 20var functionCache = kApiFunctionCache; 21 22 23function 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 50function 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 89function 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