diff -r b029d63565a2 -r c1ba166f3fc4 src/NativeTable.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/NativeTable.cpp Sat Nov 17 18:41:01 2012 -0800 @@ -0,0 +1,96 @@ +/* vim: set ts=4 sw=4 tw=99 et: + * + * Copyright (C) 2012 David Anderson + * + * This file is part of SourcePawn. + * + * SourcePawn 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. + * + * SourcePawn 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 + * SourcePawn. If not, see http://www.gnu.org/licenses/. + */ +#include "Zone.h" +#include "NativeTable.h" +#include "StringPool.h" + +using namespace ke; + +NativeTable::NativeTable(Zone *zone) + : zone_(zone), + nativeMap_(ZoneAllocatorPolicy()) +{ +} + +NativeTable::~NativeTable() +{ + for (size_t i = 0; i < natives_.length(); i++) + delete natives_[i]; +} + +bool +NativeTable::initialize() +{ + return nativeMap_.init(16); +} + +bool +NativeTable::add(Handle name, size_t *indexp) +{ + // :TODO: assert no GC + CharsAndLength key(name->chars(), name->length()); + NativeMap::Insert p = nativeMap_.findForAdd(key); + if (p.found()) { + *indexp = (*p)->index; + return true; + } + + NativeInfo *info = new NativeInfo(name, NULL, natives_.length()); + if (!info || !natives_.append(info)) + return false; + + if (!nativeMap_.add(p, info)) + return false; + + *indexp = info->index; + + return true; +} + +bool +NativeTable::bind(const char *name, void *address) +{ + CharsAndLength key(name, strlen(name)); + NativeMap::Insert p = nativeMap_.findForAdd(key); + if (p.found()) { + (*p)->address = address; + return true; + } + + Local str(zone_, zone_->symbols()->add(key.str(), key.length())); + if (!str) + return false; + + // :TODO: assert no GC + NativeInfo *info = new NativeInfo(str, address, natives_.length()); + if (!info || !natives_.append(info)) + return false; + + if (!nativeMap_.add(p, info)) + return false; + + return true; +} + +void +NativeTable::accept(VirtualObjectVisitor *visitor) +{ + for (size_t i = 0; i < natives_.length(); i++) + visitor->visit(natives_[i]->name.address()); +}