From 0c5f1854c0cc74076ccf48dc902115f0cbc49a89 Mon Sep 17 00:00:00 2001 From: "gears.daemon" Date: Wed, 13 Feb 2008 19:01:03 +0000 Subject: [PATCH] [Author: aa] Finish dispatcher-based modules. * Implement ModuleWrapper for IE. * Add JsParamFetcher::SetReturnValue(JsToken) for Firefox, which is needed so that GearsFactory can return dispatcher-based modules. * Remove support for ISupports modules from JsCallContext. This was added because cdevries was thinking he'd use JsCallContext in an ISupports module, but we since have decided that it makes sense to make JsParamFetcher ISupports-only and JsCallContext dispatcher-only. * Fix a bug in JsParamToToken for doubles. * Add a stub for the DatabaseManager module (part of Database2) as a test. PRESUBMIT=passed R=michaeln CC=google-gears-eng@googlegroups.com DELTA=1052 (407 added, 532 deleted, 113 changed) OCL=6406911 SCL=6440934 git-svn-id: https://google-gears.googlecode.com/svn/trunk@919 fe895e04-df30-0410-9975-d76d301b4276 --- gears/Makefile | 36 +---- gears/base/common/base_class.cc | 24 ++- gears/base/common/base_class.h | 62 +++++--- gears/base/common/dispatcher.cc | 11 ++ gears/base/common/dispatcher.h | 2 + gears/base/common/js_runner_ff.cc | 8 - gears/base/common/js_runner_ff_marshaling.cc | 19 ++- gears/base/common/js_types.cc | 80 ++++------ gears/base/common/js_types.h | 4 +- gears/base/common/module_wrapper.h | 2 + gears/base/firefox/module.cc | 30 ---- gears/base/firefox/module_wrapper.h | 30 ++-- gears/base/ie/interfaces.idl.m4 | 14 -- gears/base/ie/module_wrapper.cc | 229 ++++++++++----------------- gears/base/ie/module_wrapper.h | 97 ++++++++++-- gears/base/npapi/module_wrapper.h | 4 +- gears/cctests/test.cc | 76 +++------ gears/cctests/{test_ie.idl => test.h} | 46 +++--- gears/cctests/test_ff.h | 67 -------- gears/cctests/test_ff.idl.m4 | 40 ----- gears/cctests/test_ie.h | 68 -------- gears/database/npapi/result_set.cc | 6 +- gears/factory/firefox/factory.cc | 131 ++++++++++----- gears/factory/firefox/factory.h | 9 ++ gears/factory/ie/factory.cc | 83 +++++++--- gears/factory/ie/factory.h | 9 ++ gears/test/testcases/internal_tests.js | 2 +- gears/tools/rules.mk | 14 +- 28 files changed, 539 insertions(+), 664 deletions(-) rewrite gears/base/ie/module_wrapper.cc (61%) rename gears/cctests/{test_ie.idl => test.h} (72%) delete mode 100644 gears/cctests/test_ff.h delete mode 100644 gears/cctests/test_ff.idl.m4 delete mode 100644 gears/cctests/test_ie.h diff --git a/gears/Makefile b/gears/Makefile index c62052e..4d270d4 100644 --- a/gears/Makefile +++ b/gears/Makefile @@ -807,43 +807,11 @@ NPAPI_CPPSRCS += \ ifeq ($(MODE),dbg) -FF_VPATH += \ - cctests \ - $(NULL) - -FF_M4SRCS += \ - test_ff.idl.m4 \ - $(NULL) - -FF_IDLSRCS += \ - test_ff.idl \ - $(NULL) - -FF_CPPSRCS += \ - test.cc \ - $(NULL) - -IE_VPATH += \ +SHARED_VPATH += \ cctests \ $(NULL) -IE_IDLSRCS += \ - test_ie.idl \ - $(NULL) - -IE_CPPSRCS += \ - test.cc \ - $(NULL) - -IEMOBILE_VPATH += \ - cctests \ - $(NULL) - -IEMOBILE_IDLSRCS += \ - test_ie.idl \ - $(NULL) - -IEMOBILE_CPPSRCS += \ +SHARED_CPPSRCS += \ test.cc \ $(NULL) diff --git a/gears/base/common/base_class.cc b/gears/base/common/base_class.cc index ff09686..53acda3 100644 --- a/gears/base/common/base_class.cc +++ b/gears/base/common/base_class.cc @@ -27,6 +27,7 @@ #include "gears/base/common/base_class.h" #include "gears/base/common/js_runner.h" +#include "gears/base/common/module_wrapper.h" #include "gears/base/common/security_model.h" // for kUnknownDomain #include "gears/base/common/string_utils.h" #include "gears/third_party/scoped_ptr/scoped_ptr.h" @@ -115,6 +116,7 @@ bool ModuleImplBaseClass::InitBaseManually(bool is_worker, #if BROWSER_FF worker_js_argc_ = 0; worker_js_argv_ = NULL; + worker_js_retval_ = NULL; #elif BROWSER_IE // These do not exist in IE yet. #endif @@ -156,29 +158,31 @@ JsRunnerInterface *ModuleImplBaseClass::GetJsRunner() const { return js_runner_; } -#if BROWSER_NPAPI || BROWSER_FF -void ModuleImplBaseClass::AddRef() { - js_wrapper_->AddRef(); +void ModuleImplBaseClass::AddReference() { + assert(js_wrapper_); + js_wrapper_->AddReference(); } -void ModuleImplBaseClass::Release() { - js_wrapper_->Release(); +void ModuleImplBaseClass::RemoveReference() { + assert(js_wrapper_); + js_wrapper_->RemoveReference(); } JsToken ModuleImplBaseClass::GetWrapperToken() const { return js_wrapper_->GetWrapperToken(); } -#endif //----------------------------------------------------------------------------- #if BROWSER_FF // the rest of this file only applies to Firefox, for now -void ModuleImplBaseClass::JsWorkerSetParams(int argc, JsToken *argv) { +void ModuleImplBaseClass::JsWorkerSetParams(int argc, JsToken *argv, + JsToken *retval) { assert(is_initialized_); worker_js_argc_ = argc; worker_js_argv_ = argv; + worker_js_retval_ = retval; } int ModuleImplBaseClass::JsWorkerGetArgc() const { @@ -193,5 +197,11 @@ JsToken* ModuleImplBaseClass::JsWorkerGetArgv() const { return worker_js_argv_; } +JsToken *ModuleImplBaseClass::JsWorkerGetRetVal() const { + assert(is_initialized_); + assert(EnvIsWorker()); + return worker_js_retval_; +} + #endif // BROWSER_FF //----------------------------------------------------------------------------- diff --git a/gears/base/common/base_class.h b/gears/base/common/base_class.h index e1893e0..1981e10 100644 --- a/gears/base/common/base_class.h +++ b/gears/base/common/base_class.h @@ -110,24 +110,25 @@ class ModuleImplBaseClass { #if BROWSER_FF // JavaScript worker-thread parameter information - void JsWorkerSetParams(int argc, JsToken *argv); + void JsWorkerSetParams(int argc, JsToken *argv, JsToken *retval); int JsWorkerGetArgc() const; JsToken* JsWorkerGetArgv() const; + JsToken* JsWorkerGetRetVal() const; #elif BROWSER_IE // These do not exist in IE yet. #endif -#if BROWSER_NPAPI || BROWSER_FF // Methods for dealing with the JavaScript wrapper interface. void SetJsWrapper(ModuleWrapperBaseClass *wrapper) { js_wrapper_ = wrapper; } ModuleWrapperBaseClass *GetWrapper() const { assert(js_wrapper_); return js_wrapper_; } - void AddRef(); - void Release(); + void AddReference(); + void RemoveReference(); + + // TODO(aa): Remove and replace call sites with GetWrapper()->GetToken(). JsToken GetWrapperToken() const; -#endif private: // TODO(cprince): This state should be constant per (thread,page) tuple. @@ -138,6 +139,9 @@ class ModuleImplBaseClass { bool is_initialized_; bool env_is_worker_; #if BROWSER_FF || BROWSER_NPAPI + // TODO_REMOVE_NSISUPPORTS: Remove this member once all modules are based on + // Dispatcher. env_page_js_context_ is only really used to initialize + // JsParamFetcher, which isn't needed with Dispatcher. JsContextPtr env_page_js_context_; #elif BROWSER_IE // Pointer to the object that hosts this object. On Win32, this is the pointer @@ -160,16 +164,14 @@ class ModuleImplBaseClass { #if BROWSER_FF int worker_js_argc_; JsToken *worker_js_argv_; + JsToken *worker_js_retval_; #elif BROWSER_IE // These do not exist in IE yet. #endif JsRunnerInterface *js_runner_; - -#if BROWSER_NPAPI || BROWSER_FF // Weak pointer to our JavaScript wrapper. ModuleWrapperBaseClass *js_wrapper_; -#endif DISALLOW_EVIL_CONSTRUCTORS(ModuleImplBaseClass); }; @@ -195,8 +197,6 @@ class ModuleImplBaseClassVirtual : public ModuleImplBaseClass { class DispatcherInterface; -// TODO(mpcomplete): implement the rest of this for other platforms. - // Interface for the wrapper class that binds the Gears object to the // JavaScript engine. class ModuleWrapperBaseClass { @@ -205,26 +205,25 @@ class ModuleWrapperBaseClass { // JsRunnerInterface. virtual JsToken GetWrapperToken() const = 0; - // Adds a reference to the wrapper class. - virtual void AddRef() = 0; - - // Releases a reference to the wrapper class. - virtual void Release() = 0; - // Gets the Dispatcher for this module. virtual DispatcherInterface *GetDispatcher() const = 0; + // Adds a reference to the wrapper class. + virtual void AddReference() = 0; + + // Removes a reference to the wrapper class. + virtual void RemoveReference() = 0; + protected: // Don't allow direct deletion via this interface. virtual ~ModuleWrapperBaseClass() { } }; -#if BROWSER_NPAPI || BROWSER_FF // GComPtr: automatically call Release() class ReleaseWrapperFunctor { public: void operator()(ModuleImplBaseClass *x) const { - if (x != NULL) { x->Release(); } + if (x != NULL) { x->RemoveReference(); } } }; @@ -232,18 +231,29 @@ template class GComPtr : public scoped_token { public: explicit GComPtr(Module *v) - : scoped_token(v) { - if (v) { - v->AddRef(); - } + : scoped_token(v) {} + + Module *operator->() const { return this->get(); } + + // IE expects that when you return an object to script, it has already been + // AddRef()'d. NPAPI and Firefox do not do this. Gears modules should call + // this method after returning a newly created object to script to do the + // right thing. + void ReleaseNewObjectToScript() { +#ifdef BROWSER_IE + // Leave the object AddRef()'d for IE +#else + get()->RemoveReference(); +#endif + release(); } - - Module* operator->() const { return this->get(); } }; -// Creates new Module of the given type. Returns NULL on failure. +// Creates new Module of the given type. Returns NULL on failure. The new +// module's ref count is initialized to 1. Callers should use GComPtr and +// ReleaseNewObjectToScript() with the result of this function to ensure +// consistent behavior across platforms. template Module *CreateModule(JsRunnerInterface *js_runner); -#endif #endif // GEARS_BASE_COMMON_BASE_CLASS_H__ diff --git a/gears/base/common/dispatcher.cc b/gears/base/common/dispatcher.cc index b3d793e..78397b5 100644 --- a/gears/base/common/dispatcher.cc +++ b/gears/base/common/dispatcher.cc @@ -113,6 +113,17 @@ const DispatcherNameList &Dispatcher::GetMemberNames() { return GetThreadLocals().members; } +template +DispatchId Dispatcher::GetDispatchId(const std::string &member_name) { + DispatcherNameList member_names = GetMemberNames(); + DispatcherNameList::iterator result = member_names.find(member_name); + if (result != member_names.end()) { + return result->second; + } else { + return NULL; + } +} + // static template void Dispatcher::RegisterProperty(const char *name, diff --git a/gears/base/common/dispatcher.h b/gears/base/common/dispatcher.h index e614f0c..4d6c928 100644 --- a/gears/base/common/dispatcher.h +++ b/gears/base/common/dispatcher.h @@ -54,6 +54,7 @@ class DispatcherInterface { virtual bool GetProperty(DispatchId property_id, JsCallContext *context) = 0; virtual bool SetProperty(DispatchId property_id, JsCallContext *context) = 0; virtual const DispatcherNameList &GetMemberNames() = 0; + virtual DispatchId GetDispatchId(const std::string &member_name) = 0; }; // The implementation of the DispatcherInterface. Each dispatch target class @@ -84,6 +85,7 @@ class Dispatcher : public DispatcherInterface { virtual bool GetProperty(DispatchId property_id, JsCallContext *context); virtual bool SetProperty(DispatchId property_id, JsCallContext *context); virtual const DispatcherNameList &GetMemberNames(); + virtual DispatchId GetDispatchId(const std::string &member_name); protected: // Register JavaScript property/methods. diff --git a/gears/base/common/js_runner_ff.cc b/gears/base/common/js_runner_ff.cc index 77f20b2..a868f04 100644 --- a/gears/base/common/js_runner_ff.cc +++ b/gears/base/common/js_runner_ff.cc @@ -56,10 +56,6 @@ #include "gears/base/firefox/dom_utils.h" #include "gears/factory/firefox/factory.h" -#ifdef DEBUG -#include "ff/genfiles/test_ff.h" -#endif - static const int kGarbageCollectionIntervalMsec = 2000; // Internal base class used to share some code between DocumentJsRunner and @@ -517,10 +513,6 @@ bool JsRunner::InitJavaScriptEngine() { {GEARSMANAGEDRESOURCESTOREINTERFACE_IID, NULL}, {GEARSRESOURCESTOREINTERFACE_IID, NULL}, // GEARSFILESUBMITTERINTERFACE_IID can never be created in a child worker -#ifdef DEBUG - // test - {GEARSTESTINTERFACE_IID, NULL}, -#endif // blob {GEARSBLOBINTERFACE_IID, NULL}, // timer diff --git a/gears/base/common/js_runner_ff_marshaling.cc b/gears/base/common/js_runner_ff_marshaling.cc index b4328a8..26d8082 100644 --- a/gears/base/common/js_runner_ff_marshaling.cc +++ b/gears/base/common/js_runner_ff_marshaling.cc @@ -598,7 +598,7 @@ class ScopedJsArgSetter { public: // sets argc/argv/context on construction ScopedJsArgSetter(nsISupports *isupports, JSContext *cx, - int argc, jsval *argv) { + int argc, jsval *argv, jsval *retval) { gears_native_ = NULL; // dtor only checks this nsresult nr; gears_idl_ = do_QueryInterface(isupports, &nr); @@ -610,14 +610,15 @@ class ScopedJsArgSetter { assert(cx == gears_native_->EnvPageJsContext()); prev_argc_ = gears_native_->JsWorkerGetArgc(); prev_argv_ = gears_native_->JsWorkerGetArgv(); - gears_native_->JsWorkerSetParams(argc, argv); + prev_retval_ = gears_native_->JsWorkerGetRetVal(); + gears_native_->JsWorkerSetParams(argc, argv, retval); } } } // restores argc/argv/context on destruction ~ScopedJsArgSetter() { if (gears_native_) { - gears_native_->JsWorkerSetParams(prev_argc_, prev_argv_); + gears_native_->JsWorkerSetParams(prev_argc_, prev_argv_, prev_retval_); } } private: @@ -628,6 +629,7 @@ class ScopedJsArgSetter { // for 'onabort', and the JS handler calls any C++ function) int prev_argc_; jsval *prev_argv_; + jsval *prev_retval_; }; @@ -693,6 +695,7 @@ JSBool JsContextWrapper::JsWrapperCaller(JSContext *cx, JSObject *obj, &call_context); } + // NOTE: early return for dispatcher-based modules. return success ? JS_TRUE : JS_FALSE; } @@ -701,7 +704,8 @@ JSBool JsContextWrapper::JsWrapperCaller(JSContext *cx, JSObject *obj, // conversion code. // Give the ModuleImplBaseClass direct access to JS params - ScopedJsArgSetter arg_setter(instance_data->isupports, cx, argc, argv); + ScopedJsArgSetter arg_setter(instance_data->isupports, cx, argc, argv, + js_retval); // Get interface information about this function. const nsXPTMethodInfo *function_info = function_data->function_info; @@ -1182,10 +1186,9 @@ JSBool JsContextWrapper::JsWrapperCaller(JSContext *cx, JSObject *obj, } if (param_info.IsRetval()) { - //if (!cx.GetReturnValueWasSet()) { // I'M NOT SIMULATING THIS; I DON'T THINK I NEED TO BE - // cx.SetRetVal(v); - //} - *js_retval = v; // CPRINCE REPLACEMENT + if (JSVAL_IS_VOID(*js_retval)) // Check to make sure that the js return + // value hasn't been set directly. + *js_retval = v; } else { assert(false); // NOT YET IMPLEMENTED! /*** diff --git a/gears/base/common/js_types.cc b/gears/base/common/js_types.cc index 190fcb8..6175576 100644 --- a/gears/base/common/js_types.cc +++ b/gears/base/common/js_types.cc @@ -1012,13 +1012,13 @@ void ConvertJsParamToToken(const JsParamToSend ¶m, } case JSPARAM_DOUBLE: { const double *value = static_cast(param.value_ptr); - *token = DOUBLE_TO_JSVAL(*value); + jsdouble *js_double = JS_NewDouble(context, *value); + *token = DOUBLE_TO_JSVAL(js_double); break; } case JSPARAM_STRING16: { const std::string16 *value = static_cast( param.value_ptr); - // TODO(cprince): Does this string copy get freed? JSString *js_string = JS_NewUCStringCopyZ( context, reinterpret_cast(value->c_str())); @@ -1058,48 +1058,6 @@ void ConvertJsParamToToken(const JsParamToSend ¶m, } } -// This code is shared between JsCallContext and JsParamFetcher for FF. -// It initialises all the parameters which are members of the respective -// classes, execept obj which is an input parameter. -static void GetContextAndArgs(ModuleImplBaseClass *obj, - JsContextPtr *js_context, - int *js_argc, - JsToken **js_argv, - nsCOMPtr *xpc, - nsCOMPtr *ncc) { - if (obj->EnvIsWorker()) { - *js_context = obj->EnvPageJsContext(); - *js_argc = obj->JsWorkerGetArgc(); - *js_argv = obj->JsWorkerGetArgv(); - } else { - // In the main thread use the caller's current JS context, NOT the context - // where 'obj' was created. These can be different! Each frame has its - // own JS context, and code can reference 'top.OtherFrame.FooObject'. - nsresult nr; - *xpc = do_GetService("@mozilla.org/js/xpc/XPConnect;1", &nr); - if (*xpc && NS_SUCCEEDED(nr)) { - nr = (*xpc)->GetCurrentNativeCallContext(getter_AddRefs(*ncc)); - if (*ncc && NS_SUCCEEDED(nr)) { - (*ncc)->GetJSContext(js_context); - PRUint32 argc; - (*ncc)->GetArgc(&argc); - *js_argc = static_cast(argc); - (*ncc)->GetArgvPtr(js_argv); - } - } - } -} - - -JsCallContext::JsCallContext(ModuleImplBaseClass* obj) - : js_context_(NULL), is_exception_set_(false), - argc_(0), argv_(NULL), retval_(NULL), - js_runner_(obj->GetJsRunner()), - xpc_(NULL), ncc_(NULL) { - GetContextAndArgs(obj, &js_context_, &argc_, &argv_, &xpc_, &ncc_); -} - - JsCallContext::JsCallContext(JsContextPtr cx, JsRunnerInterface *js_runner, int argc, JsToken *argv, JsToken *retval) : js_context_(cx), is_exception_set_(false), @@ -1380,7 +1338,29 @@ int JsCallContext::GetArguments(int output_argc, JsArgument *output_argv) { #if BROWSER_FF // the rest of this file only applies to Firefox, for now JsParamFetcher::JsParamFetcher(ModuleImplBaseClass *obj) { - GetContextAndArgs(obj, &js_context_, &js_argc_, &js_argv_, &xpc_, &ncc_); + if (obj->EnvIsWorker()) { + js_context_ = obj->EnvPageJsContext(); + js_argc_ = obj->JsWorkerGetArgc(); + js_argv_ = obj->JsWorkerGetArgv(); + js_retval_ = obj->JsWorkerGetRetVal(); + } else { + // In the main thread use the caller's current JS context, NOT the context + // where 'obj' was created. These can be different! Each frame has its + // own JS context, and code can reference 'top.OtherFrame.FooObject'. + nsresult nr; + xpc_ = do_GetService("@mozilla.org/js/xpc/XPConnect;1", &nr); + if (xpc_ && NS_SUCCEEDED(nr)) { + nr = xpc_->GetCurrentNativeCallContext(getter_AddRefs(ncc_)); + if (ncc_ && NS_SUCCEEDED(nr)) { + ncc_->GetJSContext(&js_context_); + PRUint32 argc; + ncc_->GetArgc(&argc); + js_argc_ = static_cast(argc); + ncc_->GetArgvPtr(&js_argv_); + ncc_->GetRetValPtr(&js_retval_); + } + } + } } @@ -1451,6 +1431,16 @@ bool JsParamFetcher::GetAsNewRootedCallback(int i, JsRootedCallback **out) { return true; } +void JsParamFetcher::SetReturnValue(JsToken retval) { + if (js_retval_) { + *js_retval_ = retval; + + if (ncc_ != NULL) { + ncc_->SetReturnValueWasSet(PR_TRUE); + } + } +} + JsNativeMethodRetval JsSetException(JsContextPtr cx, JsRunnerInterface *js_runner, const char16 *message, diff --git a/gears/base/common/js_types.h b/gears/base/common/js_types.h index 4eaf211..54b92e0 100644 --- a/gears/base/common/js_types.h +++ b/gears/base/common/js_types.h @@ -389,7 +389,6 @@ class JsCallContext { : disp_params_(disp_params), retval_(retval), exception_info_(excep_info), is_exception_set_(false) {} #elif BROWSER_FF - explicit JsCallContext(ModuleImplBaseClass *obj); JsCallContext(JsContextPtr cx, JsRunnerInterface *js_runner, int argc, JsToken *argv, JsToken *retval); #else @@ -482,10 +481,13 @@ class JsParamFetcher { bool GetAsObject(int i, JsObject *out); bool GetAsNewRootedCallback(int i, JsRootedCallback **out); + void SetReturnValue(JsToken retval); + private: JsContextPtr js_context_; int js_argc_; JsToken *js_argv_; + JsToken *js_retval_; nsCOMPtr xpc_; nsCOMPtr ncc_; diff --git a/gears/base/common/module_wrapper.h b/gears/base/common/module_wrapper.h index c1e7414..e8c0480 100644 --- a/gears/base/common/module_wrapper.h +++ b/gears/base/common/module_wrapper.h @@ -30,6 +30,8 @@ #include "gears/base/npapi/module_wrapper.h" #elif BROWSER_FF #include "gears/base/firefox/module_wrapper.h" +#elif BROWSER_IE +#include "gears/base/ie/module_wrapper.h" #else // TODO: Add more browser support here. #endif diff --git a/gears/base/firefox/module.cc b/gears/base/firefox/module.cc index b239177..be041a6 100644 --- a/gears/base/firefox/module.cc +++ b/gears/base/firefox/module.cc @@ -48,10 +48,6 @@ #include "gears/ui/firefox/ui_utils.h" #include "gears/workerpool/firefox/workerpool.h" -#ifdef DEBUG -#include "gears/cctests/test_ff.h" -#endif - //----------------------------------------------------------------------------- // TODO(cprince): can remove this when switch to google3 logging @@ -167,14 +163,6 @@ NS_DOMCI_EXTENSION(Scour) NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsFileSubmitter, PR_TRUE, &kGearsFileSubmitterClassId) -#ifdef DEBUG - // test - NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsTest) - NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsTestInterface) - NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsTest, PR_TRUE, - &kGearsTestClassId) -#endif - // blob NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsBlob) NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsBlobInterface) @@ -247,13 +235,6 @@ static NS_METHOD ScourRegisterSelf(nsIComponentManager *compMgr, GEARSRESOURCESTOREINTERFACE_IID_STR }, { kGearsFileSubmitterClassName, "GearsFileSubmitterInterface", GEARSFILESUBMITTERINTERFACE_IID_STR }, - -#ifdef DEBUG - // test - { kGearsTestClassName, "GearsTestInterface", - GEARSTESTINTERFACE_IID_STR }, -#endif - // blob { kGearsBlobClassName, "GearsBlobInterface", GEARSBLOBINTERFACE_IID_STR }, @@ -306,11 +287,6 @@ NS_DECL_DOM_CLASSINFO(GearsManagedResourceStore) NS_DECL_DOM_CLASSINFO(GearsResourceStore) NS_DECL_DOM_CLASSINFO(GearsFileSubmitter) -#ifdef DEBUG -// test -NS_DECL_DOM_CLASSINFO(GearsTest) -#endif - // blob NS_DECL_DOM_CLASSINFO(GearsBlob) // timer @@ -342,12 +318,6 @@ void PR_CALLBACK ScourModuleDestructor(nsIModule *self) { NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsLocalServer)); NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsManagedResourceStore)); NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsResourceStore)); - -#ifdef DEBUG - // test - NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsTest)); -#endif - // blob NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsBlob)); // timer diff --git a/gears/base/firefox/module_wrapper.h b/gears/base/firefox/module_wrapper.h index 90bde6e..b57fe72 100644 --- a/gears/base/firefox/module_wrapper.h +++ b/gears/base/firefox/module_wrapper.h @@ -46,20 +46,18 @@ class ModuleWrapper : public ModuleWrapperBaseClass { public: ModuleWrapper(ModuleImplBaseClassVirtual *impl, DispatcherInterface *dispatcher) - : token_(0), ref_count_(0) { + : token_(0), js_context_(NULL), ref_count_(0) { impl_.reset(impl); dispatcher_.reset(dispatcher); } - void SetJsObject(JsToken token) { + void SetJsObject(JsToken token, JsContextPtr js_context) { assert(token_ == 0); assert(token); + assert(!js_context_); + assert(js_context); token_ = token; - } - - virtual DispatcherInterface *GetDispatcher() const { - assert(dispatcher_.get()); - return dispatcher_.get(); + js_context_ = js_context; } virtual JsToken GetWrapperToken() const { @@ -67,19 +65,24 @@ class ModuleWrapper : public ModuleWrapperBaseClass { return token_; } - virtual void AddRef() { + virtual DispatcherInterface *GetDispatcher() const { + assert(dispatcher_.get()); + return dispatcher_.get(); + } + + virtual void AddReference() { assert(JSVAL_IS_GCTHING(token_)); if (1 == AtomicIncrement(&ref_count_, 1)) { - JS_AddRoot(impl_->EnvPageJsContext(), &token_); + JS_AddRoot(js_context_, &token_); } } - virtual void Release() { + virtual void RemoveReference() { assert(JSVAL_IS_GCTHING(token_)); AtomicWord new_ref_count = AtomicIncrement(&ref_count_, -1); assert(new_ref_count >= 0); if (new_ref_count == 0) { - JS_RemoveRoot(impl_->EnvPageJsContext(), &token_); + JS_RemoveRoot(js_context_, &token_); } } @@ -100,6 +103,7 @@ class ModuleWrapper : public ModuleWrapperBaseClass { scoped_ptr dispatcher_; JsToken token_; + JsContextPtr js_context_; AtomicWord ref_count_; DISALLOW_EVIL_CONSTRUCTORS(ModuleWrapper); @@ -123,8 +127,10 @@ GearsClass *CreateModule(JsRunnerInterface *js_runner) { return NULL; } - module_wrapper->SetJsObject(js_object); + module_wrapper->SetJsObject(js_object, js_runner->GetContext()); module_wrapper.release(); + + impl->AddReference(); return impl; } diff --git a/gears/base/ie/interfaces.idl.m4 b/gears/base/ie/interfaces.idl.m4 index 6cd2359..a9840b8 100644 --- a/gears/base/ie/interfaces.idl.m4 +++ b/gears/base/ie/interfaces.idl.m4 @@ -61,10 +61,6 @@ import "localserver/ie/localserver.idl"; import "timer/timer_ie.idl"; import "workerpool/ie/workerpool.idl"; -#ifdef DEBUG -import "cctests/test_ie.idl"; -#endif DEBUG - //------------------------------------------------------------------------------ // GearsTypelib //------------------------------------------------------------------------------ @@ -165,16 +161,6 @@ library GearsTypelib [default] interface GearsDesktopInterface; }; -#ifdef DEBUG - [ - uuid(F98360E4-ECE5-4177-971F-639A0A6D353E) - ] - coclass GearsTest - { - [default] interface GearsTestInterface; - }; -#endif DEBUG - [ uuid(B76AFB62-9BA2-43e8-B27F-9F1CAC8148B7) ] diff --git a/gears/base/ie/module_wrapper.cc b/gears/base/ie/module_wrapper.cc dissimilarity index 61% index 16d93ae..dc7f9f2 100644 --- a/gears/base/ie/module_wrapper.cc +++ b/gears/base/ie/module_wrapper.cc @@ -1,145 +1,84 @@ -// Copyright 2007, Google Inc. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// 3. Neither the name of Google Inc. nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "gears/base/common/common.h" -#include "gears/base/common/js_types.h" -#include "gears/base/common/thread_locals.h" -#include "gears/base/ie/module_wrapper.h" - -const static std::string kCallContextThreadLocalKey("base:modulewrapper"); - -ModuleWrapper::ModuleWrapper() : impl_(NULL) {} - -ModuleWrapper::~ModuleWrapper() {} - -HRESULT ModuleWrapper::GetTypeInfoCount(unsigned int FAR* retval) { - // JavaScript does not call this - assert(false); - return E_NOTIMPL; -} - -HRESULT ModuleWrapper::GetTypeInfo(unsigned int index, LCID lcid, - ITypeInfo FAR* FAR* retval) { - // JavaScript does not call this - assert(false); - return E_NOTIMPL; -}; - -HRESULT ModuleWrapper::GetIDsOfNames(REFIID iid, OLECHAR FAR* FAR* names, - unsigned int num_names, LCID lcid, - DISPID FAR* retval) { - // TODO(aa): Get this information from the class itself using something like - // the NPAPI port's RegisterMethod(). - assert(impl_); - return impl_->GetIDsOfNames(iid, names, num_names, lcid, retval); -} - -HRESULT ModuleWrapper::Invoke(DISPID member_id, REFIID iid, LCID lcid, - WORD flags, DISPPARAMS FAR* params, - VARIANT FAR* retval, EXCEPINFO FAR* exception, - unsigned int FAR* arg_error_index) { - assert(impl_); - - // Our Gears objects do not ever expect any arguments via IDispatch, so we - // create a new params object reflecting that. However JScript does use - // "named args" to indicate when a property is being read or written. So - // copy those values from what the browser specified. - CComVariant variant_arg; - DISPPARAMS wrapped_params; - wrapped_params.cNamedArgs = params->cNamedArgs; - wrapped_params.rgdispidNamedArgs = params->rgdispidNamedArgs; - wrapped_params.rgvarg = &variant_arg; - - if (flags & DISPATCH_PROPERTYPUT) { - // We have to tell COM we are passing a parameter, even though we don't use - // it, otherwise the call is rejected. - wrapped_params.cArgs = 1; - } else { - wrapped_params.cArgs = 0; - } - - JsCallContext js_call_context(params, retval, exception); - - // IDispatch getters do not accept any input params so there is no way to pass - // this JsCallContext to our implementation methods on the stack. Instead, we - // stuff them to the side in this thread-local stack. - // In the future, we will be changing our Gears classes so that they are not - // COM objects and do not implement IDispatch, but instead have their own - // dynamic dispatch implementation. Once that is done, we can get rid of this. - PushJsCallContext(&js_call_context); - - HRESULT hr = impl_->Invoke(member_id, iid, lcid, flags, &wrapped_params, - NULL, NULL, NULL); // result, exception info, bad - // arg index. We use - // JsCallContext for these - // things instead. - PopJsCallContext(); - - - if (js_call_context.is_exception_set()) { - return DISP_E_EXCEPTION; - } else if (FAILED(hr)) { - // Handle generic failures where the Gears module did not specify exception - // details (bad module!). - js_call_context.SetException(GET_INTERNAL_ERROR_MESSAGE()); - return DISP_E_EXCEPTION; - } else { - return S_OK; - } -} - -void ModuleWrapper::PushJsCallContext(JsCallContext *js_call_context) { - JsCallContextStack *context_stack = reinterpret_cast( - ThreadLocals::GetValue(kCallContextThreadLocalKey)); - if (!context_stack) { - context_stack = new JsCallContextStack(); - ThreadLocals::SetValue(kCallContextThreadLocalKey, context_stack, - &DestroyJsCallContextStack); - - } - context_stack->push(js_call_context); -} - -void ModuleWrapper::PopJsCallContext() { - JsCallContextStack *context_stack = reinterpret_cast( - ThreadLocals::GetValue(kCallContextThreadLocalKey)); - assert(context_stack); - assert(context_stack->size() > 0); - context_stack->pop(); -} - -JsCallContext *ModuleWrapper::PeekJsCallContext() { - JsCallContextStack *context_stack = reinterpret_cast( - ThreadLocals::GetValue(kCallContextThreadLocalKey)); - assert(context_stack); - assert(context_stack->size() > 0); - return context_stack->top(); -} - -void ModuleWrapper::DestroyJsCallContextStack(void *context_stack) { - if (context_stack) { - delete reinterpret_cast(context_stack); - } -} +// Copyright 2007, Google Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// 3. Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "gears/base/common/common.h" +#include "gears/base/common/dispatcher.h" +#include "gears/base/common/js_types.h" +#include "gears/base/common/string_utils.h" +#include "gears/base/ie/module_wrapper.h" + +HRESULT ModuleWrapper::GetIDsOfNames(REFIID iid, OLECHAR FAR* FAR* names, + unsigned int num_names, LCID lcid, + DISPID FAR* retval) { + // JavaScript does not have named parameters + assert(num_names == 1); + + std::string member_name_utf8; + if (!String16ToUTF8(static_cast(*names), &member_name_utf8)) { + assert(false); + return DISP_E_UNKNOWNNAME; + } + + DispatchId dispatch_id = dispatcher_->GetDispatchId(member_name_utf8); + if (dispatch_id == NULL) { + *retval = DISPID_UNKNOWN; + return DISP_E_UNKNOWNNAME; + } else { + *retval = reinterpret_cast(dispatch_id); + return S_OK; + } +} + +HRESULT ModuleWrapper::Invoke(DISPID member_id, REFIID iid, LCID lcid, + WORD flags, DISPPARAMS FAR* params, + VARIANT FAR* retval, EXCEPINFO FAR* exception, + unsigned int FAR* arg_error_index) { + assert(dispatcher_.get()); + JsCallContext js_call_context(params, retval, exception); + + DispatchId dispatch_id = reinterpret_cast(member_id); + + if (flags & DISPATCH_METHOD) { + if (!dispatcher_->CallMethod(dispatch_id, &js_call_context)) { + return DISP_E_MEMBERNOTFOUND; + } + } else if (flags & DISPATCH_PROPERTYGET) { + if (!dispatcher_->GetProperty(dispatch_id, &js_call_context)) { + return DISP_E_MEMBERNOTFOUND; + } + } else if (flags & DISPATCH_PROPERTYPUT) { + if (!dispatcher_->SetProperty(dispatch_id, &js_call_context)) { + return DISP_E_MEMBERNOTFOUND; + } + } else { + return DISP_E_MEMBERNOTFOUND; + } + + if (js_call_context.is_exception_set()) { + return DISP_E_EXCEPTION; + } else { + return S_OK; + } +} diff --git a/gears/base/ie/module_wrapper.h b/gears/base/ie/module_wrapper.h index 5260e9e..10feff2 100644 --- a/gears/base/ie/module_wrapper.h +++ b/gears/base/ie/module_wrapper.h @@ -27,12 +27,20 @@ #define GEARS_BASE_IE_MODULE_WRAPPER_H__ #include -#include +#include "gears/base/common/base_class.h" #include "gears/base/common/common.h" +#include "gears/base/common/dispatcher.h" #include "gears/base/common/js_types.h" +#include "gears/base/ie/atl_headers.h" +#include "gears/third_party/scoped_ptr/scoped_ptr.h" -class ATL_NO_VTABLE ModuleWrapper - : public IDispatch, +// Represents the bridge between the JavaScript engine and a Gears module. A +// ModuleWrapper wraps each Gears module instance and exposes its methods to +// JavaScript. The wrapper is ref-counted and has ownership of the module so +// that when all references are released, the module is destroyed. +class ATL_NO_VTABLE ModuleWrapper + : public ModuleWrapperBaseClass, + public IDispatch, public CComObjectRootEx, public CComCoClass { public: @@ -43,15 +51,30 @@ class ATL_NO_VTABLE ModuleWrapper DECLARE_NOT_AGGREGATABLE(ModuleWrapper) DECLARE_PROTECT_FINAL_CONSTRUCT() - ModuleWrapper(); - ~ModuleWrapper(); + ModuleWrapper() { + VariantInit(&token_); + token_.vt = VT_DISPATCH; + token_.pdispVal = const_cast(this); + } + + ~ModuleWrapper() {} static JsCallContext *PeekJsCallContext(); // IDispatch - STDMETHOD(GetTypeInfoCount)(unsigned int FAR* retval); + STDMETHOD(GetTypeInfoCount)(unsigned int FAR* retval) { + // JavaScript does not call this + assert(false); + return E_NOTIMPL; + } + STDMETHOD(GetTypeInfo)(unsigned int index, LCID lcid, - ITypeInfo FAR* FAR* retval); + ITypeInfo FAR* FAR* retval) { + // JavaScript does not call this + assert(false); + return E_NOTIMPL; + } + STDMETHOD(GetIDsOfNames)(REFIID iid, OLECHAR FAR* FAR* names, unsigned int num_names, LCID lcid, DISPID FAR* retval); @@ -60,22 +83,62 @@ class ATL_NO_VTABLE ModuleWrapper EXCEPINFO FAR* exception, unsigned int FAR* arg_error_index); - void Init(IDispatch *impl) { - assert(!impl_); - assert(impl); - impl_ = impl; + // ModuleWrapperBaseClass + // Returns a token for this wrapper class that can be returned via the + // JsRunnerInterface. + virtual JsToken GetWrapperToken() const { + return token_; } - private: - typedef std::stack JsCallContextStack; + // Gets the Dispatcher for this module. + virtual DispatcherInterface *GetDispatcher() const { + assert(dispatcher_.get()); + return dispatcher_.get(); + } - static void PushJsCallContext(JsCallContext *call_context); - static void PopJsCallContext(); - static void DestroyJsCallContextStack(void *call_context); + virtual void AddReference() { + AddRef(); + } - CComPtr impl_; + virtual void RemoveReference() { + Release(); + } + + void Init(ModuleImplBaseClassVirtual *impl, DispatcherInterface *dispatcher) { + assert(!impl_.get()); + assert(impl); + impl_.reset(impl); + + assert(!dispatcher_.get()); + assert(dispatcher); + dispatcher_.reset(dispatcher); + } + + private: + scoped_ptr impl_; + scoped_ptr dispatcher_; + VARIANT token_; DISALLOW_EVIL_CONSTRUCTORS(ModuleWrapper); }; + + +// Creates an instance of the class and its wrapper. +template +GearsClass *CreateModule(JsRunnerInterface *js_runner) { + CComObject *module_wrapper; + HRESULT hr = CComObject::CreateInstance(&module_wrapper); + if (FAILED(hr)) return NULL; + + GearsClass *impl = new GearsClass(); + Dispatcher *dispatcher = new Dispatcher(impl); + + module_wrapper->Init(impl, dispatcher); + impl->SetJsWrapper(module_wrapper); + impl->AddReference(); + + return impl; +} + #endif // GEARS_BASE_IE_MODULE_WRAPPER_H__ diff --git a/gears/base/npapi/module_wrapper.h b/gears/base/npapi/module_wrapper.h index 8e6237b..ee9e787 100644 --- a/gears/base/npapi/module_wrapper.h +++ b/gears/base/npapi/module_wrapper.h @@ -62,8 +62,8 @@ class ModuleWrapper return dispatcher_.get(); } - virtual void AddRef() { NPN_RetainObject(this); } - virtual void Release() { NPN_ReleaseObject(this); } + virtual void AddReference() { NPN_RetainObject(this); } + virtual void RemoveReference() { NPN_ReleaseObject(this); } protected: scoped_ptr impl_; diff --git a/gears/cctests/test.cc b/gears/cctests/test.cc index 8fc6001..d4e3f32 100644 --- a/gears/cctests/test.cc +++ b/gears/cctests/test.cc @@ -25,22 +25,22 @@ #ifdef DEBUG +#include "gears/cctests/test.h" + +#include "gears/base/common/dispatcher.h" +#include "gears/base/common/js_types.h" +#include "gears/base/common/module_wrapper.h" + +DECLARE_GEARS_WRAPPER(GearsTest); + +void Dispatcher::Init() { + RegisterMethod("runTests", &GearsTest::RunTests); +} + #ifdef WIN32 #include // must manually #include before nsIEventQueueService.h #endif -#if BROWSER_FF -#include // for PR_* -#include // for NS_IMPL_* and NS_INTERFACE_* -#include -#include -#include -#include "gears/cctests/test_ff.h" -#elif BROWSER_IE -#include "gears/base/ie/activex_utils.h" -#include "gears/cctests/test_ie.h" -#endif - #include "gears/base/common/name_value_table_test.h" #include "gears/base/common/permissions_db.h" #include "gears/base/common/permissions_db_test.h" @@ -55,34 +55,6 @@ #include "gears/localserver/common/resource_store.h" #include "gears/third_party/scoped_ptr/scoped_ptr.h" -// Constants for returning a boolean value - hopefully there should be a -// standard way to do this one day. -#if BROWSER_FF - const PRBool BROWSER_TRUE = PR_TRUE; - const PRBool BROWSER_FALSE = PR_FALSE; -#elif BROWSER_IE - const VARIANT_BOOL BROWSER_TRUE = VARIANT_TRUE; - const VARIANT_BOOL BROWSER_FALSE = VARIANT_FALSE; -#endif - -#if BROWSER_FF -// Boilerplate. == NS_IMPL_ISUPPORTS + ..._MAP_ENTRY_EXTERNAL_DOM_CLASSINFO -NS_IMPL_ADDREF(GearsTest) -NS_IMPL_RELEASE(GearsTest) -NS_INTERFACE_MAP_BEGIN(GearsTest) - NS_INTERFACE_MAP_ENTRY(GearsBaseClassInterface) - NS_INTERFACE_MAP_ENTRY(GearsTestInterface) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, GearsTestInterface) - NS_INTERFACE_MAP_ENTRY_EXTERNAL_DOM_CLASSINFO(GearsTest) -NS_INTERFACE_MAP_END - -// Object identifiers -const char *kGearsTestClassName = "GearsTest"; -const nsCID kGearsTestClassId = { 0xF2C21A3C, 0x09D2, 0x42ab, { 0xA4, 0x52, - 0xB5, 0xE3, 0x63, 0xF3, 0x71, 0x09 } }; - // {F2C21A3C-09D2-42ab-A452-B5E363F37109} -#endif - bool TestHttpCookies(); bool TestHttpRequest(); bool TestManifest(); @@ -100,21 +72,16 @@ bool TestSerialization(); // from serialization_test.cc bool TestBufferBlob(); -#if BROWSER_FF -NS_IMETHODIMP GearsTest::RunTests(PRBool *retval) { -#elif BROWSER_IE -STDMETHODIMP GearsTest::RunTests(VARIANT_BOOL *retval) { -#endif - *retval = RunTestsImpl() ? BROWSER_TRUE : BROWSER_FALSE; - RETURN_NORMAL(); -} - -bool GearsTest::RunTestsImpl() { +void GearsTest::RunTests(JsCallContext *context) { // We need permissions to use the localserver. SecurityOrigin cc_tests_origin; cc_tests_origin.InitFromUrl(STRING16(L"http://cc_tests/")); PermissionsDB *permissions = PermissionsDB::GetDB(); - if (!permissions) return false; + if (!permissions) { + context->SetException(GET_INTERNAL_ERROR_MESSAGE()); + return; + } + permissions->SetCanAccessGears(cc_tests_origin, PermissionsDB::PERMISSION_ALLOWED); @@ -144,8 +111,8 @@ bool GearsTest::RunTestsImpl() { permissions = PermissionsDB::GetDB(); permissions->SetCanAccessGears(cc_tests_origin, PermissionsDB::PERMISSION_DEFAULT); - - return ok; + + context->SetReturnValue(JSPARAM_BOOL, &ok); } //------------------------------------------------------------------------------ @@ -741,6 +708,7 @@ bool TestBufferBlob() { return false; \ } \ } +#if BROWSER_FF || BROWSER_IE // blobs not implemented for npapi yet int num_bytes = 0; uint8 buffer[64] = {0}; @@ -789,6 +757,8 @@ bool TestBufferBlob() { TEST_ASSERT(buffer[2] == 'e'); TEST_ASSERT(buffer[3] == 'd'); TEST_ASSERT(buffer[4] == 'e'); +#endif + return true; } diff --git a/gears/cctests/test_ie.idl b/gears/cctests/test.h similarity index 72% rename from gears/cctests/test_ie.idl rename to gears/cctests/test.h index 5c6e8da..b982aa2 100644 --- a/gears/cctests/test_ie.idl +++ b/gears/cctests/test.h @@ -1,9 +1,9 @@ -// Copyright 2007, Google Inc. +// Copyright 2008, Google Inc. // -// Redistribution and use in source and binary forms, with or without +// Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, +// 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation @@ -13,34 +13,36 @@ // specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifdef DEBUG -import "oaidl.idl"; -import "ocidl.idl"; +#ifndef GEARS_CCTESTS_TEST_H__ +#define GEARS_CCTESTS_TEST_H__ -// -// GearsTestInterface -// +#include "gears/base/common/base_class.h" +#include "gears/base/common/common.h" + +class GearsTest : public ModuleImplBaseClassVirtual { + public: + GearsTest() : ModuleImplBaseClassVirtual("GearsTest") {} -[ - object, - uuid(27749CE4-EC8C-482b-841A-DD2C3B8C7E29), - dual, - nonextensible, - pointer_default(unique) -] -interface GearsTestInterface : IDispatch { - HRESULT RunTests([out, retval] VARIANT_BOOL *can); + // IN: nothing + // OUT: bool + void RunTests(JsCallContext *context); + + private: + DISALLOW_EVIL_CONSTRUCTORS(GearsTest); }; -#endif DEBUG +#endif // GEARS_CCTESTS_TEST_H__ + +#endif // DEBUG diff --git a/gears/cctests/test_ff.h b/gears/cctests/test_ff.h deleted file mode 100644 index ef565ab..0000000 --- a/gears/cctests/test_ff.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2007, Google Inc. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// 3. Neither the name of Google Inc. nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GEARS_CCTESTS_TEST_FF_H__ -#define GEARS_CCTESTS_TEST_FF_H__ - -#ifdef DEBUG - -#include - -#include "ff/genfiles/test_ff.h" // from OUTDIR -#include "gears/base/common/base_class.h" -#include "gears/base/common/common.h" -#include "gears/base/common/js_runner.h" - -// Object identifiers -extern const char *kGearsTestClassName; -extern const nsCID kGearsTestClassId; - -class GearsTest - : public ModuleImplBaseClass, - public GearsTestInterface { - public: - NS_DECL_ISUPPORTS - GEARS_IMPL_BASECLASS - - // End boilerplate code. Begin interface. - - // need a default constructor to instance objects from the Factory - GearsTest() {} - ~GearsTest() {} - - // JS function is runTests(). - NS_IMETHOD RunTests(PRBool *retval); - - private: - // Generic Cross-Browser function to actually run the tests. - bool RunTestsImpl(); - - DISALLOW_EVIL_CONSTRUCTORS(GearsTest); -}; - -#endif // DEBUG - -#endif // GEARS_CCTESTS_TEST_FF_H__ diff --git a/gears/cctests/test_ff.idl.m4 b/gears/cctests/test_ff.idl.m4 deleted file mode 100644 index cd3d3f8..0000000 --- a/gears/cctests/test_ff.idl.m4 +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2007, Google Inc. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// 3. Neither the name of Google Inc. nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -m4_changequote(`^',`^')m4_dnl -m4_ifdef(^DEBUG^,^m4_dnl - -#include "nsISupports.idl" -#include "base_interface_ff.idl" // XPIDL doesn't like slashes in #includes - -// -// GearsTestInterface -// -[scriptable, function, uuid(F2C21A3C-09D2-42ab-A452-B5E363F37109)] -interface GearsTestInterface : GearsBaseClassInterface { - boolean RunTests(); -}; - -^) diff --git a/gears/cctests/test_ie.h b/gears/cctests/test_ie.h deleted file mode 100644 index 5785b4c..0000000 --- a/gears/cctests/test_ie.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2007, Google Inc. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// 3. Neither the name of Google Inc. nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GEARS_CCTESTS_TEST_IE_H__ -#define GEARS_CCTESTS_TEST_IE_H__ - -#ifdef DEBUG - -#include "gears/base/common/base_class.h" -#include "gears/base/common/common.h" -#include "gears/base/common/js_runner.h" -#include "ie/genfiles/test_ie.h" // from OUTDIR - -class GearsTest - : public ModuleImplBaseClass, - public CComObjectRootEx, - public CComCoClass, - public IDispatchImpl { - public: - BEGIN_COM_MAP(GearsTest) - COM_INTERFACE_ENTRY(GearsTestInterface) - COM_INTERFACE_ENTRY(IDispatch) - END_COM_MAP() - - DECLARE_NOT_AGGREGATABLE(GearsTest) - DECLARE_PROTECT_FINAL_CONSTRUCT() - // End boilerplate code. Begin interface. - - // need a default constructor to instance objects from the Factory - GearsTest() {} - ~GearsTest() {} - - // JS function is runTests(). - STDMETHOD(RunTests)( - /* [retval][out] */ VARIANT_BOOL *retval); - - private: - // Generic Cross-Browser function to actually run the tests. - bool RunTestsImpl(); - - DISALLOW_EVIL_CONSTRUCTORS(GearsTest); -}; - -#endif // DEBUG - -#endif // GEARS_CCTESTS_TEST_IE_H__ diff --git a/gears/database/npapi/result_set.cc b/gears/database/npapi/result_set.cc index 7166d11..562082a 100644 --- a/gears/database/npapi/result_set.cc +++ b/gears/database/npapi/result_set.cc @@ -61,7 +61,7 @@ GearsResultSet::~GearsResultSet() { if (database_ != NULL) { database_->RemoveResultSet(this); - database_->Release(); + database_->RemoveReference(); database_ = NULL; } } @@ -81,7 +81,7 @@ bool GearsResultSet::InitializeResultSet(sqlite3_stmt *statement, Finalize(); } else { database_ = db; - database_->AddRef(); + database_->AddReference(); db->AddResultSet(this); } return succeeded; @@ -91,7 +91,7 @@ void GearsResultSet::PageUnloading() { if (database_ != NULL) { // Don't remove ourselves from the result set, since database_ is going away // soon anyway. - database_->Release(); + database_->RemoveReference(); database_ = NULL; } } diff --git a/gears/factory/firefox/factory.cc b/gears/factory/firefox/factory.cc index 307669b..ca9b51e 100755 --- a/gears/factory/firefox/factory.cc +++ b/gears/factory/firefox/factory.cc @@ -32,10 +32,12 @@ #include "common/genfiles/product_constants.h" // from OUTDIR #include "gears/base/common/common.h" +#include "gears/base/common/module_wrapper.h" #include "gears/base/common/string16.h" #include "gears/base/firefox/dom_utils.h" #include "gears/console/firefox/console_ff.h" #include "gears/database/firefox/database.h" +#include "gears/database2/database_manager.h" #include "gears/desktop/desktop_ff.h" #include "gears/factory/common/factory_utils.h" #include "gears/httprequest/firefox/httprequest_ff.h" @@ -44,7 +46,7 @@ #include "gears/workerpool/firefox/workerpool.h" #ifdef DEBUG -#include "gears/cctests/test_ff.h" +#include "gears/cctests/test.h" #endif // Boilerplate. == NS_IMPL_ISUPPORTS + ..._MAP_ENTRY_EXTERNAL_DOM_CLASSINFO @@ -76,8 +78,6 @@ GearsFactory::GearsFactory() NS_IMETHODIMP GearsFactory::Create(//const nsAString &object //const nsAString &version nsISupports **retval) { - nsresult nr; - // Make sure the user gives this site permission to use Gears. if (!HasPermissionToUseGears(this, NULL, NULL, NULL)) { @@ -112,62 +112,117 @@ NS_IMETHODIMP GearsFactory::Create(//const nsAString &object RETURN_EXCEPTION(STRING16(L"Invalid parameter.")); } + // First try to create a dispatcher-based module. + std::string16 error; + bool success = CreateDispatcherModule(object, &js_params, &error); + + if (success) { + RETURN_NORMAL(); + } else if (error.length() > 0) { + RETURN_EXCEPTION(error.c_str()); + } + + // There was no dispatcher-based implementation of this object. Try to create + // an isupports module. + success = CreateISupportsModule(object, retval, &error); + if (success) { + RETURN_NORMAL(); + } else if (error.length() > 0) { + RETURN_EXCEPTION(error.c_str()); + } else { + RETURN_EXCEPTION(STRING16(L"Unknown object.")); + } +} + +bool GearsFactory::CreateDispatcherModule(const std::string16 &object_name, + JsParamFetcher *js_params, + std::string16 *error) { + GComPtr object(NULL); + + if (object_name == STRING16(L"beta.test")) { +#ifdef DEBUG + object.reset(CreateModule(GetJsRunner())); +#else + *error = STRING16(L"Object is only available in debug build."); + return false; +#endif + } else { + // Don't return an error here. Caller handles reporting unknown modules. + error->clear(); + return false; + } + + if (!object.get()) { + *error = STRING16(L"Failed to create requested object."); + return false; + } + + if (!object->InitBaseFromSibling(this)) { + *error = STRING16(L"Error initializing base class."); + return false; + } + + js_params->SetReturnValue(object->GetWrapperToken()); + object.ReleaseNewObjectToScript(); + return true; +} + +bool GearsFactory::CreateISupportsModule(const std::string16 &object_name, + nsISupports **retval, + std::string16 *error) { nsCOMPtr isupports = NULL; + ModuleImplBaseClass *native_base = NULL; - nr = NS_ERROR_FAILURE; - if (object == STRING16(L"beta.console")) { + nsresult nr = NS_ERROR_FAILURE; + if (object_name == STRING16(L"beta.console")) { isupports = do_QueryInterface(new GearsConsole(), &nr); - } else if (object == STRING16(L"beta.database")) { + } else if (object_name == STRING16(L"beta.database")) { isupports = do_QueryInterface(new GearsDatabase(), &nr); - } else if (object == STRING16(L"beta.desktop")) { + } else if (object_name == STRING16(L"beta.desktop")) { isupports = do_QueryInterface(new GearsDesktop(), &nr); - } else if (object == STRING16(L"beta.httprequest")) { + } else if (object_name == STRING16(L"beta.httprequest")) { isupports = do_QueryInterface(new GearsHttpRequest(), &nr); - } else if (object == STRING16(L"beta.localserver")) { + } else if (object_name == STRING16(L"beta.localserver")) { isupports = do_QueryInterface(new GearsLocalServer(), &nr); - } else if (object == STRING16(L"beta.test")) { -#ifdef DEBUG - isupports = do_QueryInterface(new GearsTest(), &nr); -#else - RETURN_EXCEPTION(STRING16(L"Object is only available in debug build.")); -#endif - } else if (object == STRING16(L"beta.timer")) { + } else if (object_name == STRING16(L"beta.timer")) { isupports = do_QueryInterface(new GearsTimer(), &nr); - } else if (object == STRING16(L"beta.workerpool")) { + } else if (object_name == STRING16(L"beta.workerpool")) { isupports = do_QueryInterface(new GearsWorkerPool(), &nr); } else { - RETURN_EXCEPTION(STRING16(L"Unknown object.")); + // Don't return an error here. Caller handles reporting unknown modules. + error->clear(); + return false; + } + + if (NS_FAILED(nr) || !isupports) { + *error = STRING16(L"Failed to create requested object."); + return false; } // setup the ModuleImplBaseClass (copy settings from this factory) - if (NS_SUCCEEDED(nr) && isupports) { - bool base_init_succeeded = false; - - nsCOMPtr idl_base = - do_QueryInterface(isupports, &nr); - if (NS_SUCCEEDED(nr) && idl_base) { - ModuleImplBaseClass *native_base = NULL; - idl_base->GetNativeBaseClass(&native_base); - if (native_base) { - if (native_base->InitBaseFromSibling(this)) { - base_init_succeeded = true; - } + bool base_init_succeeded = false; + nsCOMPtr idl_base = + do_QueryInterface(isupports, &nr); + if (NS_SUCCEEDED(nr) && idl_base) { + ModuleImplBaseClass *native_base = NULL; + idl_base->GetNativeBaseClass(&native_base); + if (native_base) { + if (native_base->InitBaseFromSibling(this)) { + base_init_succeeded = true; } } - if (!base_init_succeeded) { - RETURN_EXCEPTION(STRING16(L"Error initializing base class.")); - } } - if (NS_FAILED(nr) || !isupports) { - RETURN_EXCEPTION(STRING16(L"Failed to create requested object.")); + if (!base_init_succeeded) { + *error = STRING16(L"Error initializing base class."); + return false; } *retval = isupports.get(); (*retval)->AddRef(); // ~nsCOMPtr will Release, so must AddRef here - assert((*retval)->AddRef() == 3 && - (*retval)->Release() == 2); - RETURN_NORMAL(); + assert((*retval)->AddRef() == 4 && + (*retval)->Release() == 3); + return true; } diff --git a/gears/factory/firefox/factory.h b/gears/factory/firefox/factory.h index aa072b0..f0b4077 100755 --- a/gears/factory/firefox/factory.h +++ b/gears/factory/firefox/factory.h @@ -83,6 +83,15 @@ class GearsFactory const char16 *custom_name, const char16 *custom_message); + // Helper methods used by Create() which create either a dispatcher-based or + // isupports-based module. Returns true if the module was created + // successfully. Returns false and an empty error message if the module is + // unknown. Returns false and an error message for other errors. + bool CreateDispatcherModule(const std::string16 &object_name, + JsParamFetcher *js_params, std::string16 *error); + bool CreateISupportsModule(const std::string16 &object_name, + nsISupports **retval, std::string16 *error); + // A factory starts out operational, but it can be put in a "suspended" state, // unable to create objects. This is important for some use cases, like // cross-origin workers. diff --git a/gears/factory/ie/factory.cc b/gears/factory/ie/factory.cc index e7e4d28..4052e24 100755 --- a/gears/factory/ie/factory.cc +++ b/gears/factory/ie/factory.cc @@ -25,12 +25,14 @@ #include +#include "gears/base/common/module_wrapper.h" #include "gears/base/common/string16.h" #include "gears/base/ie/activex_utils.h" #include "gears/base/ie/atl_headers.h" #include "gears/base/ie/detect_version_collision.h" #include "gears/console/ie/console_ie.h" #include "gears/database/ie/database.h" +#include "gears/database2/database_manager.h" #include "gears/desktop/desktop_ie.h" #include "gears/factory/common/factory_utils.h" #include "gears/factory/ie/factory.h" @@ -40,7 +42,7 @@ #include "gears/workerpool/ie/workerpool.h" #ifdef DEBUG -#include "gears/cctests/test_ie.h" +#include "gears/cctests/test.h" #endif @@ -55,8 +57,6 @@ GearsFactory::GearsFactory() STDMETHODIMP GearsFactory::create(const BSTR object_name_bstr_in, const VARIANT *version_variant, IDispatch **retval) { - HRESULT hr; - const BSTR object_name_bstr = ActiveXUtils::SafeBSTR(object_name_bstr_in); LOG16((L"GearsFactory::create(%s)\n", object_name_bstr)); @@ -97,10 +97,62 @@ STDMETHODIMP GearsFactory::create(const BSTR object_name_bstr_in, // code consistent across callers, and they are easier to support over time. std::string16 object_name(object_name_bstr); + std::string16 error; + bool success = false; + + // Try creating a dispatcher-based module first. + success = CreateDispatcherModule(object_name, retval, &error); + if (success) { + RETURN_NORMAL(); + } else if (error.length() > 0) { + RETURN_EXCEPTION(error.c_str()); + } + + success = CreateComModule(object_name, retval, &error); + if (success) { + RETURN_NORMAL(); + } else if (error.length() > 0) { + RETURN_EXCEPTION(error.c_str()); + } else { + RETURN_EXCEPTION(STRING16(L"Unknown object.")); + } +} + +bool GearsFactory::CreateDispatcherModule(const std::string16 &object_name, + IDispatch **retval, + std::string16 *error) { + GComPtr object(NULL); + + if (object_name == STRING16(L"beta.test")) { +#ifdef DEBUG + object.reset(CreateModule(GetJsRunner())); +#else + *error = STRING16(L"Object is only available in debug build."); + return false; +#endif + } else { + // Don't return an error here. Caller handles reporting unknown modules. + error->clear(); + return false; + } + + // setup the ModuleImplBaseClass (copy settings from this factory) + if (!object->InitBaseFromSibling(this)) { + *error = STRING16(L"Error initializing base class."); + return false; + } + + *retval = object->GetWrapperToken().pdispVal; + object.ReleaseNewObjectToScript(); + return true; +} + +bool GearsFactory::CreateComModule(const std::string16 &object_name, + IDispatch **retval, std::string16 *error) { ModuleImplBaseClass *base_class = NULL; CComQIPtr idispatch; - hr = E_FAIL; + HRESULT hr = E_FAIL; if (0) { // dummy statement to support mixed "#ifdef" and "else if" below #ifdef WINCE // TODO(oshlack): Implement console for WinCE. @@ -111,7 +163,7 @@ STDMETHODIMP GearsFactory::create(const BSTR object_name_bstr_in, base_class = obj; idispatch = obj; #endif - } else if (object_name == STRING16(L"beta.database")) { + } else if (object_name == STRING16(L"beta.database")) { CComObject *obj; hr = CComObject::CreateInstance(&obj); base_class = obj; @@ -135,15 +187,6 @@ STDMETHODIMP GearsFactory::create(const BSTR object_name_bstr_in, hr = CComObject::CreateInstance(&obj); base_class = obj; idispatch = obj; - } else if (object_name == STRING16(L"beta.test")) { -#ifdef DEBUG - CComObject *obj; - hr = CComObject::CreateInstance(&obj); - base_class = obj; - idispatch = obj; -#else - RETURN_EXCEPTION(STRING16(L"Object is only available in debug build.")); -#endif } else if (object_name == STRING16(L"beta.timer")) { CComObject *obj; hr = CComObject::CreateInstance(&obj); @@ -155,16 +198,20 @@ STDMETHODIMP GearsFactory::create(const BSTR object_name_bstr_in, base_class = obj; idispatch = obj; } else { - RETURN_EXCEPTION(STRING16(L"Unknown object.")); + // Don't return an error here. Caller handles reporting unknown modules. + error->clear(); + return false; } if (FAILED(hr) || !base_class || !idispatch) { - RETURN_EXCEPTION(STRING16(L"Failed to create requested object.")); + *error = STRING16(L"Failed to create requested object."); + return false; } // setup the ModuleImplBaseClass (copy settings from this factory) if (!base_class->InitBaseFromSibling(this)) { - RETURN_EXCEPTION(STRING16(L"Error initializing base class.")); + *error = STRING16(L"Error initializing base class."); + return false; } // Our factory-created Gears objects no longer need to be sited, since we get @@ -183,7 +230,7 @@ STDMETHODIMP GearsFactory::create(const BSTR object_name_bstr_in, (*retval)->AddRef(); // ~CComQIPtr will Release, so must AddRef here assert((*retval)->AddRef() == 3 && (*retval)->Release() == 2); - RETURN_NORMAL(); + return true; } diff --git a/gears/factory/ie/factory.h b/gears/factory/ie/factory.h index c5bcf7f..c89d977 100755 --- a/gears/factory/ie/factory.h +++ b/gears/factory/ie/factory.h @@ -107,6 +107,15 @@ class ATL_NO_VTABLE GearsFactory const char16 *custom_name, const char16 *custom_message); + // Helper methods used by Create() which create either a dispatcher-based or + // COM-based module. Returns true if the module was created successfully. + // Returns false and an empty error message if the module is unknown. Returns + // false and an error message for other errors. + bool CreateDispatcherModule(const std::string16 &object_name, + IDispatch **retval, std::string16 *error); + bool CreateComModule(const std::string16 &object_name, IDispatch **retval, + std::string16 *error); + // A factory starts out operational, but it can be put in a "suspended" state, // unable to create objects. This is important for some use cases, like // cross-origin workers. diff --git a/gears/test/testcases/internal_tests.js b/gears/test/testcases/internal_tests.js index 69d3513..6ac0b6a 100644 --- a/gears/test/testcases/internal_tests.js +++ b/gears/test/testcases/internal_tests.js @@ -27,7 +27,7 @@ function testInternal() { if (isDebug) { var internalTests = google.gears.factory.create('beta.test'); - assert(internalTests.RunTests(), + assert(internalTests.runTests(), 'Internal tests failed.'); } } diff --git a/gears/tools/rules.mk b/gears/tools/rules.mk index 51ef6a8..f85278d 100644 --- a/gears/tools/rules.mk +++ b/gears/tools/rules.mk @@ -66,18 +66,22 @@ COMMON_OBJS = \ $(patsubst %.c,$(COMMON_OUTDIR)/%$(OBJ_SUFFIX),$(COMMON_CSRCS)) FF_OBJS = \ $(patsubst %.cc,$(FF_OUTDIR)/%$(OBJ_SUFFIX),$(FF_CPPSRCS)) \ - $(patsubst %.c,$(FF_OUTDIR)/%$(OBJ_SUFFIX),$(FF_CSRCS)) + $(patsubst %.c,$(FF_OUTDIR)/%$(OBJ_SUFFIX),$(FF_CSRCS)) \ + $(patsubst %.cc,$(FF_OUTDIR)/%$(OBJ_SUFFIX),$(SHARED_CPPSRCS)) IE_OBJS = \ $(patsubst %.cc,$(IE_OUTDIR)/%$(OBJ_SUFFIX),$(IE_CPPSRCS)) \ - $(patsubst %.c,$(IE_OUTDIR)/%$(OBJ_SUFFIX),$(IE_CSRCS)) + $(patsubst %.c,$(IE_OUTDIR)/%$(OBJ_SUFFIX),$(IE_CSRCS)) \ + $(patsubst %.cc,$(IE_OUTDIR)/%$(OBJ_SUFFIX),$(SHARED_CPPSRCS)) IEMOBILE_OBJS = \ $(patsubst %.cc,$(IE_OUTDIR)/%$(OBJ_SUFFIX),$(IEMOBILE_CPPSRCS)) \ - $(patsubst %.c,$(IE_OUTDIR)/%$(OBJ_SUFFIX),$(IEMOBILE_CSRCS)) + $(patsubst %.c,$(IE_OUTDIR)/%$(OBJ_SUFFIX),$(IEMOBILE_CSRCS)) \ + $(patsubst %.cc,$(IE_OUTDIR)/%$(OBJ_SUFFIX),$(SHARED_CPPSRCS)) IEMOBILE_SETUP_OBJS = \ $(patsubst %.cc,$(IE_OUTDIR)/%$(OBJ_SUFFIX),$(IEMOBILE_SETUP_CPPSRCS)) NPAPI_OBJS = \ $(patsubst %.cc,$(NPAPI_OUTDIR)/%$(OBJ_SUFFIX),$(NPAPI_CPPSRCS)) \ - $(patsubst %.c,$(NPAPI_OUTDIR)/%$(OBJ_SUFFIX),$(NPAPI_CSRCS)) + $(patsubst %.c,$(NPAPI_OUTDIR)/%$(OBJ_SUFFIX),$(NPAPI_CSRCS)) \ + $(patsubst %.cc,$(NPAPI_OUTDIR)/%$(OBJ_SUFFIX),$(SHARED_CPPSRCS)) LIBGD_OBJS = \ $(patsubst %.c,$(LIBGD_OUTDIR)/%$(OBJ_SUFFIX),$(LIBGD_CSRCS)) SQLITE_OBJS = \ @@ -170,7 +174,7 @@ IEMOBILE_VPATH += $(IE_OUTDIR) NPAPI_VPATH += $(NPAPI_OUTDIR)/genfiles # Make VPATH search our paths before third-party paths. -VPATH += $(COMMON_VPATH) $($(BROWSER)_VPATH) $(THIRD_PARTY_VPATH) +VPATH += $(COMMON_VPATH) $($(BROWSER)_VPATH) $(SHARED_VPATH) $(THIRD_PARTY_VPATH) #----------------------------------------------------------------------------- # OUTPUT FILENAMES -- 2.11.4.GIT