19258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org// Copyright 2006-2008 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org"use strict"; 6a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This file contains infrastructure used by the API. See 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// v8natives.js for an explanation of these files are processed and 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// loaded. 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenfunction CreateDate(time) { 135d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org var date = new $Date(); 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen date.setTime(time); 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return date; 1641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org} 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgvar kApiFunctionCache = new InternalArray(); 20f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgvar functionCache = kApiFunctionCache; 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.orgfunction Instantiate(data, name) { 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!%IsTemplate(data)) return data; 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen var tag = %GetTemplateField(data, kApiTagOffset); 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (tag) { 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case kFunctionTag: 2841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org return InstantiateFunction(data, name); 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case kNewObjectTag: 3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen var Constructor = %GetTemplateField(data, kApiConstructorOffset); 314acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Note: Do not directly use a function template as a condition, our 324acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // internal ToBoolean doesn't handle that! 33248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org var result; 34248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org if (typeof Constructor === 'undefined') { 35248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org result = {}; 36248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org ConfigureTemplateInstance(result, data); 37248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org } else { 38248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org // ConfigureTemplateInstance is implicitly called before calling the API 39248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org // constructor in HandleApiCall. 40248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org result = new (Instantiate(Constructor))(); 41248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org result = %ToFastProperties(result); 42248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org } 4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen throw 'Unknown API tag <' + tag + '>'; 4643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 4741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org} 4843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.orgfunction InstantiateFunction(data, name) { 513291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // We need a reference to kApiFunctionCache in the stack frame 523291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // if we need to bail out from a stack overflow. 533291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org var cache = kApiFunctionCache; 5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen var serialNumber = %GetTemplateField(data, kApiSerialNumberOffset); 553291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org var isFunctionCached = 563291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org (serialNumber in cache) && (cache[serialNumber] != kUninitialized); 573291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (!isFunctionCached) { 583291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org try { 592c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org var flags = %GetTemplateField(data, kApiFlagOffset); 60a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org var prototype; 613c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org if (!(flags & (1 << kRemovePrototypeBit))) { 62a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org var template = %GetTemplateField(data, kApiPrototypeTemplateOffset); 63a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org prototype = typeof template === 'undefined' 64a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org ? {} : Instantiate(template); 65a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 66662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org var parent = %GetTemplateField(data, kApiParentTemplateOffset); 67662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // Note: Do not directly use a function template as a condition, our 68662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // internal ToBoolean doesn't handle that! 69a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (typeof parent !== 'undefined') { 70662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org var parent_fun = Instantiate(parent); 7131c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org %InternalSetPrototype(prototype, parent_fun.prototype); 72662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } 733291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 74a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org var fun = %CreateApiFunction(data, prototype); 75a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (IS_STRING(name)) %FunctionSetName(fun, name); 76a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org var doNotCache = flags & (1 << kDoNotCacheBit); 77a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (!doNotCache) cache[serialNumber] = fun; 783291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org ConfigureTemplateInstance(fun, data); 79639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (doNotCache) return fun; 803291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } catch (e) { 813291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org cache[serialNumber] = kUninitialized; 823291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org throw e; 8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 853291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org return cache[serialNumber]; 8641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org} 8743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenfunction ConfigureTemplateInstance(obj, data) { 9043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen var properties = %GetTemplateField(data, kApiPropertyListOffset); 911e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (!properties) return; 921e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Disable access checks while instantiating the object. 931e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org var requires_access_checks = %DisableAccessChecks(obj); 941e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org try { 951e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org for (var i = 1; i < properties[0];) { 961e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org var length = properties[i]; 971e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (length == 3) { 98870a0b67c822d289024711912e2512af01b66c3bager@chromium.org var name = properties[i + 1]; 99870a0b67c822d289024711912e2512af01b66c3bager@chromium.org var prop_data = properties[i + 2]; 100870a0b67c822d289024711912e2512af01b66c3bager@chromium.org var attributes = properties[i + 3]; 101870a0b67c822d289024711912e2512af01b66c3bager@chromium.org var value = Instantiate(prop_data, name); 1025de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org %AddPropertyForTemplate(obj, name, value, attributes); 103975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org } else if (length == 4 || length == 5) { 104975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org // TODO(verwaest): The 5th value used to be access_control. Remove once 105975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org // the bindings are updated. 1061e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org var name = properties[i + 1]; 107dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org var getter = properties[i + 2]; 108dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org var setter = properties[i + 3]; 1091e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org var attribute = properties[i + 4]; 110dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org %DefineApiAccessorProperty(obj, name, getter, setter, attribute); 1111e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } else { 1121e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org throw "Bad properties array"; 113870a0b67c822d289024711912e2512af01b66c3bager@chromium.org } 1141e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org i += length + 1; 11543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1161e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } finally { 1171e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (requires_access_checks) %EnableAccessChecks(obj); 11843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 11941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org} 120