OLD | NEW |
| (Empty) |
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 } | |
OLD | NEW |