/* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2013 Jay Freeman (saurik)
+ * Copyright (C) 2009-2014 Jay Freeman (saurik)
*/
-/* GNU General Public License, Version 3 {{{ */
+/* GNU Affero General Public License, Version 3 {{{ */
/*
- * Cycript is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation, either version 3 of the License,
- * or (at your option) any later version.
- *
- * Cycript is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Cycript. If not, see <http://www.gnu.org/licenses/>.
+ * GNU Affero General Public License for more details.
+
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
/* }}} */
#include "JavaScript.hpp"
#include "String.hpp"
-struct CYHooks *hooks_;
+std::vector<CYHook *> hooks_;
+
+CYRegisterHook::CYRegisterHook(CYHook *hook) {
+ hooks_.push_back(hook);
+}
/* JavaScript Properties {{{ */
bool CYHasProperty(JSContextRef context, JSObjectRef object, JSStringRef name) {
break;
default:
- if (hooks_ != NULL && hooks_->PoolFFI != NULL)
- if ((*hooks_->PoolFFI)(pool, context, type, ffi, data, value))
- return;
+ for (CYHook *hook : hooks_)
+ if (hook->PoolFFI != NULL)
+ if ((*hook->PoolFFI)(pool, context, type, ffi, data, value))
+ return;
CYThrow("unimplemented signature code: '%c''\n", type->primitive);
}
null:
return CYJSNull(context);
default:
- if (hooks_ != NULL && hooks_->FromFFI != NULL)
- if (JSValueRef value = (*hooks_->FromFFI)(context, type, ffi, data, initialize, owner))
- return value;
+ for (CYHook *hook : hooks_)
+ if (hook->FromFFI != NULL)
+ if (JSValueRef value = (*hook->FromFFI)(context, type, ffi, data, initialize, owner))
+ return value;
CYThrow("unimplemented signature code: '%c''\n", type->primitive);
}
uint8_t value[cif->rtype->size];
- if (hooks_ != NULL && hooks_->CallFunction != NULL)
- (*hooks_->CallFunction)(context, cif, function, value, values);
- else
- ffi_call(cif, function, value, values);
+ for (CYHook *hook : hooks_)
+ if (hook->CallFunction != NULL) {
+ // XXX: this only supports one hook, but it is a bad idea anyway
+ (*hook->CallFunction)(context, cif, function, value, values);
+ goto from;
+ }
+ ffi_call(cif, function, value, values);
+ from:
return CYFromFFI(context, signature->elements[0].type, cif->rtype, value, initialize);
}
return JSContextGetGlobalObject(context);
}
+// XXX: this is neither exceptin safe nor even terribly sane
class ExecutionHandle {
private:
JSContextRef context_;
- void *handle_;
+ std::vector<void *> handles_;
public:
ExecutionHandle(JSContextRef context) :
context_(context)
{
- if (hooks_ != NULL && hooks_->ExecuteStart != NULL)
- handle_ = (*hooks_->ExecuteStart)(context_);
- else
- handle_ = NULL;
+ handles_.resize(hooks_.size());
+ for (size_t i(0); i != hooks_.size(); ++i) {
+ CYHook *hook(hooks_[i]);
+ if (hook->ExecuteStart != NULL)
+ handles_[i] = (*hook->ExecuteStart)(context_);
+ else
+ handles_[i] = NULL;
+ }
}
~ExecutionHandle() {
- if (hooks_ != NULL && hooks_->ExecuteEnd != NULL)
- (*hooks_->ExecuteEnd)(context_, handle_);
+ for (size_t i(hooks_.size()); i != 0; --i) {
+ CYHook *hook(hooks_[i-1]);
+ if (hook->ExecuteEnd != NULL)
+ (*hook->ExecuteEnd)(context_, handles_[i-1]);
+ }
}
};
Result_ = JSStringCreateWithUTF8CString("_");
- if (hooks_ != NULL && hooks_->Initialize != NULL)
- (*hooks_->Initialize)();
+ for (CYHook *hook : hooks_)
+ if (hook->Initialize != NULL)
+ (*hook->Initialize)();
}
void CYThrow(JSContextRef context, JSValueRef value) {
if (code.data == NULL) {
if (strchr(name, '/') == NULL && (
+#ifdef __APPLE__
dlopen(pool.strcat("/System/Library/Frameworks/", name, ".framework/", name, NULL), RTLD_LAZY | RTLD_GLOBAL) != NULL ||
dlopen(pool.strcat("/System/Library/PrivateFrameworks/", name, ".framework/", name, NULL), RTLD_LAZY | RTLD_GLOBAL) != NULL ||
+#endif
false))
return CYJSUndefined(NULL);
if (CYBridgeEntry *entry = CYBridgeHash("1dlerror", 8))
entry->cache_ = new cy::Functor(entry->value_, reinterpret_cast<void (*)()>(&dlerror));
- if (hooks_ != NULL && hooks_->SetupContext != NULL)
- (*hooks_->SetupContext)(context);
+ for (CYHook *hook : hooks_)
+ if (hook->SetupContext != NULL)
+ (*hook->SetupContext)(context);
CYArrayPush(context, alls, cycript);
}