void setup(Branch& branch) { g_slots.resize(numSlots); for (int i=0; i < numSlots; i++) set_bool(g_slots[i], false); handle_t::setup_type(&handle_type); set_opaque_pointer(&handle_type.parameter, (void*) on_release_func); branch.compile("def alloc_handle(any s) -> any;"); install_function(branch["alloc_handle"], alloc_handle); }
void bug_with_is_major_block() { Block block; Term* f = block.compile("def f() {}"); test_assert(is_major_block(nested_contents(f))); // There was a bug where, if the function was patched with a native handler, it // would no longer be considered a major block. install_function(f, my_native_patch); test_assert(is_major_block(nested_contents(f))); }
void test_release() { Block block; block.compile("type T = handle_type()"); block.compile("def T.release(self)"); install_function(&block, "T.release", my_release_func); Type* T = find_type(&block, "T"); test_assert(T != NULL); test_assert(find_method(NULL, T, "release") != NULL); gTimesReleaseCalled = 0; Value value; make(T, &value); test_assert(is_handle(&value)); test_equals(gTimesReleaseCalled, 0); set_int(handle_get_value(&value), 5); set_null(&value); test_equals(gTimesReleaseCalled, 1); gTimesReleaseCalled = 0; Value value2; make(T, &value); copy(&value, &value2); test_assert(gTimesReleaseCalled == 0); set_null(&value2); test_assert(gTimesReleaseCalled == 0); set_null(&value); test_assert(gTimesReleaseCalled == 1); gTimesReleaseCalled = 0; make(T, &value); make(T, &value2); set_null(&value); test_assert(gTimesReleaseCalled == 1); set_null(&value2); test_assert(gTimesReleaseCalled == 2); }
void native_patch_apply_patch(NativePatch* module, Block* block) { // Walk through list of patches, and try to find any functions to apply them to. std::map<std::string, EvaluateFunc>::const_iterator it; for (it = module->patches.begin(); it != module->patches.end(); ++it) { std::string const& name = it->first; EvaluateFunc evaluateFunc = it->second; Term* term = find_local_name(block, name.c_str()); if (term == NULL) continue; if (!is_function(term)) continue; install_function(term, evaluateFunc); } }
void module_possibly_patch_new_function(World* world, Block* function) { NativePatchWorld* moduleWorld = world->nativePatchWorld; Value globalName; get_global_name(function, &globalName); // No global name: no patch. if (!is_string(&globalName)) return; // Lookup in the global table. caValue* patchEntry = hashtable_get(&moduleWorld->everyPatchedFunction, &globalName); if (patchEntry == NULL) { // No patch for this function. return; } caValue* nativeModuleName = list_get(patchEntry, 0); caValue* functionName = list_get(patchEntry, 1); // Found a patch; apply it. NativePatch* module = get_existing_native_patch(world, as_cstring(nativeModuleName)); if (module == NULL) { std::cout << "in module_possibly_patch_new_function, couldn't find module: " << as_cstring(nativeModuleName) << std::endl; return; } std::map<std::string, EvaluateFunc>::const_iterator it; it = module->patches.find(as_cstring(functionName)); if (it == module->patches.end()) { std::cout << "in module_possibly_patch_new_function, couldn't find function: " << as_cstring(functionName) << std::endl; return; } EvaluateFunc evaluateFunc = it->second; install_function(function->owningTerm, evaluateFunc); }