Beispiel #1
0
static void
registerWakeup(Word name, Word value ARG_LD)
{ Word wake;
  Word tail = valTermRef(LD->attvar.tail);

  assert(gTop+6 <= gMax && tTop+4 <= tMax);

  wake = gTop;
  gTop += 4;
  wake[0] = FUNCTOR_wakeup3;
  wake[1] = needsRef(*name) ? makeRef(name) : *name;
  wake[2] = needsRef(*value) ? makeRef(value) : *value;
  wake[3] = ATOM_nil;

  if ( *tail )
  { Word t;				/* Non-empty list */

    deRef2(tail, t);
    TrailAssignment(t);
    *t = consPtr(wake, TAG_COMPOUND|STG_GLOBAL);
    TrailAssignment(tail);		/* on local stack! */
    *tail = makeRef(wake+3);
    DEBUG(1, Sdprintf("appended to wakeup\n"));
  } else				/* empty list */
  { Word head = valTermRef(LD->attvar.head);

    assert(isVar(*head));
    TrailAssignment(head);		/* See (*) */
    *head = consPtr(wake, TAG_COMPOUND|STG_GLOBAL);
    TrailAssignment(tail);
    *tail = makeRef(wake+3);
    LD->alerted |= ALERT_WAKEUP;
    DEBUG(1, Sdprintf("new wakeup\n"));
  }
}
void CurlDownload::didReceiveHeader(const String& header)
{
    LockHolder locker(m_mutex);

    if (header == "\r\n" || header == "\n") {

        long httpCode = 0;
        CURLcode err = curl_easy_getinfo(m_curlHandle, CURLINFO_RESPONSE_CODE, &httpCode);

        if (httpCode >= 200 && httpCode < 300) {
            URL url = getCurlEffectiveURL(m_curlHandle);
            callOnMainThread([this, url = url.isolatedCopy(), protectedThis = makeRef(*this)] {
                m_response.setURL(url);
                m_response.setMimeType(extractMIMETypeFromMediaType(m_response.httpHeaderField(HTTPHeaderName::ContentType)));
                m_response.setTextEncodingName(extractCharsetFromMediaType(m_response.httpHeaderField(HTTPHeaderName::ContentType)));

                didReceiveResponse();
            });
        }
    } else {
        callOnMainThread([this, header = header.isolatedCopy(), protectedThis = makeRef(*this)] {
            int splitPos = header.find(":");
            if (splitPos != -1)
                m_response.setHTTPHeaderField(header.left(splitPos), header.substring(splitPos + 1).stripWhiteSpace());
        });
    }
}
Beispiel #3
0
void Qhp::addIndexItem(Definition *context,MemberDef *md,
                       const char *sectionAnchor,const char *word)
{
  (void)word;
  //printf("addIndexItem(%s %s %s\n",
  //       context?context->name().data():"<none>",
  //       md?md->name().data():"<none>",
  //       word);

  if (md) // member
  {
    static bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES);
    if (context==0) // global member
    {
      if (md->getGroupDef())
        context = md->getGroupDef();
      else if (md->getFileDef())
        context = md->getFileDef();
    }
    if (context==0) return; // should not happen
    QCString cfname  = md->getOutputFileBase();
    QCString cfiname = context->getOutputFileBase();
    QCString level1  = context->name();
    QCString level2  = word ? QCString(word) : md->name();
    QCString contRef = separateMemberPages ? cfname : cfiname;
    QCString anchor  = sectionAnchor ? QCString(sectionAnchor) : md->anchor();

    QCString ref;

    // <keyword name="foo" id="MyApplication::foo" ref="doc.html#foo"/>
    ref = makeRef(contRef, anchor);
    QCString id = level1+"::"+level2;
    const char * attributes[] =
    {
      "name", level2,
      "id",   id,
      "ref",  ref,
      0
    };
    m_index.openClose("keyword", attributes);
  }
  else if (context) // container
  {
    // <keyword name="Foo" id="Foo" ref="doc.html#Foo"/>
    QCString contRef = context->getOutputFileBase();
    QCString level1  = word ? QCString(word) : context->name();
    QCString ref = makeRef(contRef,sectionAnchor);
    const char * attributes[] =
    {
      "name", level1,
      "id",   level1,
      "ref",  ref,
      0
    };
    m_index.openClose("keyword", attributes);
  }
}
// https://wicg.github.io/entries-api/#dom-filesystemdirectoryentry-getfile
// https://wicg.github.io/entries-api/#dom-filesystemdirectoryentry-getdirectory
void DOMFileSystem::getEntry(ScriptExecutionContext& context, FileSystemDirectoryEntry& directory, const String& virtualPath, const FileSystemDirectoryEntry::Flags& flags, GetEntryCallback&& completionCallback)
{
    ASSERT(&directory.filesystem() == this);

    if (!isValidVirtualPath(virtualPath)) {
        callOnMainThread([completionCallback = WTFMove(completionCallback)] {
            completionCallback(Exception { TypeMismatchError, "Path is invalid"_s });
        });
        return;
    }

    if (flags.create) {
        callOnMainThread([completionCallback = WTFMove(completionCallback)] {
            completionCallback(Exception { SecurityError, "create flag cannot be true"_s });
        });
        return;
    }

    auto resolvedVirtualPath = resolveRelativeVirtualPath(directory.virtualPath(), virtualPath);
    ASSERT(resolvedVirtualPath[0] == '/');
    auto fullPath = evaluatePath(resolvedVirtualPath);
    if (fullPath == m_rootPath) {
        callOnMainThread([this, context = makeRef(context), completionCallback = WTFMove(completionCallback)]() mutable {
            completionCallback(Ref<FileSystemEntry> { root(context) });
        });
        return;
    }

    m_workQueue->dispatch([this, context = makeRef(context), fullPath = crossThreadCopy(fullPath), resolvedVirtualPath = crossThreadCopy(resolvedVirtualPath), completionCallback = WTFMove(completionCallback)]() mutable {
        auto entryType = fileType(fullPath);
        callOnMainThread([this, context = WTFMove(context), resolvedVirtualPath = crossThreadCopy(resolvedVirtualPath), entryType, completionCallback = WTFMove(completionCallback)]() mutable {
            if (!entryType) {
                completionCallback(Exception { NotFoundError, "Cannot find entry at given path"_s });
                return;
            }
            switch (entryType.value()) {
            case FileMetadata::Type::Directory:
                completionCallback(Ref<FileSystemEntry> { FileSystemDirectoryEntry::create(context, *this, resolvedVirtualPath) });
                break;
            case FileMetadata::Type::File:
                completionCallback(Ref<FileSystemEntry> { FileSystemFileEntry::create(context, *this, resolvedVirtualPath) });
                break;
            default:
                completionCallback(Exception { NotFoundError, "Cannot find entry at given path"_s });
                break;
            }
        });
    });
}
Beispiel #5
0
BufferSrcFilterContext::BufferSrcFilterContext(const FilterContext &baseContext)
{
    if (baseContext && isFilterValid(baseContext.getFilter()))
    {
        makeRef(baseContext);
    }
}
Beispiel #6
0
void
assignAttVar(Word av, Word value ARG_LD)
{ Word a;

  assert(isAttVar(*av));
  assert(!isRef(*value));
  assert(gTop+7 <= gMax && tTop+6 <= tMax);

  DEBUG(1, Sdprintf("assignAttVar(%s)\n", vName(av)));

  if ( isAttVar(*value) )
  { if ( value > av )
    { Word tmp = av;
      av = value;
      value = tmp;
    } else if ( av == value )
      return;
  }

  a = valPAttVar(*av);
  registerWakeup(a, value PASS_LD);

  TrailAssignment(av);
  if ( isAttVar(*value) )
  { DEBUG(1, Sdprintf("Unifying two attvars\n"));
    *av = makeRef(value);
  } else
    *av = *value;

  return;
}
void ThreadedCompositor::setDeviceScaleFactor(float scale)
{
    m_compositingRunLoop->performTask([this, protectedThis = makeRef(*this), scale] {
        m_deviceScaleFactor = scale;
        scheduleDisplayImmediately();
    });
}
Beispiel #8
0
void
assignAttVar(Word av, Word value, int flags ARG_LD)
{ Word a;
  mark m;

  assert(isAttVar(*av));
  assert(!isRef(*value));
  assert(gTop+8 <= gMax && tTop+6 <= tMax);
  DEBUG(CHK_SECURE, assert(on_attvar_chain(av)));

  DEBUG(1, Sdprintf("assignAttVar(%s)\n", vName(av)));

  if ( isAttVar(*value) )
  { if ( value > av )
    { Word tmp = av;
      av = value;
      value = tmp;
    } else if ( av == value )
      return;
  }

  if( !(flags & ATT_ASSIGNONLY) )
  { a = valPAttVar(*av);
    registerWakeup(av, a, value PASS_LD);
  }

  if ( (flags&ATT_WAKEBINDS) )
    return;

  Mark(m);		/* must be trailed, even if above last choice */
  LD->mark_bar = NO_MARK_BAR;
  TrailAssignment(av);
  DiscardMark(m);

  if ( isAttVar(*value) )
  { DEBUG(1, Sdprintf("Unifying two attvars\n"));
    *av = makeRef(value);
  } else if ( isVar(*value) )
  { DEBUG(1, Sdprintf("Assigning attvar with plain var\n"));
    *av = makeRef(value);			/* JW: Does this happen? */
  } else
    *av = *value;

  return;
}
Beispiel #9
0
void NetscapePlugin::pluginThreadAsyncCall(void (*function)(void*), void* userData)
{
    RunLoop::main().dispatch([protectedThis = makeRef(*this), function, userData] {
        if (!protectedThis->m_isStarted)
            return;

        function(userData);
    });
}
void ThreadedCompositor::didChangeVisibleRect()
{
    RunLoop::main().dispatch([this, protectedThis = makeRef(*this), visibleRect = m_viewportController->visibleContentsRect(), scale = m_viewportController->pageScaleFactor()] {
        if (m_client)
            m_client->setVisibleContentsRect(visibleRect, FloatPoint::zero(), scale);
    });

    scheduleDisplayImmediately();
}
void CoordinatedGraphicsScene::dispatchOnClientRunLoop(Function<void()>&& function)
{
    if (&m_clientRunLoop == &RunLoop::current()) {
        function();
        return;
    }

    m_clientRunLoop.dispatch([protectedThis = makeRef(*this), function = WTFMove(function)] {
        function();
    });
}
void CoordinatedGraphicsScene::dispatchOnMainThread(Function<void()>&& function)
{
    if (RunLoop::isMain()) {
        function();
        return;
    }

    RunLoop::main().dispatch([protectedThis = makeRef(*this), function = WTFMove(function)] {
        function();
    });
}
Beispiel #13
0
static int
assign_in_dict(Word dp, Word val ARG_LD)
{ deRef(val);

  if ( !canBind(*val) )
  { *dp = *val;
  } else if ( isAttVar(*val) )
  { *dp = makeRef(val);
  } else
  { if ( dp < val )
    { if ( unlikely(tTop+1 >= tMax) )
	return TRAIL_OVERFLOW;
      setVar(*dp);
      Trail(val, makeRef(dp));
    } else
    { *dp = makeRef(val);
    }
  }

  return TRUE;
}
void IDBDatabase::dispatchEvent(Event& event)
{
    LOG(IndexedDB, "IDBDatabase::dispatchEvent (%" PRIu64 ") (%p)", m_databaseConnectionIdentifier, this);
    ASSERT(&originThread() == &Thread::current());

    auto protectedThis = makeRef(*this);

    EventTargetWithInlineData::dispatchEvent(event);

    if (event.isVersionChangeEvent() && event.type() == m_eventNames.versionchangeEvent)
        m_connectionProxy->didFireVersionChangeEvent(m_databaseConnectionIdentifier, downcast<IDBVersionChangeEvent>(event).requestIdentifier());
}
LocalStorageDatabaseTracker::LocalStorageDatabaseTracker(Ref<WorkQueue>&& queue, const String& localStorageDirectory)
    : m_queue(WTFMove(queue))
    , m_localStorageDirectory(localStorageDirectory.isolatedCopy())
{
    ASSERT(!m_localStorageDirectory.isEmpty());

    // Make sure the encoding is initialized before we start dispatching things to the queue.
    UTF8Encoding();

    m_queue->dispatch([protectedThis = makeRef(*this)]() mutable {
        protectedThis->importOriginIdentifiers();
    });
}
Beispiel #16
0
int
PL_get_attr__LD(term_t t, term_t a ARG_LD)
{ Word p = valTermRef(t);

  deRef(p);
  if ( isAttVar(*p) )
  { Word ap = valPAttVar(*p);

    *valTermRef(a) = makeRef(ap);	/* reference, so we can assign */
    succeed;
  }

  fail;
}
void DOMFileSystem::getFile(ScriptExecutionContext& context, FileSystemFileEntry& fileEntry, GetFileCallback&& completionCallback)
{
    auto virtualPath = fileEntry.virtualPath();
    auto fullPath = evaluatePath(virtualPath);
    m_workQueue->dispatch([context = makeRef(context), fullPath = crossThreadCopy(fullPath), virtualPath = crossThreadCopy(virtualPath), completionCallback = WTFMove(completionCallback)]() mutable {
        auto validatedVirtualPath = validatePathIsExpectedType(fullPath, WTFMove(virtualPath), FileMetadata::Type::File);
        callOnMainThread([context = WTFMove(context), fullPath = crossThreadCopy(fullPath), validatedVirtualPath = crossThreadCopy(validatedVirtualPath), completionCallback = WTFMove(completionCallback)]() mutable {
            if (validatedVirtualPath.hasException())
                completionCallback(validatedVirtualPath.releaseException());
            else
                completionCallback(File::create(fullPath));
        });
    });
}
void ThreadedCompositor::didChangeContentsSize(const IntSize& size)
{
    // FIXME: This seems a bit wrong, but it works. Needs review and investigation.
    m_viewportSize = size;

    m_compositingRunLoop->performTask([this, protectedThis = makeRef(*this), size] {
#if PLATFORM(WPE)
        // FIXME: Ditto.
        if (m_target)
            m_target->resize(size);
#endif
        m_viewportController->didChangeContentsSize(size);
    });
}
void ThreadedCompositor::setNativeSurfaceHandleForCompositing(uint64_t handle)
{
#if PLATFORM(GTK)
    m_compositingRunLoop->stopUpdates();
    m_compositingRunLoop->performTaskSync([this, protectedThis = makeRef(*this), handle] {
        m_scene->setActive(!!handle);

        // A new native handle can't be set without destroying the previous one first if any.
        ASSERT(!!handle ^ !!m_nativeSurfaceHandle);
        m_nativeSurfaceHandle = handle;
        if (!m_nativeSurfaceHandle)
            m_context = nullptr;
        m_nativeSurfaceHandle = 0;
    });
#endif
}
Beispiel #20
0
void Qhp::handlePrevSection()
{
  /*
  <toc>
    <section title="My Application Manual" ref="index.html">
      <section title="Chapter 1" ref="doc.html#chapter1"/>
      <section title="Chapter 2" ref="doc.html#chapter2"/>
      <section title="Chapter 3" ref="doc.html#chapter3"/>
    </section>
  </toc>
  */

  if (m_prevSectionTitle.isNull())
  {
    m_prevSectionTitle=" "; // should not happen...
  }

  // We skip "Main Page" as our extra root is pointing to that
  if (!((m_prevSectionLevel==1) && (m_prevSectionTitle==getFullProjectName())))
  {
    QCString finalRef = makeRef(m_prevSectionBaseName, m_prevSectionAnchor);

    const char * const attributes[] =
    { "title", m_prevSectionTitle,
      "ref",   finalRef,
      NULL
    };

    if (m_prevSectionLevel < m_sectionLevel)
    {
      // Section with children
      m_toc.open("section", attributes);
    }
    else
    {
      // Section without children
      m_toc.openClose("section", attributes);
    }
  }
  else
  {
    m_skipMainPageSection=TRUE;
  }

  clearPrevSection();
}
void DOMFileSystem::getParent(ScriptExecutionContext& context, FileSystemEntry& entry, GetParentCallback&& completionCallback)
{
    ASSERT(&entry.filesystem() == this);

    auto virtualPath = resolveRelativeVirtualPath(entry.virtualPath(), "..");
    ASSERT(virtualPath[0] == '/');
    auto fullPath = evaluatePath(virtualPath);
    m_workQueue->dispatch([this, context = makeRef(context), fullPath = crossThreadCopy(fullPath), virtualPath = crossThreadCopy(virtualPath), completionCallback = WTFMove(completionCallback)]() mutable {
        auto validatedVirtualPath = validatePathIsExpectedType(fullPath, WTFMove(virtualPath), FileMetadata::Type::Directory);
        callOnMainThread([this, context = WTFMove(context), validatedVirtualPath = crossThreadCopy(validatedVirtualPath), completionCallback = WTFMove(completionCallback)]() mutable {
            if (validatedVirtualPath.hasException())
                completionCallback(validatedVirtualPath.releaseException());
            else
                completionCallback(FileSystemDirectoryEntry::create(context, *this, validatedVirtualPath.releaseReturnValue()));
        });
    });
}
void ThreadedCompositor::invalidate()
{
    m_scene->detach();
    m_compositingRunLoop->stopUpdates();
    m_compositingRunLoop->performTaskSync([this, protectedThis = makeRef(*this)] {
        m_scene->purgeGLResources();
        m_context = nullptr;
#if PLATFORM(WPE)
        m_target = nullptr;
#endif
        m_scene = nullptr;
        m_viewportController = nullptr;
    });
    m_compositingRunLoop = nullptr;
    m_client = nullptr;
#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
    m_displayRefreshMonitor->invalidate();
#endif
}
void DOMFileSystem::listDirectory(ScriptExecutionContext& context, FileSystemDirectoryEntry& directory, DirectoryListingCallback&& completionHandler)
{
    ASSERT(&directory.filesystem() == this);

    auto directoryVirtualPath = directory.virtualPath();
    auto fullPath = evaluatePath(directoryVirtualPath);
    if (fullPath == m_rootPath) {
        Vector<Ref<FileSystemEntry>> children;
        children.append(fileAsEntry(context));
        completionHandler(WTFMove(children));
        return;
    }

    m_workQueue->dispatch([this, context = makeRef(context), completionHandler = WTFMove(completionHandler), fullPath = crossThreadCopy(fullPath), directoryVirtualPath = crossThreadCopy(directoryVirtualPath)]() mutable {
        auto listedChildren = listDirectoryWithMetadata(fullPath);
        callOnMainThread([this, context = WTFMove(context), completionHandler = WTFMove(completionHandler), listedChildren = crossThreadCopy(listedChildren), directoryVirtualPath = directoryVirtualPath.isolatedCopy()]() mutable {
            completionHandler(toFileSystemEntries(context, *this, WTFMove(listedChildren), directoryVirtualPath));
        });
    });
}
ThreadedCompositor::ThreadedCompositor(Client* client, WebPage& webPage, uint64_t nativeSurfaceHandle)
    : m_client(client)
    , m_nativeSurfaceHandle(nativeSurfaceHandle)
#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
    , m_displayRefreshMonitor(adoptRef(new WebKit::DisplayRefreshMonitor(*this)))
#endif
    , m_compositingRunLoop(std::make_unique<CompositingRunLoop>([this] { renderLayerTree(); }))
{
    m_clientRendersNextFrame.store(false);
    m_coordinateUpdateCompletionWithClient.store(false);

    m_compositingManager.establishConnection(webPage);

    m_compositingRunLoop->performTaskSync([this, protectedThis = makeRef(*this)] {
        m_scene = adoptRef(new CoordinatedGraphicsScene(this));
        m_viewportController = std::make_unique<SimpleViewportController>(this);
#if PLATFORM(GTK)
        m_scene->setActive(!!m_nativeSurfaceHandle);
#endif
    });
}
Beispiel #25
0
void NetworkDataTaskBlob::resume()
{
    ASSERT(m_state != State::Running);
    if (m_state == State::Canceling || m_state == State::Completed)
        return;

    m_state = State::Running;

    if (m_scheduledFailureType != NoFailure) {
        ASSERT(m_failureTimer.isActive());
        return;
    }

    RunLoop::main().dispatch([this, protectedThis = makeRef(*this)] {
        if (m_state == State::Canceling || m_state == State::Completed || !m_client) {
            clearStream();
            return;
        }

        if (!equalLettersIgnoringASCIICase(m_firstRequest.httpMethod(), "get")) {
            didFail(Error::MethodNotAllowed);
            return;
        }

        // If the blob data is not found, fail now.
        if (!m_blobData) {
            didFail(Error::NotFoundError);
            return;
        }

        // Parse the "Range" header we care about.
        String range = m_firstRequest.httpHeaderField(HTTPHeaderName::Range);
        if (!range.isEmpty() && !parseRange(range, m_rangeOffset, m_rangeEnd, m_rangeSuffixLength)) {
            didReceiveResponse(Error::RangeError);
            return;
        }

        getSizeForNext();
    });
}
void ThreadedCompositor::didChangeViewportAttribute(const ViewportAttributes& attr)
{
    m_compositingRunLoop->performTask([this, protectedThis = makeRef(*this), attr] {
        m_viewportController->didChangeViewportAttribute(attr);
    });
}
void ThreadedCompositor::scrollTo(const IntPoint& position)
{
    m_compositingRunLoop->performTask([this, protectedThis = makeRef(*this), position] {
        m_viewportController->scrollTo(position);
    });
}
void ThreadedCompositor::scrollBy(const IntSize& delta)
{
    m_compositingRunLoop->performTask([this, protectedThis = makeRef(*this), delta] {
        m_viewportController->scrollBy(delta);
    });
}
void ThreadedCompositor::forceRepaint()
{
    m_compositingRunLoop->performTaskSync([this, protectedThis = makeRef(*this)] {
        renderLayerTree();
    });
}
Beispiel #30
0
static int
copy_term(Word from, Word to, int flags ARG_LD)
{ term_agendaLR agenda;
  int rc = TRUE;

  initTermAgendaLR(&agenda, 1, from, to);
  while( nextTermAgendaLR(&agenda, &from, &to) )
  {
  again:

    switch(tag(*from))
    { case TAG_REFERENCE:
      { Word p2 = unRef(*from);

	if ( *p2 == VAR_MARK )		/* reference to a copied variable */
	{ *to = makeRef(p2);
	} else
	{ from = p2;			/* normal reference */
	  goto again;
	}

	continue;
      }
      case TAG_VAR:
      { if ( shared(*from) )
	{ *to = VAR_MARK;
	  *from = makeRef(to);
	  TrailCyclic(from PASS_LD);
	} else
	{ setVar(*to);
	}

	continue;
      }
      case TAG_ATTVAR:
	if ( flags&COPY_ATTRS )
	{ Word p = valPAttVar(*from);

	  if ( isAttVar(*p) )		/* already copied */
	  { *to = makeRefG(p);
	  } else
	  { Word attr;

	    if ( !(attr = alloc_attvar(PASS_LD1)) )
	    { rc = GLOBAL_OVERFLOW;
	      goto out;
	    }
	    TrailCyclic(p PASS_LD);
	    TrailCyclic(from PASS_LD);
	    *from = consPtr(attr, STG_GLOBAL|TAG_ATTVAR);
	    *to = makeRefG(attr);

	    from = p;
	    to = &attr[1];
	    goto again;
	  }
	} else
	{ if ( shared(*from) )
	  { Word p = valPAttVar(*from & ~BOTH_MASK);

	    if ( *p == VAR_MARK )
	    { *to = makeRef(p);
	    } else
	    { *to = VAR_MARK;
	      *from = consPtr(to, STG_GLOBAL|TAG_ATTVAR)|BOTH_MASK;
	      TrailCyclic(p PASS_LD);
	      TrailCyclic(from PASS_LD);
	    }
	  } else
	  { setVar(*to);
	  }
	}
	continue;
      case TAG_COMPOUND:
      { Functor ff = valueTerm(*from);

	if ( isRef(ff->definition) )
	{ *to = consPtr(unRef(ff->definition), TAG_COMPOUND|STG_GLOBAL);
	  continue;
	}

	if ( ground(ff->definition) )
	{ *to = *from;
	  continue;
	}

	if ( shared(ff->definition) )
	{ int arity = arityFunctor(ff->definition);
	  Functor ft;

	  if ( !(ft = (Functor)allocGlobalNoShift(arity+1)) )
	  { rc = GLOBAL_OVERFLOW;
	    goto out;
	  }
	  ft->definition = ff->definition & ~BOTH_MASK;
	  ff->definition = makeRefG((Word)ft);
	  TrailCyclic(&ff->definition PASS_LD);
	  *to = consPtr(ft, TAG_COMPOUND|STG_GLOBAL);

	  if ( pushWorkAgendaLR(&agenda, arity, ff->arguments, ft->arguments) )
	    continue;
	  rc = MEMORY_OVERFLOW;
	  goto out;
	} else				/* unshared term */
	{ int arity = arityFunctor(ff->definition);
	  Functor ft;

	  if ( !(ft = (Functor)allocGlobalNoShift(arity+1)) )
	  { rc = GLOBAL_OVERFLOW;
	    goto out;
	  }
	  ft->definition = ff->definition & ~BOTH_MASK;
	  *to = consPtr(ft, TAG_COMPOUND|STG_GLOBAL);

	  if ( pushWorkAgendaLR(&agenda, arity, ff->arguments, ft->arguments) )
	    continue;
	  rc = MEMORY_OVERFLOW;
	  goto out;
	}
      }
      default:
	*to = *from;
        continue;
    }
  }

out:
  clearTermAgendaLR(&agenda);
  return rc;
}