1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file. 47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/renderer/safe_builtins.h" 67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/logging.h" 87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/stl_util.h" 97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/stringprintf.h" 10a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/renderer/script_context.h" 117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace extensions { 137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace { 157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const char kClassName[] = "extensions::SafeBuiltins"; 177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Documentation for makeCallback in the JavaScript, out here to reduce the 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// (very small) amount of effort that the v8 parser needs to do: 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Returns a new object with every function on |obj| configured to call()\n" 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// itself with the given arguments.\n" 237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// E.g. given\n" 247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// var result = makeCallable(Function.prototype)\n" 257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// |result| will be a object including 'bind' such that\n" 267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// result.bind(foo, 1, 2, 3);\n" 277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// is equivalent to Function.prototype.bind.call(foo, 1, 2, 3), and so on.\n" 287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// This is a convenient way to save functions that user scripts may clobber.\n" 297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const char kScript[] = 307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "(function() {\n" 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "'use strict';\n" 327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "native function Apply();\n" 337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "native function Save();\n" 347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "\n" 357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "// Used in the callback implementation, could potentially be clobbered.\n" 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "function makeCallable(obj, target, isStatic, propertyNames) {\n" 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " propertyNames.forEach(function(propertyName) {\n" 387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) " var property = obj[propertyName];\n" 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " target[propertyName] = function() {\n" 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " var recv = obj;\n" 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " var firstArgIndex = 0;\n" 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " if (!isStatic) {\n" 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " if (arguments.length == 0)\n" 4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) " throw 'There must be at least one argument, the receiver';\n" 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " recv = arguments[0];\n" 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " firstArgIndex = 1;\n" 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " }\n" 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " return Apply(\n" 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " property, recv, arguments, firstArgIndex, arguments.length);\n" 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " };\n" 517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) " });\n" 527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "}\n" 537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "\n" 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "function saveBuiltin(builtin, protoPropertyNames, staticPropertyNames) {\n" 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " var safe = function() {\n" 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " throw 'Safe objects cannot be called nor constructed. ' +\n" 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " 'Use $Foo.self() or new $Foo.self() instead.';\n" 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " };\n" 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " safe.self = builtin;\n" 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " makeCallable(builtin.prototype, safe, false, protoPropertyNames);\n" 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " if (staticPropertyNames)\n" 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " makeCallable(builtin, safe, true, staticPropertyNames);\n" 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " Save(builtin.name, safe);\n" 647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "}\n" 657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "\n" 6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "// Save only what is needed by the extension modules.\n" 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "saveBuiltin(Object,\n" 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " ['hasOwnProperty'],\n" 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " ['create', 'defineProperty', 'getOwnPropertyDescriptor',\n" 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " 'getPrototypeOf', 'keys']);\n" 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "saveBuiltin(Function,\n" 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " ['apply', 'bind', 'call']);\n" 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "saveBuiltin(Array,\n" 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " ['concat', 'forEach', 'indexOf', 'join', 'push', 'slice',\n" 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " 'splice', 'map', 'filter']);\n" 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "saveBuiltin(String,\n" 7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) " ['indexOf', 'slice', 'split']);\n" 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "saveBuiltin(RegExp,\n" 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " ['test']);\n" 8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "saveBuiltin(Error,\n" 8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) " [],\n" 8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) " ['captureStackTrace']);\n" 837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "\n" 847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "// JSON is trickier because extensions can override toJSON in\n" 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "// incompatible ways, and we need to prevent that.\n" 867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "var builtinTypes = [\n" 877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " Object, Function, Array, String, Boolean, Number, Date, RegExp\n" 887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "];\n" 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "var builtinToJSONs = builtinTypes.map(function(t) {\n" 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " return t.toJSON;\n" 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "});\n" 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "var builtinArray = Array;\n" 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "var builtinJSONStringify = JSON.stringify;\n" 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Save('JSON', {\n" 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " parse: JSON.parse,\n" 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " stringify: function(obj) {\n" 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " var savedToJSONs = new builtinArray(builtinTypes.length);\n" 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " try {\n" 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " for (var i = 0; i < builtinTypes.length; ++i) {\n" 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " try {\n" 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " if (builtinTypes[i].prototype.toJSON !==\n" 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " builtinToJSONs[i]) {\n" 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " savedToJSONs[i] = builtinTypes[i].prototype.toJSON;\n" 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " builtinTypes[i].prototype.toJSON = builtinToJSONs[i];\n" 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " }\n" 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " } catch (e) {}\n" 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " }\n" 108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " } catch (e) {}\n" 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " try {\n" 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " return builtinJSONStringify(obj);\n" 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " } finally {\n" 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " for (var i = 0; i < builtinTypes.length; ++i) {\n" 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " try {\n" 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " if (i in savedToJSONs)\n" 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " builtinTypes[i].prototype.toJSON = savedToJSONs[i];\n" 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " } catch (e) {}\n" 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " }\n" 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " }\n" 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " }\n" 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "});\n" 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "\n" 1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "}());\n"; 1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)v8::Local<v8::String> MakeKey(const char* name, v8::Isolate* isolate) { 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return v8::String::NewFromUtf8( 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) isolate, base::StringPrintf("%s::%s", kClassName, name).c_str()); 1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void SaveImpl(const char* name, 1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) v8::Local<v8::Value> value, 1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) v8::Local<v8::Context> context) { 1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CHECK(!value.IsEmpty() && value->IsObject()) << name; 133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch context->Global()->SetHiddenValue(MakeKey(name, context->GetIsolate()), 134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch value); 1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)v8::Local<v8::Object> Load(const char* name, v8::Handle<v8::Context> context) { 1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) v8::Local<v8::Value> value = 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) context->Global()->GetHiddenValue(MakeKey(name, context->GetIsolate())); 1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CHECK(!value.IsEmpty() && value->IsObject()) << name; 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return value->ToObject(); 1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class ExtensionImpl : public v8::Extension { 1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public: 1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ExtensionImpl() : v8::Extension(kClassName, kScript) {} 1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private: 149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( 150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Isolate* isolate, 1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) v8::Handle<v8::String> name) OVERRIDE { 152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (name->Equals(v8::String::NewFromUtf8(isolate, "Apply"))) 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return v8::FunctionTemplate::New(isolate, Apply); 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (name->Equals(v8::String::NewFromUtf8(isolate, "Save"))) 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return v8::FunctionTemplate::New(isolate, Save); 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NOTREACHED() << *v8::String::Utf8Value(name); 1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return v8::Handle<v8::FunctionTemplate>(); 1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) static void Apply(const v8::FunctionCallbackInfo<v8::Value>& info) { 161a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch CHECK(info.Length() == 5 && info[0]->IsFunction() && // function 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // info[1] could be an object or a string 163a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch info[2]->IsObject() && // args 164a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch info[3]->IsInt32() && // first_arg_index 165a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch info[4]->IsInt32()); // args_length 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch v8::Local<v8::Function> function = info[0].As<v8::Function>(); 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch v8::Local<v8::Object> recv; 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (info[1]->IsObject()) { 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch recv = info[1]->ToObject(); 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (info[1]->IsString()) { 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch recv = v8::StringObject::New(info[1]->ToString())->ToObject(); 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) info.GetIsolate()->ThrowException( 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Exception::TypeError(v8::String::NewFromUtf8( 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) info.GetIsolate(), 176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "The first argument is the receiver and must be an object"))); 1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) v8::Local<v8::Object> args = info[2]->ToObject(); 1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int first_arg_index = static_cast<int>(info[3]->ToInt32()->Value()); 1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int args_length = static_cast<int>(info[4]->ToInt32()->Value()); 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int argc = args_length - first_arg_index; 184a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch scoped_ptr<v8::Local<v8::Value> []> argv(new v8::Local<v8::Value>[argc]); 1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (int i = 0; i < argc; ++i) { 1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CHECK(args->Has(i + first_arg_index)); 1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) argv[i] = args->Get(i + first_arg_index); 1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) v8::Local<v8::Value> return_value = function->Call(recv, argc, argv.get()); 1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!return_value.IsEmpty()) 1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) info.GetReturnValue().Set(return_value); 1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) static void Save(const v8::FunctionCallbackInfo<v8::Value>& info) { 196a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch CHECK(info.Length() == 2 && info[0]->IsString() && info[1]->IsObject()); 197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SaveImpl(*v8::String::Utf8Value(info[0]), 1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) info[1], 199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) info.GetIsolate()->GetCallingContext()); 2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}; 2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace 2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static 206a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochv8::Extension* SafeBuiltins::CreateV8Extension() { return new ExtensionImpl(); } 2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 208a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochSafeBuiltins::SafeBuiltins(ScriptContext* context) : context_(context) {} 2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SafeBuiltins::~SafeBuiltins() {} 2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)v8::Local<v8::Object> SafeBuiltins::GetArray() const { 2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return Load("Array", context_->v8_context()); 2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)v8::Local<v8::Object> SafeBuiltins::GetFunction() const { 2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return Load("Function", context_->v8_context()); 2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochv8::Local<v8::Object> SafeBuiltins::GetJSON() const { 221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return Load("JSON", context_->v8_context()); 222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)v8::Local<v8::Object> SafeBuiltins::GetObjekt() const { 2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return Load("Object", context_->v8_context()); 2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochv8::Local<v8::Object> SafeBuiltins::GetRegExp() const { 229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return Load("RegExp", context_->v8_context()); 230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochv8::Local<v8::Object> SafeBuiltins::GetString() const { 233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return Load("String", context_->v8_context()); 234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)v8::Local<v8::Object> SafeBuiltins::GetError() const { 23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return Load("Error", context_->v8_context()); 23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 240a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} // namespace extensions 241