dvander@195: /* vim: set ts=4 sw=4 tw=99 et: dvander@195: * dvander@195: * Copyright (C) 2012 David Anderson dvander@195: * dvander@195: * This file is part of SourcePawn. dvander@195: * dvander@195: * SourcePawn is free software: you can redistribute it and/or modify it under dvander@195: * the terms of the GNU General Public License as published by the Free dvander@195: * Software Foundation, either version 3 of the License, or (at your option) dvander@195: * any later version. dvander@195: * dvander@195: * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY dvander@195: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS dvander@195: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. dvander@195: * dvander@195: * You should have received a copy of the GNU General Public License along with dvander@195: * SourcePawn. If not, see http://www.gnu.org/licenses/. dvander@195: */ dvander@195: #include "Zone.h" dvander@195: #include "NativeTable.h" dvander@195: #include "StringPool.h" dvander@196: #include "Heap-inl.h" dvander@195: dvander@195: using namespace ke; dvander@195: dvander@195: NativeTable::NativeTable(Zone *zone) dvander@195: : zone_(zone), dvander@195: nativeMap_(ZoneAllocatorPolicy()) dvander@195: { dvander@195: } dvander@195: dvander@195: NativeTable::~NativeTable() dvander@195: { dvander@195: for (size_t i = 0; i < natives_.length(); i++) dvander@195: delete natives_[i]; dvander@195: } dvander@195: dvander@195: bool dvander@195: NativeTable::initialize() dvander@195: { dvander@195: return nativeMap_.init(16); dvander@195: } dvander@195: dvander@195: bool dvander@195: NativeTable::add(Handle name, size_t *indexp) dvander@195: { dvander@195: // :TODO: assert no GC dvander@195: CharsAndLength key(name->chars(), name->length()); dvander@195: NativeMap::Insert p = nativeMap_.findForAdd(key); dvander@195: if (p.found()) { dvander@195: *indexp = (*p)->index; dvander@195: return true; dvander@195: } dvander@195: dvander@195: NativeInfo *info = new NativeInfo(name, NULL, natives_.length()); dvander@195: if (!info || !natives_.append(info)) dvander@195: return false; dvander@195: dvander@195: if (!nativeMap_.add(p, info)) dvander@195: return false; dvander@195: dvander@195: *indexp = info->index; dvander@195: dvander@195: return true; dvander@195: } dvander@195: dvander@195: bool dvander@195: NativeTable::bind(const char *name, void *address) dvander@195: { dvander@195: CharsAndLength key(name, strlen(name)); dvander@195: NativeMap::Insert p = nativeMap_.findForAdd(key); dvander@195: if (p.found()) { dvander@195: (*p)->address = address; dvander@195: return true; dvander@195: } dvander@195: dvander@195: Local str(zone_, zone_->symbols()->add(key.str(), key.length())); dvander@195: if (!str) dvander@195: return false; dvander@195: dvander@195: // :TODO: assert no GC dvander@195: NativeInfo *info = new NativeInfo(str, address, natives_.length()); dvander@195: if (!info || !natives_.append(info)) dvander@195: return false; dvander@195: dvander@195: if (!nativeMap_.add(p, info)) dvander@195: return false; dvander@195: dvander@195: return true; dvander@195: } dvander@195: dvander@195: void dvander@195: NativeTable::accept(VirtualObjectVisitor *visitor) dvander@195: { dvander@195: for (size_t i = 0; i < natives_.length(); i++) dvander@195: visitor->visit(natives_[i]->name.address()); dvander@195: }